Ejemplo n.º 1
0
        public bool SetupTransport(string serviceUri)
        {
            bool result = false;

            lock (this)
            {
                // Save these to help reconnect later.
                serverUri = serviceUri;

                // Set up the ControlChannelTrigger with the stream socket.
                result = RegisterWithControlChannelTrigger(serverUri);
                if (result == false)
                {
                    Diag.DebugPrint("Failed to sign on and connect");
                    if (socket != null)
                    {
                        socket.Dispose();
                        socket     = null;
                        readPacket = null;
                    }
                    if (channel != null)
                    {
                        channel.Dispose();
                        channel = null;
                    }
                }
            }
            return(result);
        }
 public AppContext(CommModule commInstance, HttpClient httpClient, ControlChannelTrigger channel, string id)
 {
     HttpClient   = httpClient;
     Channel      = channel;
     ChannelId    = id;
     CommInstance = commInstance;
     messageQueue = new ConcurrentQueue <Task <HttpResponseMessage> >();
 }
Ejemplo n.º 3
0
 public ApplicationContext(CommModule commInstance, MessageWebSocket webSocket, ControlChannelTrigger channel, string id)
 {
     WebSocketHandle = webSocket;
     Channel         = channel;
     ChannelId       = id;
     CommInstance    = commInstance;
     RecievedMessage = new ConcurrentQueue <string>();
 }
Ejemplo n.º 4
0
 public AppContext(CommModule commInstance, StreamSocket socket, ControlChannelTrigger channel, string id)
 {
     SocketHandle = socket;
     Channel      = channel;
     ChannelId    = id;
     CommInstance = commInstance;
     messageQueue = new ConcurrentQueue <string>();
 }
Ejemplo n.º 5
0
        public void CheckKeepAlive(string id, ControlChannelTrigger trigger)
        {
            Connection connection = _connectionList[id];

            if (connection != null)
            {
                connection.CheckKeepAlive(trigger);
            }
        }
Ejemplo n.º 6
0
        public void Run(Windows.ApplicationModel.Background.IBackgroundTaskInstance taskInstance)
        {
            if (taskInstance == null)
            {
                Diag.DebugPrint("PushNotifyTask: taskInstance was null");
                return;
            }

            Diag.DebugPrint("PushNotifyTask " + taskInstance.Task.Name + " Starting...");

            // Use the ControlChannelTriggerEventDetails object to derive the context for this background task.
            // The context happens to be the channelId that apps can use to differentiate between
            // various instances of the channel..
            var channelEventArgs = taskInstance.TriggerDetails as IControlChannelTriggerEventDetails;

            ControlChannelTrigger channel = channelEventArgs.ControlChannelTrigger;

            if (channel == null)
            {
                Diag.DebugPrint("Channel object may have been deleted.");
                return;
            }

            string channelId = channel.ControlChannelTriggerId;

            if (((IDictionary <string, object>)CoreApplication.Properties).ContainsKey(channelId))
            {
                try
                {
                    string messageReceived = "PushNotification Received";
                    var    appContext      = ((IDictionary <string, object>)CoreApplication.Properties)[channelId] as AppContext;

                    // Process any messages that have been enqueued by the receive completion handler.
                    bool result = AppContext.messageQueue.TryDequeue(out messageReceived);
                    if (result)
                    {
                        Diag.DebugPrint("Message: " + messageReceived);
                        InvokeSimpleToast(messageReceived);
                    }
                    else
                    {
                        Diag.DebugPrint("There was no message for this push notification: ");
                    }
                }
                catch (Exception exp)
                {
                    Diag.DebugPrint("PushNotifyTask failed with: " + exp.Message);
                }
            }
            else
            {
                Diag.DebugPrint("Cannot find AppContext key " + channelId);
            }

            Diag.DebugPrint("PushNotifyTask " + taskInstance.Task.Name + " finished.");
        }
Ejemplo n.º 7
0
        public void Reset()
        {
            lock (this)
            {
                if (readPacket != null)
                {
                    try
                    {
                        readPacket.DetachStream();
                        readPacket = null;
                    }
                    catch (Exception exp)
                    {
                        Diag.DebugPrint("Could not detach DataReader: " + exp.Message);
                    }
                }

                if (writePacket != null)
                {
                    try
                    {
                        writePacket.DetachStream();
                        writePacket = null;
                    }
                    catch (Exception exp)
                    {
                        Diag.DebugPrint("Could not detach DataWriter: " + exp.Message);
                    }
                }

                if (socket != null)
                {
                    socket.Dispose();
                    socket = null;
                }

                if (channel != null)
                {
                    if (((IDictionary <string, object>)CoreApplication.Properties).ContainsKey(channel.ControlChannelTriggerId))
                    {
                        CoreApplication.Properties.Remove(channel.ControlChannelTriggerId);
                    }

                    // Call the Dispose() method on the controlchanneltrigger object to release any
                    // OS maintained resources for this channel object.
                    channel.Dispose();
                    channel = null;
                }
                Diag.DebugPrint("CommModule has been reset.");
            }
        }
 private void DisposeProperties()
 {
     Diag.DebugPrint("Entering cleanup");
     if (httpClient != null)
     {
         httpClient.Dispose();
         httpClient = null;
     }
     if (channel != null)
     {
         channel.Dispose();
         channel = null;
     }
     Diag.DebugPrint("Exiting cleanup");
 }
Ejemplo n.º 9
0
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            if (taskInstance == null)
            {
                Diag.DebugPrint("PushNotifyTask: taskInstance was null");
                return;
            }

            Diag.DebugPrint("PushNotifyTask " + taskInstance.Task.Name + " Starting...");

            var channelEventArgs = taskInstance.TriggerDetails as IControlChannelTriggerEventDetails;

            ControlChannelTrigger channel = channelEventArgs.ControlChannelTrigger;

            if (channel == null)
            {
                Diag.DebugPrint("Channel object may have been deleted");
                return;
            }

            string channelId = channel.ControlChannelTriggerId;

            if (CoreApplication.Properties.ContainsKey(channelId))
            {
                try
                {
                    var appContext = CoreApplication.Properties[channelId] as AppContext;

                    bool result = AppContext.Dequeue(out Message messageReceived);

                    if (result)
                    {
                        appContext.CommInstance.Invoke(messageReceived);
                    }
                    else
                    {
                        Diag.DebugPrint("There was no message for this push notification.");
                    }
                }
                catch (Exception ex)
                {
                    Diag.DebugPrint("PushNotifyTask failed with: " + ex.Message);
                }

                Diag.DebugPrint("PushNotifyTask " + taskInstance.Task.Name + " finished.");
            }
        }
Ejemplo n.º 10
0
        private bool RegisterControlChannel()
        {
            if (!UnregisterControlChannel())
            {
                return(false);
            }

            if (IsInternetAvailable)
            {
                _XMPP.Socket = new StreamSocket();

                try
                {
                    // Create controlchannel
                    var slotType = _currentParameters.RequestConnectedStandby ? ControlChannelTriggerResourceType.RequestHardwareSlot : ControlChannelTriggerResourceType.RequestSoftwareSlot;
                    _controlChannel = new ControlChannelTrigger("CT" + Id, 15, slotType);
                    _controlChannel.UsingTransport(_XMPP.Socket);

                    // Register package received event
                    BackgroundTaskBuilder pushNotificationTrigger = new BackgroundTaskBuilder();
                    pushNotificationTrigger.Name           = "PN" + Id;
                    pushNotificationTrigger.TaskEntryPoint = "BackgroundTasks.PushNotificationTrigger";
                    pushNotificationTrigger.SetTrigger(_controlChannel.PushNotificationTrigger);
                    pushNotificationTrigger.Register();

                    // Register keepalive event
                    BackgroundTaskBuilder keepAliveTrigger = new BackgroundTaskBuilder();
                    keepAliveTrigger.Name           = "KA" + Id;
                    keepAliveTrigger.TaskEntryPoint = "BackgroundTasks.KeepAliveTrigger";
                    keepAliveTrigger.SetTrigger(_controlChannel.KeepAliveTrigger);
                    keepAliveTrigger.Register();
                }
                catch
                {
                    PushEvent(ErrorType.RegisterControlChannel, ErrorPolicyType.Reconnect);
                    return(false);
                }
#if DEBUG
                PushEvent(LogType.Info, "ControlChanel registered");
#endif
                return(true);
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 11
0
        public bool SetupTransport(string serverHostName, string servicePort)
        {
            bool result = false;

            lock (this)
            {
                if (appRole == AppRole.ClientRole)
                {
                    // Save these to help reconnect later.
                    serverName = serverHostName;
                    serverPort = servicePort;

                    // Set up the ControlChannelTrigger with the stream socket.
                    result = RegisterWithControlChannelTrigger(serverHostName, serverPort);
                    if (result == false)
                    {
                        Diag.DebugPrint("Failed to sign on and connect");
                        if (socket != null)
                        {
                            socket.Dispose();
                            socket     = null;
                            readPacket = null;
                        }
                        if (channel != null)
                        {
                            channel.Dispose();
                            channel = null;
                        }
                    }
                }
                else
                {
                    //
                    // start listening on the port.
                    //
                    serverSocket = null;
                    result       = StartListening(servicePort);
                    if (result == false)
                    {
                        Diag.DebugPrint("Failed to listen");
                    }
                }
            }

            return(result);
        }
        public static void RegisterBackgroundTasks(this ControlChannelTrigger channel)
        {
            const string WebSocketKeepAliveTask = "Windows.Networking.Sockets.WebSocketKeepAlive";

            var keepAliveBuilder = new BackgroundTaskBuilder();

            keepAliveBuilder.Name           = "KeepaliveTaskForNtofications";
            keepAliveBuilder.TaskEntryPoint = WebSocketKeepAliveTask;
            keepAliveBuilder.SetTrigger(channel.KeepAliveTrigger);
            keepAliveBuilder.Register();

            var pushNotifyBuilder = new BackgroundTaskBuilder();

            pushNotifyBuilder.Name           = "PushNotificationTask";
            pushNotifyBuilder.TaskEntryPoint = "NotificationManager.Tasks.PushNotifyTask";
            pushNotifyBuilder.SetTrigger(channel.PushNotificationTrigger);
            pushNotifyBuilder.Register();
        }
        public static ControlChannelTrigger RegisterChannel(this ControlChannelTrigger channel)
        {
            const int    serverKeepAliveInterval = 30;
            const string channelId = "notifications";

            Diag.DebugPrint("Create ControlChannelTrigger ...");

            try
            {
                channel = new ControlChannelTrigger(channelId, serverKeepAliveInterval, ControlChannelTriggerResourceType.RequestHardwareSlot);
            }
            catch (UnauthorizedAccessException ex)
            {
                Diag.DebugPrint("Plesase add the app to the lock screen. " + ex.Message);
                return(null);
            }

            return(channel);
        }
Ejemplo n.º 14
0
        public bool SetupTransport(string serviceUri)
        {
            OutputDebugString("edetocCCTSample_Tracing:   Entering SetupTransport");

            bool result = false;

            lock (this)
            {
                // Save these to help reconnect later.
                serverUri = serviceUri;


                //Diag.DebugPrint("edetoc - About to call RegisterWithControlChannelTrigger");

                // Set up the ControlChannelTrigger with the stream socket.
                result = RegisterWithControlChannelTrigger(serverUri);

                if (result == false)
                {
                    Diag.DebugPrint("Failed to sign on and connect");
                    if (socket != null)
                    {
                        socket.Dispose();
                        socket     = null;
                        readPacket = null;
                    }
                    if (channel != null)
                    {
                        channel.Dispose();
                        channel = null;
                    }
                }
                else
                {
                    //Diag.DebugPrint("edetoc - RegisterWithControlChannelTrigger OK");
                }
            }

            OutputDebugString("edetocCCTSample_Tracing:   Leaving SetupTransport");

            return(result);
        }
Ejemplo n.º 15
0
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            taskInstance.Canceled += Canceled;

            var backend = Runtime.Instance;

            if (backend != null)
            {
                backend.OnBackgroundTaskRunning(taskInstance);
            }

            try
            {
                IControlChannelTriggerEventDetails channelEventArgs = (IControlChannelTriggerEventDetails)taskInstance.TriggerDetails;
                ControlChannelTrigger channel = channelEventArgs.ControlChannelTrigger;
                channel.FlushTransport();
            }
            catch
            { }
        }
Ejemplo n.º 16
0
        public void CheckKeepAlive(ControlChannelTrigger trigger)
        {
            // Send keepalive for the next check
            var pingIq = new XMPP.tags.jabber.client.iq();

            pingIq.type = Tags.jabber.client.iq.typeEnum.get;
            pingIq.from = Id;
            pingIq.Add(new XMPP.tags.xmpp.ping.ping());
            Send(pingIq);

            // Check how long since the last packet
            var diffTime        = DateTime.Now - _lastReceiveTime;
            var diffTimeMinutes = (uint)diffTime.TotalMinutes;

            var keepAliveMinutes = (trigger != null) ? trigger.CurrentKeepAliveIntervalInMinutes : 15; // 15 is default

            if (diffTimeMinutes > keepAliveMinutes)
            {
                trigger.DecreaseNetworkKeepAliveInterval();
                OnError(this, new ErrorEventArgs("Connection to server lost", ErrorType.NotConnected, ErrorPolicyType.Reconnect));
            }
        }
        private bool RegisterWithCCTHelper()
        {
            bool result = false;

            // Specify the keepalive interval expected by the server for this app
            // in order of minutes.
            const int serverKeepAliveInterval = 15;

            // Specify the channelId string to differentiate this
            // channel instance from any other channel instance.
            // When background task fires, the channel object is provided
            // as context and the channel id can be used to adapt the behavior
            // of the app as required.
            const string channelId = "channelOne";

            // Try creating the controlchanneltrigger if this has not been already created and stored
            // in the property bag.
            Diag.DebugPrint("RegisterWithCCTHelper Starting...");

            Diag.DebugPrint("Create ControlChannelTrigger ...");

            // Create the controlchanneltrigger object and request a hardware slot for this app.
            try
            {
                channel = new ControlChannelTrigger(channelId, serverKeepAliveInterval, ControlChannelTriggerResourceType.RequestHardwareSlot);
            }
            catch (Exception exp)
            {
                Diag.DebugPrint("Error while creating controlchanneltrigger" + exp.Message + " Please add the app to the lockscreen.");
                return(result);
            }
            bool registerKA = true, registerPushNotify = true;

            if (kaTaskId != Guid.Empty || pushNotifyTaskId != Guid.Empty)
            {
                IReadOnlyDictionary <Guid, IBackgroundTaskRegistration> allTasks = BackgroundTaskRegistration.AllTasks;
                if (kaTaskId != Guid.Empty && allTasks.ContainsKey(kaTaskId))
                {
                    registerKA = false;
                }
                if (pushNotifyTaskId != Guid.Empty && allTasks.ContainsKey(pushNotifyTaskId))
                {
                    registerPushNotify = false;
                }
            }

            if (registerKA)
            {
                // Register the apps background task with the trigger for keepalive.
                BackgroundTaskBuilder keepAliveBuilder = new BackgroundTaskBuilder();
                keepAliveBuilder.Name           = "KeepaliveTaskForChannelOne";
                keepAliveBuilder.TaskEntryPoint = "Background.KATask";
                keepAliveBuilder.SetTrigger(channel.KeepAliveTrigger);
                BackgroundTaskRegistration KATask = keepAliveBuilder.Register();
                kaTaskId = KATask.TaskId;
            }

            if (registerPushNotify)
            {
                // Register the apps background task with the trigger for push notification task.
                BackgroundTaskBuilder pushNotifyBuilder = new BackgroundTaskBuilder();
                pushNotifyBuilder.Name           = "PushNotificationTaskForChannelOne";
                pushNotifyBuilder.TaskEntryPoint = "Background.PushNotifyTask";
                pushNotifyBuilder.SetTrigger(channel.PushNotificationTrigger);
                BackgroundTaskRegistration pushNotifyTask = pushNotifyBuilder.Register();
                pushNotifyTaskId = pushNotifyTask.TaskId;
            }

            // Store the objects created in the property bag for later use.
            // NOTE: make sure these objects are free threaded. STA/Both objects can
            // cause deadlocks when foreground threads are suspended.
            if (((IDictionary <string, object>)CoreApplication.Properties).ContainsKey(channel.ControlChannelTriggerId))
            {
                CoreApplication.Properties.Remove(channel.ControlChannelTriggerId);
            }

            AppContext appContext = new AppContext(this, httpClient, channel, channel.ControlChannelTriggerId);

            lock (CoreApplication.Properties)
            {
                ((IDictionary <string, object>)CoreApplication.Properties).Add(channel.ControlChannelTriggerId, appContext);
            }

            try
            {
                // Send Http Request
                SetupHttpRequestAndSendToHttpServer();

                Diag.DebugPrint("Connected!");

                result = true;

                Diag.DebugPrint("RegisterWithCCTHelper Completed.");
            }
            catch (Exception exp)
            {
                Diag.DebugPrint("RegisterWithCCTHelper Task failed with: " + exp.ToString());

                // Exceptions may be thrown for example if the application has not
                // registered the background task class id for using real time communications
                //  in the package appx manifest.
                result = false;
            }
            return(result);
        }
Ejemplo n.º 18
0
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            if (taskInstance == null)
            {
                Diag.DebugPrint("KATask: taskInstance was null");
                return;
            }

            Diag.DebugPrint("KATask " + taskInstance.Task.Name + " Starting...");

            // Use the ControlChannelTriggerEventDetails object to derive the context for this background task.
            // The context happens to be the channelId that apps can use to differentiate between
            // various instances of the channel..
            var channelEventArgs = taskInstance.TriggerDetails as IControlChannelTriggerEventDetails;

            ControlChannelTrigger channel = channelEventArgs.ControlChannelTrigger;

            if (channel == null)
            {
                Diag.DebugPrint("Channel object may have been deleted.");
                return;
            }

            string channelId = channel.ControlChannelTriggerId;

            if (((IDictionary <string, object>)CoreApplication.Properties).ContainsKey(channelId))
            {
                try
                {
                    var    appContext       = ((IDictionary <string, object>)CoreApplication.Properties)[channelId] as AppContext;
                    string KeepAliveMessage = "KeepAlive Message";
                    if (appContext != null && appContext.CommInstance != null)
                    {
                        CommModule commModule = appContext.CommInstance;
                        bool       result;
                        result = commModule.SendKAMessage(KeepAliveMessage);
                        if (result == true)
                        {
                            // Call FlushTransport on the channel object to ensure
                            // the packet is out of the process and on the wire before
                            // exiting the keepalive task.
                            commModule.channel.FlushTransport();
                        }
                        else
                        {
                            // Socket has not been set up. reconnect the transport and plug in to the controlchanneltrigger object.
                            commModule.Reset();

                            // Create RTC enabled transport.
                            commModule.SetupTransport(commModule.serverName, commModule.serverPort);
                        }
                    }
                }
                catch (Exception exp)
                {
                    Diag.DebugPrint("KA Task failed with: " + exp.Message);
                }
            }
            else
            {
                Diag.DebugPrint("Cannot find AppContext key channelOne");
            }

            Diag.DebugPrint("KATask " + taskInstance.Task.Name + " finished.");
        }
Ejemplo n.º 19
0
        async Task <bool> RegisterWithControlChannelTriggerHelper(string serverHostName, string serverPort)
        {
            bool result = false;

            socket = new StreamSocket();

            // Specify the keepalive interval expected by the server for this app
            // in order of minutes.
            const int serverKeepAliveInterval = 30;

            // Specify the channelId string to differentiate this
            // channel instance from any other channel instance.
            // When background task fires, the channel object is provided
            // as context and the channel id can be used to adapt the behavior
            // of the app as required.
            const string channelId = "channelOne";

            // Try creating the controlchanneltrigger if this has not been already created and stored
            // in the property bag.
            Diag.DebugPrint("RegisterWithCCTHelper Starting...");

            ControlChannelTriggerStatus status;

            Diag.DebugPrint("Create ControlChannelTrigger ...");

            // Create the ControlChannelTrigger object and request a hardware slot for this app.
            // If the app is not on LockScreen, then the ControlChannelTrigger constructor will
            // fail right away.
            try
            {
                channel = new ControlChannelTrigger(channelId, serverKeepAliveInterval,
                                                    ControlChannelTriggerResourceType.RequestHardwareSlot);
            }
            catch (UnauthorizedAccessException exp)
            {
                Diag.DebugPrint("Please add the app to the lockscreen. " + exp.Message);
                return(result);
            }

            // Register the apps background task with the trigger for keepalive.
            var keepAliveBuilder = new BackgroundTaskBuilder();

            keepAliveBuilder.Name           = "KeepaliveTaskForChannelOne";
            keepAliveBuilder.TaskEntryPoint = "Background.KATask";
            keepAliveBuilder.SetTrigger(channel.KeepAliveTrigger);
            keepAliveBuilder.Register();

            // Register the apps background task with the trigger for push notification task.
            var pushNotifyBuilder = new BackgroundTaskBuilder();

            pushNotifyBuilder.Name           = "PushNotificationTaskForChannelOne";
            pushNotifyBuilder.TaskEntryPoint = "Background.PushNotifyTask";
            pushNotifyBuilder.SetTrigger(channel.PushNotificationTrigger);
            pushNotifyBuilder.Register();

            // Tie the transport method to the ControlChannelTrigger object to push enable it.
            // Note that if the transport's TCP connection is broken at a later point of time,
            // the ControlChannelTrigger object can be reused to plugin a new transport by
            // calling UsingTransport API again.
            try
            {
                Diag.DebugPrint("Calling UsingTransport() ...");
                channel.UsingTransport(socket);

                // Connect the socket
                HostName hostName = new HostName(serverHostName);

                // If connect fails or times out it will throw exception.
                await socket.ConnectAsync(hostName, serverPort);

                Diag.DebugPrint("Connected");

                // Call WaitForPushEnabled API to make sure the TCP connection has
                // been established, which will mean that the OS will have allocated
                // any hardware slot for this TCP connection.
                //
                // In this sample, the ControlChannelTrigger object was created by
                // explicitly requesting a hardware slot.
                //
                // On Non-AOAC systems, if app requests hardware slot as above,
                // the system will fallback to a software slot automatically.
                //
                // On AOAC systems, if no hardware slot is available, then app
                // can request a software slot [by re-creating the ControlChannelTrigger object].
                status = channel.WaitForPushEnabled();
                Diag.DebugPrint("WaitForPushEnabled() completed with status: " + status);
                if (status != ControlChannelTriggerStatus.HardwareSlotAllocated &&
                    status != ControlChannelTriggerStatus.SoftwareSlotAllocated)
                {
                    throw new Exception(string.Format("Neither hardware nor software slot could be allocated. ChannelStatus is {0}", status.ToString()));
                }

                // Store the objects created in the property bag for later use.
                // NOTE: make sure these objects are free threaded. STA/Both objects can
                // cause deadlocks when foreground threads are suspended.
                if (((IDictionary <string, object>)CoreApplication.Properties).ContainsKey(channel.ControlChannelTriggerId))
                {
                    CoreApplication.Properties.Remove(channel.ControlChannelTriggerId);
                }

                var appContext = new AppContext(this, socket, channel, channel.ControlChannelTriggerId);
                ((IDictionary <string, object>)CoreApplication.Properties).Add(channel.ControlChannelTriggerId, appContext);

                Diag.DebugPrint("RegisterWithCCTHelper Completed.");
                result = true;

                // We are all set. Post a read to ensure push notificiation fires.
                PostSocketRead(MAX_BUFFER_LENGTH);
            }
            catch (Exception exp)
            {
                Diag.DebugPrint("RegisterWithCCTHelper failed with: " + exp.Message);

                // Exceptions may be thrown for example if the application has not
                // registered the background task class id for using real time communications
                // broker in the package appx manifest.
            }
            return(result);
        }
Ejemplo n.º 20
0
        public async void OnBackgroundTaskRunning(IBackgroundTaskInstance instance)
        {
            ControlChannelTrigger channelTrigger = null;

            try
            {
                // Get channel trigger
                var channelEventArgs = (IControlChannelTriggerEventDetails)instance.TriggerDetails;
                if (channelEventArgs != null)
                {
                    channelTrigger = channelEventArgs.ControlChannelTrigger;
                }

                // Push notification
                if (instance.Task.Name.StartsWith("PN"))
                {
                    var serverId = instance.Task.Name.Substring(2);

                    if (_connections != null)
                    {
                        _connections.WaitProcessing(serverId);
                    }
                }
                // Keep alive
                else if (instance.Task.Name.StartsWith("KA"))
                {
                    var serverId = instance.Task.Name.Substring(2);

                    if (_connections != null)
                    {
                        _connections.CheckKeepAlive(serverId, channelTrigger);
                    }
                }
                // Everything else
                else
                {
                    switch (instance.Task.Name)
                    {
                    case "ControlChannelReset":
                        await Task.Delay(_eventDelayMS);

                        PushEvent(WindowsType.ControlChannelReset);
                        _connections.Update();
                        break;

                    case "InternetAvailable":
                        await Task.Delay(_eventDelayMS);

                        PushEvent(WindowsType.InternetAvailable);
                        _connections.Update();
                        break;

                    case "InternetNotAvailable":
                        await Task.Delay(_eventDelayMS);

                        PushEvent(WindowsType.InternetNotAvailable);
                        _connections.Update();
                        break;

                    case "ServicingComplete":
                        PushEvent(WindowsType.ServicingComplete);
                        break;

                    case "SessionConnected":
                        await Task.Delay(_eventDelayMS);

                        PushEvent(WindowsType.SessionConnected);
                        _connections.Update();
                        break;

                    case "UserAway":
                        PushEvent(WindowsType.UserAway);
                        break;

                    case "UserPresent":
                        PushEvent(WindowsType.UserPresent);
                        break;

                    case "LockScreenApplicationAdded":
                        PushEvent(WindowsType.LockScreenApplicationAdded);
                        OnBackgroundStatusChanged();
                        break;

                    case "LockScreenApplicationRemoved":
                        PushEvent(WindowsType.LockScreenApplicationRemoved);
                        OnBackgroundStatusChanged();
                        break;

                    case "TimeZoneChange":
                        PushEvent(WindowsType.TimeZoneChange);
                        break;
                    }
                }
            }
            catch {}

            //if (defferal != null)
            //    defferal.Complete();

            try
            {
                if (channelTrigger != null)
                {
                    channelTrigger.FlushTransport();
                }
            }
            catch { }
        }
Ejemplo n.º 21
0
        async Task <bool> RegisterWithCCTHelper(string serverUri)
        {
            bool result = false;

            socket = new MessageWebSocket();
            socket.MessageReceived += Socket_MessageReceived;

            // Specify the keepalive interval expected by the server for this app
            // in order of minutes.
            const int serverKeepAliveInterval = 30;

            // Specify the channelId string to differentiate this
            // channel instance from any other channel instance.
            // When background task fires, the channel object is provided
            // as context and the channel id can be used to adapt the behavior
            // of the app as required.
            const string channelId = "ControlChannelWebSocketUWP";

            // IMPORTANT: Note that this is a websocket sample, therefore the
            // keepalive task class is provided by Windows for websockets.
            // For websockets, the system does the keepalive on behalf of the
            // app but the app still needs to specify this well known keepalive task.
            // This should be done here in the background registration as well
            // as in the package manifest.
            const string WebSocketKeepAliveTask = "Windows.Networking.Sockets.WebSocketKeepAlive";

            // Try creating the controlchanneltrigger if this has not been already
            // created and stored in the property bag.
            //Diag.DebugPrint("RegisterWithCCTHelper Starting...");
            ControlChannelTriggerStatus status;

            //Diag.DebugPrint("About to create ControlChannelTrigger ...");

            // Create the ControlChannelTrigger object and request a hardware slot for this app.
            // If the app is not on LockScreen, then the ControlChannelTrigger constructor will
            // fail right away.

            OutputDebugString("edetocCCTSample_Tracing:   Entering RegisterWithCCTHelper");
            try
            {
                channel = new ControlChannelTrigger(channelId, serverKeepAliveInterval,
                                                    ControlChannelTriggerResourceType.RequestHardwareSlot);
            }
            catch (UnauthorizedAccessException exp)
            {
                //Diag.DebugPrint("Please add the app to the lock screen." + exp.Message);
                OutputDebugString("edetocCCTSample_Tracing:   Failed to create ControlChannelTrigger" + exp.Message);

                return(result);
            }

            OutputDebugString("edetocCCTSample_Tracing:   ControlChannelTrigger created with success");

            //Diag.DebugPrint("ControlChannelTrigger creation OK");

            Uri serverUriInstance;

            try
            {
                serverUriInstance = new Uri(serverUri);
                OutputDebugString("edetocCCTSample_Tracing:   Uri is " + serverUriInstance.ToString());
            }
            catch (Exception exp)
            {
                OutputDebugString("edetocCCTSample_Tracing: error create URI: " + exp.Message);
                //Diag.DebugPrint("Error creating URI: " + exp.Message);
                return(result);
            }


            // Register the apps background task with the trigger for keepalive.
            var keepAliveBuilder = new BackgroundTaskBuilder();

            keepAliveBuilder.Name           = "KeepaliveTaskFor" + channelId;
            keepAliveBuilder.TaskEntryPoint = WebSocketKeepAliveTask;
            keepAliveBuilder.SetTrigger(channel.KeepAliveTrigger);
            keepAliveBuilder.Register();
            OutputDebugString("edetocCCTSample_Tracing:   WebSocketKeepAliveTask registered");
            //Diag.DebugPrint("edetoc - BG keepAliveBuilder register OK");

            // Register the apps background task with the trigger for push notification task.
            var pushNotifyBuilder = new BackgroundTaskBuilder();

            pushNotifyBuilder.Name           = "PushNotificationTaskFor" + channelId;
            pushNotifyBuilder.TaskEntryPoint = "BackgroundTaskHelper.PushNotifyTask";
            pushNotifyBuilder.SetTrigger(channel.PushNotificationTrigger);
            pushNotifyBuilder.Register();
            //Diag.DebugPrint("edetoc - BG pushNotifyBuilder register OK");
            OutputDebugString("edetocCCTSample_Tracing:   PushNotifyTask registered");

            // Tie the transport method to the ControlChannelTrigger object to push enable it.
            // Note that if the transport's TCP connection is broken at a later point of time,
            // the ControlChannelTrigger object can be reused to plug in a new transport by
            // calling UsingTransport API again.
            //Diag.DebugPrint("Calling UsingTransport() ...");
            try
            {
                OutputDebugString("edetocCCTSample_Tracing:   Before UsingTransport");

                channel.UsingTransport(socket);

                OutputDebugString("edetocCCTSample_Tracing:   After UsingTransport");

                // Connect the socket
                //
                // If connect fails or times out it will throw exception.
                OutputDebugString(string.Format("edetocCCTSample_Tracing:  {0} Before ConnectAsync", DateTime.Now.ToString()));

                await socket.ConnectAsync(serverUriInstance);

                OutputDebugString("edetocCCTSample_Tracing:   After ConnectASync");

                //Diag.DebugPrint("Socket connected");

                // Call WaitForPushEnabled API to make sure the TCP connection has
                // been established, which will mean that the OS will have allocated
                // any hardware slot for this TCP connection.
                //
                // In this sample, the ControlChannelTrigger object was created by
                // explicitly requesting a hardware slot.
                //
                // On Non-AOAC systems, if app requests hardware slot as above,
                // the system will fallback to a software slot automatically.
                //
                // On AOAC systems, if no hardware slot is available, then app
                // can request a software slot [by re-creating the ControlChannelTrigger object].
                status = channel.WaitForPushEnabled();

                //Diag.DebugPrint("WaitForPushEnabled() completed with status: " + status);
                if (status != ControlChannelTriggerStatus.HardwareSlotAllocated &&
                    status != ControlChannelTriggerStatus.SoftwareSlotAllocated)
                {
                    OutputDebugString("edetocCCTSample_Tracing:   Neither hardware nor software slot could be allocated");
                    throw new Exception(string.Format("Neither hardware nor software slot could be allocated. ChannelStatus is {0}", status.ToString()));
                }

                OutputDebugString("edetocCCTSample_Tracing:  WaitForPushEnabled OK");

                // Store the objects created in the property bag for later use.
                // NOTE: make sure these objects are free threaded. STA/Both objects can
                // cause deadlocks when foreground threads are suspended.
                CoreApplication.Properties.Remove(channel.ControlChannelTriggerId);

                var appContext = new ApplicationContext(this, socket, channel, channel.ControlChannelTriggerId);
                ((IDictionary <string, object>)CoreApplication.Properties).Add(channel.ControlChannelTriggerId, appContext);
                result = true;
                //Diag.DebugPrint("RegisterWithCCTHelper Completed.");
            }
            catch (Exception exp)
            {
                //Diag.DebugPrint("RegisterWithCCTHelper Task failed with: " + exp.Message);
                OutputDebugString("edetocCCTSample_Tracing:   RegisterWithCCTHelper  failed with: " + exp.Message);

                // Exceptions may be thrown for example if the application has not
                // registered the background task class id for using real time communications
                // broker in the package appx manifest.
            }
            return(result);
        }