How to get presence via UCMA
UCMA is a client-side API that allows you to integrate OCS functionality into your application. You can retrieve presence, publish presence, manage your subscriptions, and start conversations and conferences.
In this article, we'll take a look at retrieving presence information from UCMA by subscribing to the contact.
SIP URIs
OCS identifies people through the SIP protocol. You can get a user's SIP address from Active Directory; each valid user will have a single, unique SIP address. SIP addresses generally are of the format:
sip:username@domain
Subscriptions vs. queries
Subscribing lets you get real-time presence updates per contact. So, if you are subscribed to John Smith, you will be notified any time his presence changes. Jane Smith’s presence, on the other hand, will become stale in your application because you’re not subscribed to her and you don’t get any notifications. In her case, you would have to ask OCS for her presence information every minute or ten minutes or whatever to get latest information.
Step 1: Initialize platform
Using UCMA starts with initializing the collaboration platform.
public class PresenceRetriever
{
private CollaborationPlatform _platform;
public IAsyncResult Start()
{
var settings = new ClientPlatformSettings("OCS_GetPresence", SipTransportType.Tls);
_platform = new CollaborationPlatform(settings);
return _platform.BeginStartup(InitCompleted, null);
}
private void InitCompleted(IAsyncResult result)
{
_platform.EndStartup(result);
}
}
Step 2: Initialize endpoint
The next step is to initialize your application endpoint:
public class PresenceRetriever
{
// ...
private UserEndpoint _endpoint;
public IAsyncResult InitEndpoint(string currentUserSipUri, string ocsServerPath)
{
var settings = new UserEndpointSettings(currentUserSipUri, ocsServerPath);
_endpoint = new UserEndpoint(_platform, settings);
_endpoint.Credential = CredentialCache.DefaultNetworkCredentials;
return _endpoint.BeginEstablish(EstablishCompleted, null);
}
private void EstablishCompleted(IAsyncResult result)
{
_endpoint.EndEstablish(result);
}
}
Step 3: Subscribe to presence
You can subscribe to one or more presences at a time:
public class PresenceRetriever
{
// ...
public void Subscribe(params string[] sipUris)
{
_endpoint.RemotePresence.PresenceSubscriptionCategories =
new string[] { "state" };
_endpoint.RemotePresence.PresenceNotificationReceived +=
PresenceNotificationReceived;
var targets = new List<RemotePresentitySubscriptionTarget>();
foreach(var sipUri in sipUris)
{
targets.Add(new RemotePresentitySubscriptionTarget(sipUri, null));
}
_endpoint.RemotePresence.BeginAddTargets(targets, AddTargetsCompleted, null);
}
private void PresenceNotificationReceived(object sender, RemotePresenceNotificationEventArgs e)
{
foreach(var notice in e.Notifications)
{
foreach(var category in notice.Categories)
{
var state = PresenceState.Create(category);
Console.WriteLine(state.Availability);
}
}
}
private void AddTargetsCompleted(IAsyncResult result)
{
_endpoint.RemotePresence.EndAddTargets(result);
}
}
If you run the application now, you should get notified every time the contacts you are subscribed to change their presences.
Final step: teardown
When your application is done with OCS, you need to teardown your endpoint and the platform. The code is simple:
public class PresenceRetriever
{
// ...
public IAsyncResult Stop()
{
return _endpoint.BeginTerminate(TerminateCompleted, null);
}
private void TerminateCompleted(IAsyncResult result)
{
_endpoint.EndTerminate(result);
_platform.BeginShutdown(ShutdownCompleted, null);
}
private void ShutdownCompleted(IAsyncResult result)
{
_platform.EndShutdown(result);
}
}
Asynchronous Calls
Notice how the startup and shutdown methods return IAsyncResults. The reason for this is that since the calls to OCS are performed asynchronously, you may get into situations where you try to establish the endpoint before the platform has been setup or you try to query for presence before the endpoint is established. The way to make sure that all the necessary steps are done is to use the result to figure out whether the operation has completed or force your calling method to wait until the operation has completed via AsyncWaitHandle.WaitOne method on your result.
1.
Erik on May 03, 2010 at 10:30 pm
Thanks for the info... how would the code change if you were just querying for a user's presence at a given point in time? I'm not worried about receiving updates to changes in status and just want to get the user's presence.