void HandleStatus(WindowsNotificationStatus status)
        {
            if (MessageResponseReceived == null)
            {
                return;
            }

            //RESPONSE HEADERS
            // X-WNS-Debug-Trace string
            // X-WNS-DeviceConnectionStatus connected | disconnected | tempdisconnected (if RequestForStatus was set to true)
            // X-WNS-Error-Description string
            // X-WNS-Msg-ID string (max 16 char)
            // X-WNS-NotificationStatus received | dropped | channelthrottled
            //

            // 200 OK
            // 400 One or more headers were specified incorrectly or conflict with another header.
            // 401 The cloud service did not present a valid authentication ticket. The OAuth ticket may be invalid.
            // 403 The cloud service is not authorized to send a notification to this URI even though they are authenticated.
            // 404 The channel URI is not valid or is not recognized by WNS. - Raise Expiry
            // 405 Invalid Method - never will get
            // 406 The cloud service exceeded its throttle limit.
            // 410 The channel expired. - Raise Expiry
            // 413 The notification payload exceeds the 5000 byte size limit.
            // 500 An internal failure caused notification delivery to fail.
            // 503 The server is currently unavailable.
            MessageResponseReceived(status);
        }
예제 #2
0
        WindowsNotificationStatus ParseStatus(HttpWebResponse resp, WindowsNotification notification)
        {
            var result = new WindowsNotificationStatus()
            {
                HttpStatus = HttpStatusCode.OK
            };

            try
            {
                if (resp != null)
                {
                    result.Notification = notification;
                    result.HttpStatus   = resp.StatusCode;

                    var wnsDebugTrace             = resp.Headers["X-WNS-Debug-Trace"];
                    var wnsDeviceConnectionStatus = resp.Headers["X-WNS-DeviceConnectionStatus"] ?? "connected";
                    var wnsErrorDescription       = resp.Headers["X-WNS-Error-Description"];
                    var wnsMsgId = resp.Headers["X-WNS-Msg-ID"];
                    var wnsNotificationStatus = resp.Headers["X-WNS-NotificationStatus"] ?? "";

                    result.DebugTrace       = wnsDebugTrace;
                    result.ErrorDescription = wnsErrorDescription;
                    result.MessageID        = wnsMsgId;

                    if (wnsNotificationStatus.Equals("received", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result.NotificationStatus = WindowsNotificationSendStatus.Received;
                    }
                    else if (wnsNotificationStatus.Equals("dropped", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result.NotificationStatus = WindowsNotificationSendStatus.Dropped;
                    }
                    else
                    {
                        result.NotificationStatus = WindowsNotificationSendStatus.ChannelThrottled;
                    }

                    if (wnsDeviceConnectionStatus.Equals("connected", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result.DeviceConnectionStatus = WindowsDeviceConnectionStatus.Connected;
                    }
                    else if (wnsDeviceConnectionStatus.Equals("tempdisconnected", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result.DeviceConnectionStatus = WindowsDeviceConnectionStatus.TempDisconnected;
                    }
                    else
                    {
                        result.DeviceConnectionStatus = WindowsDeviceConnectionStatus.Disconnected;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error("Error parsing notification status: {0}", ex.ToString());
            }
            return(result);
        }
예제 #3
0
        void HandleStatus(WindowsNotificationStatus status, SendNotificationCallbackDelegate callback)
        {
            Boolean shouldRequeue = false;

            if (callback == null)
            {
                return;
            }

            //RESPONSE HEADERS
            // X-WNS-Debug-Trace   string
            // X-WNS-DeviceConnectionStatus  connected | disconnected | tempdisconnected   (if RequestForStatus was set to true)
            // X-WNS-Error-Description  string
            // X-WNS-Msg-ID   string  (max 16 char)
            // X-WNS-NotificationStatus   received | dropped | channelthrottled
            //

            // 200 OK
            // 400  One or more headers were specified incorrectly or conflict with another header.
            // 401  The cloud service did not present a valid authentication ticket. The OAuth ticket may be invalid.
            // 403  The cloud service is not authorized to send a notification to this URI even though they are authenticated.
            // 404	The channel URI is not valid or is not recognized by WNS. - Raise Expiry
            // 405	Invalid Method - never will get
            // 406	The cloud service exceeded its throttle limit.
            // 410	The channel expired. - Raise Expiry
            // 413	The notification payload exceeds the 5000 byte size limit.
            // 500	An internal failure caused notification delivery to fail.
            // 503	The server is currently unavailable.
            if (status.HttpStatus == HttpStatusCode.OK &&
                status.NotificationStatus == WindowsNotificationSendStatus.Received)
            {
                callback(this, new SendNotificationResult(status.Notification));
                return;
            }

            if (status.HttpStatus == HttpStatusCode.Unauthorized)
            {
                Trace.WriteLine("Status no autorizado, reencolando");
                shouldRequeue = true;
            }

            if (status.HttpStatus == HttpStatusCode.NotFound || status.HttpStatus == HttpStatusCode.Gone) //404 or 410
            {
                callback(this, new SendNotificationResult(status.Notification, false, new Exception("Device Subscription Expired"))
                {
                    IsSubscriptionExpired = true,
                    OldSubscriptionId     = status.Notification.ChannelUri,
                    SubscriptionExpiryUtc = DateTime.UtcNow
                });

                return;
            }

            callback(this, new SendNotificationResult(status.Notification, shouldRequeue, new WindowsNotificationSendFailureException(status)));
        }
        WindowsNotificationStatus ParseStatus(HttpWebResponse resp, WindowsNotification notification)
        {
            var result = new WindowsNotificationStatus();

            result.Notification = notification;
            result.HttpStatus   = resp.StatusCode;

            var wnsDebugTrace             = resp.Headers["X-WNS-Debug-Trace"];
            var wnsDeviceConnectionStatus = resp.Headers["X-WNS-DeviceConnectionStatus"] ?? "connected";
            var wnsErrorDescription       = resp.Headers["X-WNS-Error-Description"];
            var wnsMsgId = resp.Headers["X-WNS-Msg-ID"];
            var wnsNotificationStatus = resp.Headers["X-WNS-NotificationStatus"] ?? "";
            var wnsAuthenticate       = resp.Headers["WWW-Authenticate"];

            result.DebugTrace       = wnsDebugTrace;
            result.ErrorDescription = wnsErrorDescription;
            result.MessageID        = wnsMsgId;

            if (wnsNotificationStatus.Equals("received", StringComparison.InvariantCultureIgnoreCase))
            {
                result.NotificationStatus = WindowsNotificationSendStatus.Received;
            }
            else if (wnsNotificationStatus.Equals("dropped", StringComparison.InvariantCultureIgnoreCase))
            {
                result.NotificationStatus = WindowsNotificationSendStatus.Dropped;
            }
            else if (wnsAuthenticate != null && wnsAuthenticate.Contains("Token expired"))
            {
                result.NotificationStatus = WindowsNotificationSendStatus.TokenExpired;
            }
            else
            {
                result.NotificationStatus = WindowsNotificationSendStatus.ChannelThrottled;
            }

            if (wnsDeviceConnectionStatus.Equals("connected", StringComparison.InvariantCultureIgnoreCase))
            {
                result.DeviceConnectionStatus = WindowsDeviceConnectionStatus.Connected;
            }
            else if (wnsDeviceConnectionStatus.Equals("tempdisconnected", StringComparison.InvariantCultureIgnoreCase))
            {
                result.DeviceConnectionStatus = WindowsDeviceConnectionStatus.TempDisconnected;
            }
            else
            {
                result.DeviceConnectionStatus = WindowsDeviceConnectionStatus.Disconnected;
            }

            return(result);
        }
예제 #5
0
 void transport_MessageResponseReceived(WindowsNotificationStatus status)
 {
     if (status.HttpStatus == HttpStatusCode.OK && status.NotificationStatus == WindowsNotificationSendStatus.Received)
     {
         //It worked! Raise success
         this.Events.RaiseNotificationSent(status.Notification);
     }
     else if (status.NotificationStatus == WindowsNotificationSendStatus.TokenExpired)
     {
         // If token expired sendind a notification, requeue it again
         this.QueueNotification(status.Notification);
     }
     else
     {
         // Something happened
         this.Events.RaiseNotificationSendFailure(status.Notification, new Exception(status.ErrorDescription));
     }
     Interlocked.Decrement(ref PendingNotificationsResult);
     Interlocked.Decrement(ref waitCounter);
 }
예제 #6
0
        void HandleStatus(WindowsNotificationStatus status)
        {
            //RESPONSE HEADERS
            // X-WNS-Debug-Trace   string
            // X-WNS-DeviceConnectionStatus  connected | disconnected | tempdisconnected   (if RequestForStatus was set to true)
            // X-WNS-Error-Description  string
            // X-WNS-Msg-ID   string  (max 16 char)
            // X-WNS-NotificationStatus   received | dropped | channelthrottled
            //

            // 200 OK
            // 400  One or more headers were specified incorrectly or conflict with another header.
            // 401  The cloud service did not present a valid authentication ticket. The OAuth ticket may be invalid.
            // 403  The cloud service is not authorized to send a notification to this URI even though they are authenticated.
            // 404	The channel URI is not valid or is not recognized by WNS. - Raise Expiry
            // 405	Invalid Method - never will get
            // 406	The cloud service exceeded its throttle limit.
            // 410	The channel expired. - Raise Expiry
            // 413	The notification payload exceeds the 5000 byte size limit.
            // 500	An internal failure caused notification delivery to fail.
            // 503	The server is currently unavailable.
            if (status.HttpStatus == HttpStatusCode.OK
                && status.NotificationStatus == WindowsNotificationSendStatus.Received)
            {
                this.Events.RaiseNotificationSent(status.Notification);
                return;
            }
            else if (status.HttpStatus == HttpStatusCode.NotFound) //404
            {
                this.Events.RaiseDeviceSubscriptionExpired(PlatformType.Windows, status.Notification.ChannelUri, status.Notification);
            }
            else if (status.HttpStatus == HttpStatusCode.Gone) //410
            {
                this.Events.RaiseDeviceSubscriptionExpired(PlatformType.Windows, status.Notification.ChannelUri, status.Notification);
            }

            this.Events.RaiseNotificationSendFailure(status.Notification, new WindowsNotificationSendFailureException(status));
        }
예제 #7
0
        void HandleStatus(WindowsNotificationStatus status)
        {
            //RESPONSE HEADERS
            // X-WNS-Debug-Trace   string
            // X-WNS-DeviceConnectionStatus  connected | disconnected | tempdisconnected   (if RequestForStatus was set to true)
            // X-WNS-Error-Description  string
            // X-WNS-Msg-ID   string  (max 16 char)
            // X-WNS-NotificationStatus   received | dropped | channelthrottled
            //

            // 200 OK
            // 400  One or more headers were specified incorrectly or conflict with another header.
            // 401  The cloud service did not present a valid authentication ticket. The OAuth ticket may be invalid.
            // 403  The cloud service is not authorized to send a notification to this URI even though they are authenticated.
            // 404	The channel URI is not valid or is not recognized by WNS. - Raise Expiry
            // 405	Invalid Method - never will get
            // 406	The cloud service exceeded its throttle limit.
            // 410	The channel expired. - Raise Expiry
            // 413	The notification payload exceeds the 5000 byte size limit.
            // 500	An internal failure caused notification delivery to fail.
            // 503	The server is currently unavailable.
            if (status.HttpStatus == HttpStatusCode.OK &&
                status.NotificationStatus == WindowsNotificationSendStatus.Received)
            {
                this.Events.RaiseNotificationSent(status.Notification);
                return;
            }
            else if (status.HttpStatus == HttpStatusCode.NotFound)             //404
            {
                this.Events.RaiseDeviceSubscriptionExpired(PlatformType.Windows, status.Notification.ChannelUri, status.Notification);
            }
            else if (status.HttpStatus == HttpStatusCode.Gone)             //410
            {
                this.Events.RaiseDeviceSubscriptionExpired(PlatformType.Windows, status.Notification.ChannelUri, status.Notification);
            }

            this.Events.RaiseNotificationSendFailure(status.Notification, new WindowsNotificationSendFailureException(status));
        }
예제 #8
0
        WindowsNotificationStatus ParseStatus(HttpWebResponse resp, WindowsNotification notification)
        {
            var result = new WindowsNotificationStatus();

            result.Notification = notification;
            result.HttpStatus = resp.StatusCode;

            var wnsDebugTrace = resp.Headers["X-WNS-Debug-Trace"];
            var wnsDeviceConnectionStatus = resp.Headers["X-WNS-DeviceConnectionStatus"] ?? "connected";
            var wnsErrorDescription = resp.Headers["X-WNS-Error-Description"];
            var wnsMsgId = resp.Headers["X-WNS-Msg-ID"];
            var wnsNotificationStatus = resp.Headers["X-WNS-NotificationStatus"] ?? "";

            result.DebugTrace = wnsDebugTrace;
            result.ErrorDescription = wnsErrorDescription;
            result.MessageID = wnsMsgId;

            if (wnsNotificationStatus.Equals("received", StringComparison.InvariantCultureIgnoreCase))
                result.NotificationStatus = WindowsNotificationSendStatus.Received;
            else if (wnsNotificationStatus.Equals("dropped", StringComparison.InvariantCultureIgnoreCase))
                result.NotificationStatus = WindowsNotificationSendStatus.Dropped;
            else
                result.NotificationStatus = WindowsNotificationSendStatus.ChannelThrottled;

            if (wnsDeviceConnectionStatus.Equals("connected", StringComparison.InvariantCultureIgnoreCase))
                result.DeviceConnectionStatus = WindowsDeviceConnectionStatus.Connected;
            else if (wnsDeviceConnectionStatus.Equals("tempdisconnected", StringComparison.InvariantCultureIgnoreCase))
                result.DeviceConnectionStatus = WindowsDeviceConnectionStatus.TempDisconnected;
            else
                result.DeviceConnectionStatus = WindowsDeviceConnectionStatus.Disconnected;

            return result;
        }
예제 #9
0
 public WindowsNotificationSendFailureException(WindowsNotificationStatus status)
     : base()
 {
     this.NotificationStatus = status;
 }
예제 #10
0
        public void SendNotification(INotification notification, SendNotificationCallbackDelegate callback)
        {
            //See if we need an access token
            if (string.IsNullOrEmpty(AccessToken))
            {
                Trace.WriteLine("AccessToken nulo, renovando");
                RenewAccessToken();
            }

            if (DateTime.Now > ExpiresIn)
            {
                Trace.WriteLine("AccessToken expirado, renovando");
                RenewAccessToken();
            }

            var winNotification = notification as WindowsNotification;

            //https://cloud.notify.windows.com/?token=.....
            //Authorization: Bearer {AccessToken}
            //

            var wnsType = string.Empty;

            switch (winNotification.Type)
            {
            case WindowsNotificationType.Tile:
                wnsType = "wns/tile";
                break;

            case WindowsNotificationType.Badge:
                wnsType = "wns/badge";
                break;

            case WindowsNotificationType.DeleteNotification:
            case WindowsNotificationType.Toast:
                wnsType = "wns/toast";
                break;

            default:
                wnsType = "wns/raw";
                break;
            }

            var request = (HttpWebRequest)HttpWebRequest.Create(winNotification.ChannelUri); // "https://notify.windows.com");

            if (winNotification.Type == WindowsNotificationType.DeleteNotification)
            {
                request.Method = "DELETE";
            }
            else
            {
                request.Method = "POST";
            }
            request.Headers.Add("X-WNS-Type", wnsType);
            request.Headers.Add("Authorization", string.Format("Bearer {0}", this.AccessToken));
            request.ContentType = "text/xml";

            if (winNotification.Type == WindowsNotificationType.Raw)
            {
                request.ContentType = "application/octet-stream";
            }

            if (winNotification.Type == WindowsNotificationType.Tile)
            {
                var winTileNot = winNotification as WindowsTileNotification;

                if (winTileNot != null && winTileNot.CachePolicy.HasValue)
                {
                    request.Headers.Add("X-WNS-Cache-Policy", winTileNot.CachePolicy == WindowsNotificationCachePolicyType.Cache ? "cache" : "no-cache");
                }
            }
            else if (winNotification.Type == WindowsNotificationType.Badge)
            {
                if (winNotification is WindowsBadgeNumericNotification)
                {
                    var winTileBadge = winNotification as WindowsBadgeNumericNotification;

                    if (winTileBadge != null && winTileBadge.CachePolicy.HasValue)
                    {
                        request.Headers.Add("X-WNS-Cache-Policy", winTileBadge.CachePolicy == WindowsNotificationCachePolicyType.Cache ? "cache" : "no-cache");
                    }
                }
                else if (winNotification is WindowsBadgeGlyphNotification)
                {
                    var winTileBadge = winNotification as WindowsBadgeGlyphNotification;

                    if (winTileBadge != null && winTileBadge.CachePolicy.HasValue)
                    {
                        request.Headers.Add("X-WNS-Cache-Policy", winTileBadge.CachePolicy == WindowsNotificationCachePolicyType.Cache ? "cache" : "no-cache");
                    }
                }
            }
            else if (winNotification.Type == WindowsNotificationType.Toast)
            {
                var winToastPopup = winNotification as WindowsToastNotification;;

                if (winToastPopup != null && winToastPopup.SuppressPopup)
                {
                    request.Headers.Add("X-WNS-SuppressPopup", "true");
                }
            }
            else if (winNotification.Type == WindowsNotificationType.DeleteNotification)
            {
                var deleteArgs = "type=wns/toast";
                if (!string.IsNullOrEmpty(winNotification.NotificationTag))
                {
                    deleteArgs += string.Format(";tag={0}", winNotification.NotificationTag);
                }
                if (!string.IsNullOrEmpty(winNotification.NotificationGroup))
                {
                    deleteArgs += string.Format(";group={0}", winNotification.NotificationGroup);
                }

                request.Headers.Add("X-WNS-Match", deleteArgs);
            }

            if (winNotification.RequestForStatus.HasValue)
            {
                request.Headers.Add("X-WNS-RequestForStatus", winNotification.RequestForStatus.Value.ToString().ToLower());
            }

            if (!string.IsNullOrEmpty(winNotification.NotificationTag))
            {
                request.Headers.Add("X-WNS-Tag", winNotification.NotificationTag);
            }

            if (!string.IsNullOrEmpty(winNotification.NotificationGroup))
            {
                request.Headers.Add("X-WNS-Group", winNotification.NotificationGroup);
            }

            if (winNotification.TimeToLive.HasValue)
            {
                request.Headers.Add("X-WNS-TTL", winNotification.TimeToLive.Value.ToString()); //Time to live in seconds
            }
            //Microsoft recommends we disable expect-100 to improve latency
            request.ServicePoint.Expect100Continue = false;

            var payload = winNotification.PayloadToString();
            var data    = Encoding.UTF8.GetBytes(payload);

            request.ContentLength = data.Length;

            using (var rs = request.GetRequestStream())
                rs.Write(data, 0, data.Length);

            try
            {
                request.BeginGetResponse(new AsyncCallback(getResponseCallback), new object[] { request, winNotification, callback });
            }
            catch (WebException wex)
            {
                WindowsNotificationStatus status = null;
                try
                {
                    //Handle different httpstatuses
                    status = ParseStatus(wex.Response as HttpWebResponse, winNotification);
                    HandleStatus(status, callback);
                }
                catch (Exception ex)
                {
                    Log.Error(ex.Message, ex);
                    HandleStatus(new WindowsNotificationStatus()
                    {
                        HttpStatus             = HttpStatusCode.RequestTimeout,
                        DeviceConnectionStatus = WindowsDeviceConnectionStatus.Connected,
                        MessageID          = "",
                        Notification       = winNotification,
                        NotificationStatus = WindowsNotificationSendStatus.Dropped,
                    }, callback);
                }
            }
        }
예제 #11
0
		void HandleStatus(WindowsNotificationStatus status, SendNotificationCallbackDelegate callback)
		{
			if (callback == null)
				return;

			//RESPONSE HEADERS
			// X-WNS-Debug-Trace   string
			// X-WNS-DeviceConnectionStatus  connected | disconnected | tempdisconnected   (if RequestForStatus was set to true)
			// X-WNS-Error-Description  string
			// X-WNS-Msg-ID   string  (max 16 char)
			// X-WNS-NotificationStatus   received | dropped | channelthrottled
			//		

			// 200 OK
			// 400  One or more headers were specified incorrectly or conflict with another header.
			// 401  The cloud service did not present a valid authentication ticket. The OAuth ticket may be invalid.
			// 403  The cloud service is not authorized to send a notification to this URI even though they are authenticated.
			// 404	The channel URI is not valid or is not recognized by WNS. - Raise Expiry
			// 405	Invalid Method - never will get
			// 406	The cloud service exceeded its throttle limit.
			// 410	The channel expired. - Raise Expiry
			// 413	The notification payload exceeds the 5000 byte size limit.
			// 500	An internal failure caused notification delivery to fail.
			// 503	The server is currently unavailable.
			if (status.HttpStatus == HttpStatusCode.OK
				&& status.NotificationStatus == WindowsNotificationSendStatus.Received)
			{
				callback(this, new SendNotificationResult(status.Notification));
				return;
			}
			
			if (status.HttpStatus == HttpStatusCode.NotFound || status.HttpStatus == HttpStatusCode.Gone) //404 or 410
			{
				callback(this, new SendNotificationResult(status.Notification, false, new Exception("Device Subscription Expired"))
				{
					IsSubscriptionExpired = true,
					OldSubscriptionId = status.Notification.ChannelUri,
					SubscriptionExpiryUtc = DateTime.UtcNow
				});

				return;
			}

			callback(this, new SendNotificationResult(status.Notification, false, new WindowsNotificationSendFailureException(status)));
		}
예제 #12
0
 public WindowsNotificationSendFailureException(WindowsNotificationStatus status)
     : base()
 {
     this.NotificationStatus = status;
 }