Page 28 - MSDN Magazine, May 2018
P. 28

A new public property, IsHost, should be added to the man- ager, as well as to determine workflow. During the CreateSession method, this value is set to true, identifying this app as the host. Another public property, CurrentUser, provides an instance of the user on the machine and will be used for messaging. The session manager also maintains an ObservableCollection of users in the current session. This collection is initialized with the newly created user. For the host of the session, this instance gets created in the CreateSession method. The resulting additions to the RemoteSessionManager are shown in Figure 6.
There are three more items that need to be added to RemoteSes- sionManager to complete the CreateSession method. The first is an event handler for when a user attempts to join a session and the JoinRequested event is raised on the session. The OnJoinRequested method will automatically accept any user trying to join. This could be extended to prompt the host for approval before the user is joined to the session. The request information is provided as a RemoteSystemSessionJoinRequest included in the RemoteSystem-
Figure 6 The CreateSession Method
SessionJoinRequestedEventArgs parameter of the event handler. Invoking the Accept method will add the user to the session. The following code includes the new event to add to RemoteSession- Manager, as well as the completed OnJoinRequested method:
private void OnJoinRequested(RemoteSystemSessionController sender, RemoteSystemSessionJoinRequestedEventArgs args)
{
}
The session manager can monitor when participants are added or removed from the current session through the RemoteSystem- SessionParticipantWatcher. This class monitors the participants and raises either an Added or Removed event when needed. When a user joins a session already in progress, each participant already in the current session will receive an Added event. The app will take this series of events and determine which participant is the host by matching the DisplayName against the session’s Controller- DisplayName. This will allow participants to communicate directly with the host. The session manager maintains a participant watcher as a private variable that’s initialized in the InitParticipantWatcher. This method is called whether creating a session or joining an existing session. Figure 7 contains the new additions. You’ll notice that for this workflow you need to know when a participant is removed only if you’re the host, and if a participant is added if you’re joining a session. As a host, the RemoteSessionManager
Figure 7 InitParticipantWatcher
var deferral = args.GetDeferral(); args.JoinRequest.Accept(); deferral.Complete();
private RemoteSystemSessionController _controller; private RemoteSystemSession _currentSession; public bool IsHost { get; private set; }
public User CurrentUser { get; private set; } public ObservableCollection<User> Users { get; } =
new ObservableCollection<User>();
public async Task<SessionCreationResult> CreateSession( string sessionName, string displayName)
{
SessionCreationResult status = SessionCreationResult.Success;
RemoteSystemAccessStatus accessStatus = await RemoteSystem.RequestAccessAsync(); if (accessStatus != RemoteSystemAccessStatus.Allowed)
{
return SessionCreationResult.PermissionError; }
if (_controller == null) {
_controller = new RemoteSystemSessionController(sessionName);
_controller.JoinRequested += OnJoinRequested; }
RemoteSystemSessionCreationResult createResult = await _controller.CreateSessionAsync();
if (createResult.Status == RemoteSystemSessionCreationStatus.Success) {
_currentSession = createResult.Session;
InitParticipantWatcher();
CurrentUser = new User() { Id = _currentSession.ControllerDisplayName, DisplayName = displayName };
Users.Add(CurrentUser);
IsHost = true; }
else if(createResult.Status == RemoteSystemSessionCreationStatus.SessionLimitsExceeded)
{
status = SessionCreationResult.TooManySessions;
} else {
status = SessionCreationResult.Failure; }
return status; }
private RemoteSystemSessionParticipantWatcher _participantWatcher;
private void InitParticipantWatcher() {
_participantWatcher = _currentSession.CreateParticipantWatcher(); if (IsHost)
{
_participantWatcher.Removed += OnParticipantRemoved; }
else {
_participantWatcher.Added += OnParticipantAdded; }
_participantWatcher.Start(); }
private void OnParticipantAdded(RemoteSystemSessionParticipantWatcher watcher, RemoteSystemSessionParticipantAddedEventArgs args)
{
if(args.Participant.RemoteSystem.DisplayName ==
_currentSession.ControllerDisplayName) {
Host = args.Participant; }
}
private async void OnParticipantRemoved(RemoteSystemSessionParticipantWatcher watcher,
RemoteSystemSessionParticipantRemovedEventArgs args) {
var qry = Users.Where(u => u.Id == args.Participant.RemoteSystem.DisplayName); if (qry.Count() > 0)
{
var dispatcher = CoreApplication.MainView.CoreWindow.Dispatcher;
await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () => { Users.Remove(qry.First()); });
await BroadCastMessage("users", Users); }
}
24 msdn magazine
Universal Windows Platform


































































































   26   27   28   29   30