Exemple #1
0
        private void HandleResponse(NotificationResponse response)
        {
            var notificationItem = response.NotificationItem;

            // Handle responses according to:
            // http://msdn.microsoft.com/en-us/library/ff941100(v=VS.92).aspx

            // Notification was sent to the queue and will be received. All is good.
            if (response.NotificationStatus == NotificationStatusReceived)
            {
                /*if (response.DeviceConnectionStatus == DeviceConnectionStatusTemporarilyDisconnected)
                {
                    // We may want to do something clever here though, like not send anything else
                    // to this device for an hour or so.
                }*/
                return;
            }

            // If the notification was suppressed, don't do anything.
            // This could happen because the tile isn't pinned to the start page
            // or that the client isn't properly configured.
            // We could potentially implement the "Ask user to pin"-recipe
            if (response.NotificationStatus == NotificationStatusSuppressed)
            {
                return;
            }

            // If the subscription has expired, remove it
            if (response.SubscriptionStatus == SubscriptionStatusExpired)
            {
                _registrator.Unregister(notificationItem.ClientUniqueId);
                return;
            }

            // If the queue is full, retry in a few minutes
            if (response.NotificationStatus == NotificationStatusQueueFull &&
                (
                response.DeviceConnectionStatus == DeviceConnectionStatusConnected ||
                response.DeviceConnectionStatus == DeviceConnectionStatusTemporarilyDisconnected
                )
               )
            {
                notificationItem.FailedAttempts++;
                if (notificationItem.FailedAttempts <= notificationItem.MaxNumberOfAttempts)
                {
                    // Wait exponentially longer for each failed attempt
                    // Start with 2 minutes, then 4, then 8 etc.
                    var minutesToWait = (2 ^ notificationItem.FailedAttempts);

                    // Re-send this notification in a few minutes
                    _queue.EnqueueItem(notificationItem, DateTime.Now.AddMinutes(minutesToWait));
                }
                return;
            }

            // If server returned a 503, retry in a few minutes
            if (response.StatusCode == 503)
            {
                notificationItem.FailedAttempts++;
                if (notificationItem.FailedAttempts <= notificationItem.MaxNumberOfAttempts)
                {
                    // Wait exponentially longer for each failed attempt
                    // Start with 2 minutes, then 4, then 8 etc.
                    var minutesToWait = (2 ^ notificationItem.FailedAttempts);

                    // Re-send this notification in a few minutes
                    _queue.EnqueueItem(notificationItem, DateTime.Now.AddMinutes(minutesToWait));
                }
                return;
            }

            // Device is in an inactive state. We may retry once every hour
            if (response.StatusCode == 412 &&
                response.NotificationStatus == NotificationStatusDropped &&
                response.DeviceConnectionStatus == DeviceConnectionStatusInactive)
            {
                notificationItem.FailedAttempts++;
                if (notificationItem.FailedAttempts <= notificationItem.MaxNumberOfAttempts)
                {
                    // Re-send this notification in an hour
                    _queue.EnqueueItem(notificationItem, DateTime.Now.AddHours(1));
                }
                return;
            }

            // Throttling limit reached, let's try again in an hour
            if (response.NotificationStatus == NotificationStatusDropped && response.SubscriptionStatus == SubscriptionStatusActive)
            {
                notificationItem.FailedAttempts++;
                if (notificationItem.FailedAttempts <= notificationItem.MaxNumberOfAttempts)
                {
                    // Re-send this notification in an hour
                    _queue.EnqueueItem(notificationItem, DateTime.Now.AddHours(1));
                }
                return;
            }
        }
Exemple #2
0
        private NotificationResponse SendRequest(string subscriptionUri, byte[] notificationMessage, NotificationKind kind)
        {
            HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);

            // HTTP POST is the only allowed method to send the notification.
            sendNotificationRequest.Method = "POST";

            // The optional custom header X-MessageID uniquely identifies a notification message. If it is present, the
            // same value is returned in the notification response. It must be a string that contains a UUID.
            sendNotificationRequest.Headers.Add("X-MessageID", Guid.NewGuid().ToString());
            if (kind == NotificationKind.Tile)
            {
                sendNotificationRequest.ContentType = "text/xml";
                sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "token");
            }
            else if (kind == NotificationKind.Toast)
            {
                sendNotificationRequest.ContentType = "text/xml";
                sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "toast");
            }

            // TODO Add support for other notification classes
            var notificationClass = ((int)NotificationClass.Immediately) + (int)kind;
            sendNotificationRequest.Headers.Add("X-NotificationClass", notificationClass.ToString());

            // Sets the web request content length.
            sendNotificationRequest.ContentLength = notificationMessage.Length;

            using (Stream requestStream = sendNotificationRequest.GetRequestStream())
            {
                requestStream.Write(notificationMessage, 0, notificationMessage.Length);
            }

            // Sends the notification and make sure we handle the response eventually
            HttpWebResponse response;
            try
            {
                response = (HttpWebResponse)sendNotificationRequest.GetResponse();
            }
            catch(WebException ex)
            {
                response = ex.Response as HttpWebResponse;
            }

            var notResponse = new NotificationResponse
                                  {
                                      StatusCode = (int)response.StatusCode,
                                      NotificationStatus = response.Headers["X-NotificationStatus"],
                                      SubscriptionStatus = response.Headers["X-SubscriptionStatus"],
                                      DeviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"]
                                  };

            return notResponse;
        }