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> >(); }
public ApplicationContext(CommModule commInstance, MessageWebSocket webSocket, ControlChannelTrigger channel, string id) { WebSocketHandle = webSocket; Channel = channel; ChannelId = id; CommInstance = commInstance; RecievedMessage = new ConcurrentQueue <string>(); }
public AppContext(CommModule commInstance, StreamSocket socket, ControlChannelTrigger channel, string id) { SocketHandle = socket; Channel = channel; ChannelId = id; CommInstance = commInstance; messageQueue = new ConcurrentQueue <string>(); }
public void CheckKeepAlive(string id, ControlChannelTrigger trigger) { Connection connection = _connectionList[id]; if (connection != null) { connection.CheckKeepAlive(trigger); } }
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."); }
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"); }
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."); } }
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); } }
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); }
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); }
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 { } }
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); }
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."); }
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); }
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 { } }
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); }