private void ShutdownPresenceView(AsyncTask task, object state) { RemotePresenceView presenceView = m_remotePresenceView; if (presenceView == null) { task.Complete(null); return; } m_remotePresenceView.PresenceNotificationReceived -= this.PresenceView_NotificationReceived; task.DoOneStep( delegate() { presenceView.BeginTerminate( delegate(IAsyncResult ar) { task.DoFinalStep( delegate() { presenceView.EndTerminate(ar); }); }, null); }); }
private bool InitializeRemotePresenceView() { try { // RemotePresenceView provides a unified way to request presence for a set of presentities m_remotePresenceView = new RemotePresenceView( m_applicationEndpoint, new RemotePresenceViewSettings() { SubscriptionMode = RemotePresenceViewSubscriptionMode.Default }); // Wire up NotificationReceived before adding targets m_remotePresenceView.PresenceNotificationReceived += new EventHandler <RemotePresentitiesNotificationEventArgs>(RemotePresenceView_PresenceNotificationReceived); Helper.Logger.Info("UcPresenceProvider started"); return(true); } catch (Exception ex) { Helper.Logger.Error("UCPresenceProvider failed: Could not initialize remote presence view {0}", ex); return(false); } }
/// <summary> /// Constructor of a presence watcher supporting persistent, polling and on-demand subscriptions /// to presence categories published by specified remote presentities. on-demand subscription is /// also known as presence query. The code here also handles self-presence. /// </summary> /// <param name="endpoint"></param> public PresenceWatcher(LocalEndpoint endpoint) { _remotePresenceServices = endpoint.PresenceServices; // RemotePresenceView for persitent subscription: RemotePresenceViewSettings rpvs = new RemotePresenceViewSettings(); rpvs.SubscriptionMode = RemotePresenceViewSubscriptionMode.Persistent; _persistentPresenceView = new RemotePresenceView(endpoint, rpvs); _persistentPresenceView.PresenceNotificationReceived += new EventHandler<RemotePresentitiesNotificationEventArgs>(PersistentPresenceReceivedEventHandler); _persistentPresenceView.SubscriptionStateChanged += new EventHandler<RemoteSubscriptionStateChangedEventArgs>(PersistentSubscriptionStateChangedEventHandler); // RemotePresenceView for polling subscription rpvs = new RemotePresenceViewSettings(); rpvs.SubscriptionMode = RemotePresenceViewSubscriptionMode.Polling; rpvs.PollingInterval = new TimeSpan(0, 5, 0); // every 5 minutes _pollingPresenceView = new RemotePresenceView(endpoint, rpvs); _pollingPresenceView.SetPresenceSubscriptionCategoriesForPolling(new string[] { "contactCard", "state", "note", "noteHistory" }); _pollingPresenceView.PresenceNotificationReceived += new EventHandler<RemotePresentitiesNotificationEventArgs>(PollingPresenceReceivedEventHandler); _pollingPresenceView.SubscriptionStateChanged += new EventHandler<RemoteSubscriptionStateChangedEventArgs>(PollingSubscriptionStateChangedEventHandler); }
/// <summary> /// Returns <c>true</c> if the given endpoint is available. /// </summary> /// <param name="uri"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task<PresenceState> GetPresenceStateAsync(string uri, CancellationToken cancellationToken) { // cache contains our data lock (cache) if (cache.ContainsKey(uri)) return cache[uri]; // endpoint is down if (Endpoint.State != LocalEndpointState.Established) return null; // we associate the presence context with ourselves var view = Endpoint.PresenceServices.GetRemotePresenceViews() .FirstOrDefault(i => i.ApplicationContext == this); if (view == null) { view = new RemotePresenceView(Endpoint, new RemotePresenceViewSettings() { SubscriptionMode = RemotePresenceViewSubscriptionMode.Default, PollingInterval = TimeSpan.FromSeconds(15), }); view.ApplicationContext = this; view.PresenceNotificationReceived += view_PresenceNotificationReceived; } // subscribe to the requested uri if not already done if (!view.GetPresentities().Contains(uri)) { view.StartSubscribingToPresentities(new[] { new RemotePresentitySubscriptionTarget(uri) }); cacheWh.Reset(); } // wait a bit for state to arrive var t1 = WaitPresenceStateAsync(uri); var d1 = Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); await Task.WhenAny(t1, d1); // state arrived if (t1.IsCompleted) return await t1; // taking too long; initiate a manual query var t2 = GetPresenceQueryAsync(uri, cancellationToken); var d2 = Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); await Task.WhenAny(t1, t2, d2); // state finally arrived if (t1.IsCompleted) return await t1; // manual query completed if (t2.IsCompleted && t2.Result != null) // insert manual query result into cache lock (cache) return cache[uri] = t2.Result; // could not obtain state in any way return null; }
/// <summary> /// UnRegisters event handlers. /// </summary> /// <param name="remotePresenceView">Remote presence view.</param> private void UnRegisterEventHandlers(RemotePresenceView remotePresenceView) { if (remotePresenceView != null) { // Wire up NotificationReceived before adding targets remotePresenceView.PresenceNotificationReceived -= this.RemotePresenceView_PresenceNotificationReceived; } }
public PresenceHelper(ApplicationEndpoint appEndpoint) { _appEndpoint = appEndpoint; // Subscribe to receive presence notifications _remotePresenceView = new RemotePresenceView(appEndpoint); _remotePresenceView.PresenceNotificationReceived += new EventHandler<RemotePresentitiesNotificationEventArgs>(PresenceReceivedEventHandler); }
public static Task TerminateAsync(this RemotePresenceView view) { return(Task.Factory.FromAsync( view.BeginTerminate, view.EndTerminate, null)); }
private void StartPresenceView(AsyncTask task, object state) { m_remotePresenceView = new RemotePresenceView(this.UserEndpoint, new RemotePresenceViewSettings()); m_remotePresenceView.PresenceNotificationReceived += this.PresenceView_NotificationReceived; m_remotePresenceView.SubscriptionStateChanged += RemoteSubscriptionStateChanged; this.SubscribeToRemotePresentities(); task.Complete(null); }
/// <summary> /// Checks if a given uri is already subscribed or not. /// </summary> /// <param name="sipUri">Uri. Cannot be null or empty.</param> /// <returns>True if the uri is already subscribed to. False otherwise.</returns> private bool IsAlreadySubscribed(string sipUri) { Debug.Assert(!String.IsNullOrEmpty(sipUri), "Sip uri is null or empty"); RemotePresenceView remotePresenceView = m_remotePresenceView; bool retVal = false; if (remotePresenceView != null) { var subscriptions = remotePresenceView.GetPresentities(); retVal = subscriptions.Any(s => s.Equals(sipUri, StringComparison.InvariantCultureIgnoreCase)); } return(retVal); }
/// <summary> /// Starts the provider. /// </summary> /// <returns>True if uc presence prvovider was started successfully.</returns> internal void Start() { // RemotePresenceView provides a unified way to request presence for a set of presentities m_remotePresenceView = new RemotePresenceView( m_applicationEndpoint, new RemotePresenceViewSettings() { SubscriptionMode = RemotePresenceViewSubscriptionMode.Default }); this.RegisterEventHandlers(m_remotePresenceView); Helper.Logger.Info("UcPresenceProvider started"); }
/// <summary> /// Log the subscription states that have changed. /// </summary> /// <param name="sender"> /// View that saw subscription state changes. /// </param> /// <param name="e">Data about the state changes</param> private void RemotePresenceView_SubscriptionStateChanged( object sender, RemoteSubscriptionStateChangedEventArgs e) { // Extract the view that raised the event. RemotePresenceView view = sender as RemotePresenceView; // The event args can contain multiple StateChanged notifications foreach (KeyValuePair <RealTimeAddress, RemotePresentityStateChange> stateChanged in e.SubscriptionStateChanges) { Console.WriteLine("\nView: " + view.ApplicationContext + "; SubscriptionState for user: "******" has changed from: " + stateChanged.Value.PreviousState + " to: " + stateChanged.Value.State + "."); } }
// Helper method that is called by the imFlow_MessageReceived delegate. // This method returns the URI of the first available contact in a particular group. // The group is determined in the handler for the NotificationReceived event, // the ContactGroupServices_NotificationReceived delegate. private Uri GetFirstAvailableContact() { int ThreadID = Thread.CurrentThread.ManagedThreadId; Console.WriteLine("In getFirstAvailable - thread ID: " + ThreadID); RemotePresenceViewSettings presenceViewSettings = new RemotePresenceViewSettings(); presenceViewSettings.SubscriptionMode = RemotePresenceViewSubscriptionMode.Persistent; _remotePresenceView = new RemotePresenceView(_userEndpoint, presenceViewSettings); _remotePresenceView.PresenceNotificationReceived += new EventHandler < RemotePresentitiesNotificationEventArgs>(RemotePresenceView_PresenceNotificationReceived); _userEndpoint.ContactGroupServices.NotificationReceived += new EventHandler <Microsoft.Rtc.Collaboration.ContactsGroups.ContactGroupNotificationEventArgs>( ContactGroupServices_NotificationReceived); Console.WriteLine("In getFirstAvailable, ContactGroupServices state: {0}", _userEndpoint.ContactGroupServices.CurrentState.ToString()); _userEndpoint.ContactGroupServices.BeginSubscribe(ContactGroupSubscribeCB, _userEndpoint.ContactGroupServices); return(_remoteContactUri); }
private void StartupPresenceView(AsyncTask task, object state) { task.DoFinalStep( delegate() { CallbackRequest callbackRequest = (CallbackRequest)state; var viewSettings = new RemotePresenceViewSettings(); viewSettings.SubscriptionMode = RemotePresenceViewSubscriptionMode.Persistent; var presenceView = new RemotePresenceView(callbackRequest.CutomerEndpoint, viewSettings); presenceView.ApplicationContext = callbackRequest; var target = new RemotePresentitySubscriptionTarget(callbackRequest.TargetUri); presenceView.PresenceNotificationReceived += this.PresenceView_NotificationReceived; presenceView.SubscriptionStateChanged += this.PresenceView_SubscriptionStateChanged; callbackRequest.PresenceView = presenceView; presenceView.StartSubscribingToPresentities( new RemotePresentitySubscriptionTarget[] { target }); }); }
/// <summary> /// Log the presence notification for the remote user. /// </summary> /// <param name="sender">View that received the notification.</param> /// <param name="e">Data about the notifications received.</param> private void RemotePresenceView_NotificationReceived(object sender, RemotePresentitiesNotificationEventArgs e) { // Extract the RemotePresenceView that received the notification. RemotePresenceView view = sender as RemotePresenceView; // A RemotePresentityNotification will contain all the // categories for one user; Notifications can contain notifications // for multiple users. foreach (RemotePresentityNotification notification in e.Notifications) { Console.WriteLine("\nView: " + view.ApplicationContext + " Received a Notification for user " + notification.PresentityUri + "."); // If a category on notification is null, the category // was not present in the notification. This means there were no // changes in that category. if (notification.AggregatedPresenceState != null) { Console.WriteLine("Aggregate State = " + notification.AggregatedPresenceState.Availability + "."); } if (notification.PersonalNote != null) { Console.WriteLine("PersonalNote: " + notification.PersonalNote.Message + "."); } if (notification.ContactCard != null) { // A ContactCard contains many properties; only display // some. ContactCard contactCard = notification.ContactCard; Console.WriteLine("ContactCard Company: " + contactCard.Company + "."); Console.WriteLine("ContactCard DisplayName: " + contactCard.DisplayName + "."); Console.WriteLine("ContactCard EmailAddress: " + contactCard.EmailAddress + "."); } } }
public static void Start() { try { var host = Plugin.LyncPlugin.Configuration.GetString("host"); var thumbprint = Plugin.LyncPlugin.Configuration.GetString("thumbprint"); var gruu = Plugin.LyncPlugin.Configuration.GetString("gruu"); var trustPort = Plugin.LyncPlugin.Configuration.GetInt("trustedPort"); var appPort = Plugin.LyncPlugin.Configuration.GetInt("appPort"); var sip = Plugin.LyncPlugin.Configuration.GetString("accountSip"); var platformSettings = new ServerPlatformSettings(UserAgent, host, trustPort, gruu, CertificateUtil.GetCertificate(StoreName.My, StoreLocation.LocalMachine, thumbprint)); Platform = new CollaborationPlatform(platformSettings); AppEndpoint = new ApplicationEndpoint(Platform, new ApplicationEndpointSettings(sip, host, appPort) { UseRegistration = true }); Log("Starting Lync platform."); Platform.EndStartup(Platform.BeginStartup(null, null)); Log("Lync platform started."); AppEndpoint.EndEstablish(AppEndpoint.BeginEstablish(null, null)); UserEndpoint = new UserEndpoint(Platform, new UserEndpointSettings(sip, host, appPort) { AutomaticPresencePublicationEnabled = true }); UserEndpoint.EndEstablish(UserEndpoint.BeginEstablish(null, null)); RemotePresence = new RemotePresenceView(UserEndpoint, new RemotePresenceViewSettings()); RemotePresence.PresenceNotificationReceived += PresenceNotificationReceived; } catch (Exception ex) { Error(ex.Message); } }
// Callback method referred to in the call to BeginTerminate on the RemotePresenceView instance. private void ViewTerminateCB(IAsyncResult ar) { RemotePresenceView view = ar.AsyncState as RemotePresenceView; view.EndTerminate(ar); }
/// <summary> /// Helper to unwire important event handlers for a RemotePresenceView. /// </summary> /// <param name="view">View to remove event handlers from.</param> private void UnWireHandlersForView(RemotePresenceView view) { Console.WriteLine("\nUn-wiring handlers for view: " + view.ApplicationContext); view.SubscriptionStateChanged -= RemotePresenceView_SubscriptionStateChanged; view.PresenceNotificationReceived -= RemotePresenceView_NotificationReceived; }
/// <summary> /// Retrieves the application configuration and runs the sample. /// </summary> private void Run() { // Prepare and instantiate the platform. _helper = new UCMASampleHelper(); _userEndpoint = _helper.CreateEstablishedUserEndpoint( "SubscribePresence Sample User" /*endpointFriendlyName*/); // Get the URI of the remote user whose presence to subscribe to. _remoteUserUri = "sip:" + UCMASampleHelper.PromptUser( "Please enter the URI, in the format user@host, of the user whose Presence to subscribe to " + "=> ", "RemoteUserURI"); // RemotePresenceView is the class to be used to subscribe to // another entity's presence. _remotePresenceView = new RemotePresenceView(_userEndpoint); // Wire up event handlers to receive the incoming notifications of // the remote user being subscribed to. _remotePresenceView.SubscriptionStateChanged += new EventHandler < RemoteSubscriptionStateChangedEventArgs>( RemotePresence_SubscriptionStateNotificationReceived); _remotePresenceView.PresenceNotificationReceived += new EventHandler < RemotePresentitiesNotificationEventArgs>(RemotePresence_PresenceNotificationReceived); try { // Subscribe to target user. _target = new RemotePresentitySubscriptionTarget(_remoteUserUri); _remotePresenceView.StartSubscribingToPresentities( new RemotePresentitySubscriptionTarget[] { _target }); // Subscribe to ContactGroupServices. // This is done so that the user can add/delete groups and // add/delete contacts, among other operations. _userEndpoint.ContactGroupServices.NotificationReceived += new EventHandler <Microsoft.Rtc.Collaboration.ContactsGroups.ContactGroupNotificationEventArgs>( ContactGroupServices_NotificationReceived); _userEndpoint.ContactGroupServices.SubscriptionStateChange += new EventHandler <PresenceSubscriptionStateChangedEventArgs>(ContactGroupServices_SubscriptionStateChange); _userEndpoint.ContactGroupServices.BeginSubscribe(EndSubscribeCompleted, _userEndpoint.ContactGroupServices); // Wait for subscription to ContactsGroups to be completed. _waitForSubscribedToContactsGroupsCompleted.WaitOne(); Console.WriteLine("Subscription to ContactsGroups completed."); // Create a new group. _userEndpoint.ContactGroupServices.BeginAddGroup(_groupName, null /* group data */, EndAddGroupCompleted, _userEndpoint.ContactGroupServices); // Wait for group to be created. _waitForGroupIdSet.WaitOne(); // Add the remote user to the newly created group. ContactsGroups.ContactAddOptions addOptions = new Microsoft.Rtc.Collaboration.ContactsGroups.ContactAddOptions(); addOptions.GroupIds.Add(_groupId); _userEndpoint.ContactGroupServices.BeginAddContact(_remoteUserUri, addOptions, EndAddContactCompleted, _userEndpoint.ContactGroupServices); UCMASampleHelper.PauseBeforeContinuing("You are now subscribed to the presence of the remote " + "user. \nPlease toggle the user state of the remote user to get the appropriate " + "notifications. \nPress ENTER to delete the contact, delete the group, and unsubscribe" + "to the presence of the remote user."); // Remove contact from group, and delete group. _userEndpoint.ContactGroupServices.BeginDeleteContact(_remoteUserUri, EndDeleteContactCompleted, _userEndpoint.ContactGroupServices); } catch (ArgumentException ex) { Console.WriteLine("Could not subscribe to the presence of the remote user: "******"\n\n********************"); Console.WriteLine("Press ENTER to shutdown and exit."); Console.WriteLine("********************\n\n"); Console.ReadLine(); // Shutdown Platform _helper.ShutdownPlatform(); }
/// <summary> /// Retrieves the application configuration and begins running the /// sample. /// </summary> private void Run() { // Prepare and instantiate the platform and an endpoint. _helper = new UCMASampleHelper(); _userEndpoint = _helper.CreateEstablishedUserEndpoint( "SubscribePresenceView Sample User" /*endpointFriendlyName*/); // Get the Uri of the remote user to subscribe to. _remoteUserUri = "sip:" + UCMASampleHelper.PromptUser( "Please enter the URI, in the format User@Host, of the user to subscribe to => ", "RemoteUserURI"); Console.WriteLine("\nChanging PresenceSubscriptionCategory Filter to only include ContactCard " + "and PresenceState"); // Set category filter. This is a global filter for all persistent // subscriptions and can only be changed before any subscriptions // are active. // BUGBUG: error CS0618: 'Microsoft.Rtc.Collaboration.LocalEndpoint.RemotePresence' is obsolete: 'This property will be removed from future Versions. Please see RemotePresenceView and PresenceServices instead.' // _userEndpoint.RemotePresence.PresenceSubscriptionCategories = // new string[] { PresenceCategoryNames.ContactCard, PresenceCategoryNames.State }; // RemotePresencView objects can be used to group subscriptions. // When a RemotePresenceView is created, it is created with the // specified RemotePresenceViewSettings and associated with the // specified LocalEndpoint. The views can then be accessed via the // LocalEndpoint setting: RemotePresenceViews. // RemotePresenceView.ApplicationContext can be used to pass or // store information related to the view (seen below). // Create a RemotePresenceView with a persistent subscription mode. // This type of view can represent a contact list, for example. // Note: The Default SubscriptionMode will start a subscription as // Persistent and downgrade to Polling if an error occurs. var persistentSettings = new RemotePresenceViewSettings(); persistentSettings.SubscriptionMode = RemotePresenceViewSubscriptionMode.Default; _persistentView = new RemotePresenceView(_userEndpoint, persistentSettings); _persistentView.ApplicationContext = "Persistent View"; // Wire up event handlers for the view this.WireUpHandlersForView(_persistentView); // Create a RemotePresenceView with a polling subscription mode // This type of view can represent a list of people // on the To: line of an e-mail, for example. var pollingSettings = new RemotePresenceViewSettings(); pollingSettings.SubscriptionMode = RemotePresenceViewSubscriptionMode.Polling; // The line below is not necessary; PollingInterval has a default // (and minimum) value of 5 minutes. pollingSettings.PollingInterval = TimeSpan.FromMinutes(5); _pollingView = new RemotePresenceView(_userEndpoint, pollingSettings); _pollingView.ApplicationContext = "Polling View"; // Wire up event handlers for the view this.WireUpHandlersForView(_pollingView); Console.WriteLine("\nChanging Polling View's category filter to only include Note."); _pollingView.SetPresenceSubscriptionCategoriesForPolling( new string[] { PresenceCategoryNames.Note }); try { // This constructor does very basic validation on the uri _target = new RemotePresentitySubscriptionTarget(_remoteUserUri); } catch (ArgumentException argumentException) { // ArgumentException will be thrown if the parameter used to // create the RemotePresentitySubscriptionTarget is an // invalid sip Uri. // TODO (Left to the reader): Error handling code to either // retry creating the target with corrected parameters, log // the error for debugging or gracefully exit the program. Console.WriteLine(argumentException.ToString()); throw; } Console.WriteLine("\nInitiating subscriptions for both Views to user: "******"succeed", but the StateChanged notifications will indicate the // subscription went to a Terminated state. _persistentView.StartSubscribingToPresentities(new RemotePresentitySubscriptionTarget[] { _target }); _pollingView.StartSubscribingToPresentities(new RemotePresentitySubscriptionTarget[] { _target }); // There is no callback for the StartSubscribingToPresentities // operation because subscriptions to multiple targets can // complete at different times. Completion or failure of the // subscription can be monitored through the // SubscriptionStateChanged event handler, // RemotePresenceView_NotificationReceived. UCMASampleHelper.PauseBeforeContinuing("Press ENTER to unsubscribe."); Console.WriteLine("\nBoth Views are terminating any subscriptions to user: "******"Press ENTER to shutdown and exit."); // Shutdown Platform _helper.ShutdownPlatform(); }
/// <summary> /// Starts subscribing to the Presence of agents upon successful registration of the endpoint /// </summary> private void OnEstablishComplete(IAsyncResult result) { try { _matchMaker._endpoint.EndEstablish(result); //create a SubscriptionTarget for each agent RemotePresentitySubscriptionTarget[] contacts = new RemotePresentitySubscriptionTarget[_matchMaker._configuration.Agents.Count]; for (int i = 0; i < _matchMaker.Configuration.Agents.Count; i++) { contacts[i] = new RemotePresentitySubscriptionTarget(_matchMaker._configuration.Agents[i].SignInAddress); } RemotePresenceView MatchMakerPresence = new RemotePresenceView(_matchMaker._endpoint); //Initiate the persistent batch subscription to the list of agents //Only interested in subscribing to the Agents Availability. We should not expect more than one category instance //per Remote Presentity notification change. Always register the event handler before starting the subscription. MatchMakerPresence.PresenceNotificationReceived += _matchMaker.HandleAgentAvailabilityChanged; MatchMakerPresence.StartSubscribingToPresentities(contacts); try { _matchMaker._mohServer = new AcdMusicOnHoldServer(_matchMaker, _matchMaker.Configuration.MusicOnHoldFilePath, _matchMaker._logger); _matchMaker._mohServer.BeginStartUp(ar => { AcdMusicOnHoldServer mohServer = ar.AsyncState as AcdMusicOnHoldServer; mohServer.EndStartUp(ar); lock (_matchMaker._syncRoot) { _matchMaker.UpdateState(MatchMakerState.Started); } this.SetAsCompleted(null, false); }, _matchMaker._mohServer); } catch (RealTimeException ex) { _matchMaker._logger.Log("AcdAgentMatchMaker failed to subscribe to the Presence of its Agents", ex); _matchMaker.BeginShutdown((asyncResult) => { _matchMaker.EndShutdown(asyncResult); this.SetAsCompleted(ex, false); }, ex); } } catch (RealTimeException ex) { _matchMaker._logger.Log("AcdAgentMatchMaker failed to subscribe to the Presence of its Agents; verify your agent configuration.", ex); this.SetAsCompleted(ex, false); _matchMaker.BeginShutdown((asyncResult) => { _matchMaker.EndShutdown(asyncResult); this.SetAsCompleted(ex, false); }, ex); } }