예제 #1
0
        public void SendNotification(INotification notification, SendNotificationCallbackDelegate callback)
        {
            if (string.IsNullOrEmpty(googleAuthToken))
            {
                RefreshGoogleAuthToken();
            }

            var msg = notification as C2dmNotification;

            var result = new C2dmMessageTransportResponse();

            result.Message = msg;

            //var postData = msg.GetPostData();

            var webReq = (HttpWebRequest)WebRequest.Create(C2DM_SEND_URL);

            //webReq.ContentLength = postData.Length;
            webReq.Method      = "POST";
            webReq.ContentType = "application/x-www-form-urlencoded";
            webReq.UserAgent   = "PushSharp (version: 1.0)";
            webReq.Headers.Add("Authorization: GoogleLogin auth=" + googleAuthToken);

            webReq.BeginGetRequestStream(requestStreamCallback, new C2dmAsyncParameters()
            {
                Callback        = callback,
                WebRequest      = webReq,
                WebResponse     = null,
                Message         = msg,
                GoogleAuthToken = googleAuthToken,
                SenderId        = androidSettings.SenderID,
                ApplicationId   = androidSettings.ApplicationID
            });
        }
예제 #2
0
        private void ProcessResponse(C2dmAsyncParameters asyncParam, C2dmMessageTransportResponse response)
        {
            //Check if our token was expired and refresh/requeue if need be
            if (response.ResponseCode == MessageTransportResponseCode.InvalidAuthToken)
            {
                Interlocked.Decrement(ref waitCounter);
                asyncParam.Callback(this, new SendNotificationResult(asyncParam.Message, true, new Exception("Invalid Auth Token Response")));
                this.googleAuthToken = string.Empty;
                return;
            }

            if (response.ResponseStatus == MessageTransportResponseStatus.Ok)
            {
                asyncParam.Callback(this, new SendNotificationResult(response.Message));                 //Msg ok!
            }
            else if (response.ResponseStatus == MessageTransportResponseStatus.InvalidRegistration || response.ResponseStatus == MessageTransportResponseStatus.NotRegistered)
            {
                //Device subscription is no good!
                asyncParam.Callback(this, new SendNotificationResult(response.Message, false, new DeviceSubscriptonExpiredException())
                {
                    OldSubscriptionId = response.Message.RegistrationId, IsSubscriptionExpired = true
                });
            }
            else
            {
                //Message Failed some other way
                asyncParam.Callback(this, new SendNotificationResult(response.Message, false, new Exception(response.ResponseStatus.ToString())));
            }

            Interlocked.Decrement(ref waitCounter);
        }
예제 #3
0
 public MessageTransportException(string message, C2dmMessageTransportResponse response)
     : base(message)
 {
     this.Response = response;
 }
예제 #4
0
 public InvalidAuthenticationTokenTransportException(C2dmMessageTransportResponse response)
     : base("Invalid ClientLogin GoogleLogin Authentication Token", response)
 {
 }
예제 #5
0
 public ServiceUnavailableTransportException(TimeSpan retryAfter, C2dmMessageTransportResponse response)
     : base("Service Temporarily Unavailable.  Please wait the retryAfter amount and implement an Exponential Backoff", response)
 {
     this.RetryAfter = retryAfter;
 }
예제 #6
0
        void processResponseError(C2dmAsyncParameters asyncParam)
        {
            var result = new C2dmMessageTransportResponse()
            {
                ResponseCode   = MessageTransportResponseCode.Error,
                ResponseStatus = MessageTransportResponseStatus.Error,
                Message        = asyncParam != null ? asyncParam.Message : null,
                MessageId      = string.Empty
            };

            try
            {
                if (asyncParam.WebResponse.StatusCode == HttpStatusCode.Unauthorized)
                {
                    //401 bad auth token
                    result.ResponseCode   = MessageTransportResponseCode.InvalidAuthToken;
                    result.ResponseStatus = MessageTransportResponseStatus.Error;
                    //throw new InvalidAuthenticationTokenTransportException(result);
                }
                else if (asyncParam.WebResponse.StatusCode == HttpStatusCode.ServiceUnavailable)
                {
                    //First try grabbing the retry-after header and parsing it.
                    TimeSpan retryAfter = new TimeSpan(0, 0, 120);

                    var wrRetryAfter = asyncParam.WebResponse.GetResponseHeader("Retry-After");

                    if (!string.IsNullOrEmpty(wrRetryAfter))
                    {
                        DateTime wrRetryAfterDate = DateTime.UtcNow;

                        if (DateTime.TryParse(wrRetryAfter, out wrRetryAfterDate))
                        {
                            retryAfter = wrRetryAfterDate - DateTime.UtcNow;
                        }
                        else
                        {
                            int wrRetryAfterSeconds = 120;
                            if (int.TryParse(wrRetryAfter, out wrRetryAfterSeconds))
                            {
                                retryAfter = new TimeSpan(0, 0, wrRetryAfterSeconds);
                            }
                        }
                    }

                    //503 exponential backoff, get retry-after header
                    result.ResponseCode   = MessageTransportResponseCode.ServiceUnavailable;
                    result.ResponseStatus = MessageTransportResponseStatus.Error;

                    throw new ServiceUnavailableTransportException(retryAfter, result);
                }
            }
            finally
            {
                if (asyncParam != null && asyncParam.WebResponse != null)
                {
                    asyncParam.WebResponse.Close();
                }
            }

            ProcessResponse(asyncParam, result);
        }
예제 #7
0
        void processResponseOk(C2dmAsyncParameters asyncParam)
        {
            var result = new C2dmMessageTransportResponse()
            {
                ResponseCode   = MessageTransportResponseCode.Ok,
                ResponseStatus = MessageTransportResponseStatus.Ok,
                Message        = asyncParam.Message,
                MessageId      = string.Empty
            };

            var updateClientAuth = asyncParam.WebResponse.GetResponseHeader("Update-Client-Auth");

            //Update our client auth if necessary
            if (!string.IsNullOrEmpty(updateClientAuth))
            {
                googleAuthToken = updateClientAuth;
            }

            //Get the response body
            var responseBody = "Error=";

            try { responseBody = (new StreamReader(asyncParam.WebResponse.GetResponseStream())).ReadToEnd(); }
            catch { }

            //Handle the type of error
            if (responseBody.StartsWith("Error="))
            {
                var wrErr = responseBody.Substring(responseBody.IndexOf("Error=") + 6);
                switch (wrErr.ToLower().Trim())
                {
                case "quotaexceeded":
                    result.ResponseStatus = MessageTransportResponseStatus.QuotaExceeded;
                    break;

                case "devicequotaexceeded":
                    result.ResponseStatus = MessageTransportResponseStatus.DeviceQuotaExceeded;
                    break;

                case "invalidregistration":
                    result.ResponseStatus = MessageTransportResponseStatus.InvalidRegistration;
                    break;

                case "notregistered":
                    result.ResponseStatus = MessageTransportResponseStatus.NotRegistered;
                    break;

                case "messagetoobig":
                    result.ResponseStatus = MessageTransportResponseStatus.MessageTooBig;
                    break;

                case "missingcollapsekey":
                    result.ResponseStatus = MessageTransportResponseStatus.MissingCollapseKey;
                    break;

                default:
                    result.ResponseStatus = MessageTransportResponseStatus.Error;
                    break;
                }

                result.ResponseCode = MessageTransportResponseCode.Error;
                //throw new MessageTransportException(wrErr, result);
            }
            else
            {
                //Get the message ID
                if (responseBody.StartsWith("id="))
                {
                    result.MessageId = responseBody.Substring(3).Trim();
                }
            }

            asyncParam.WebResponse.Close();

            ProcessResponse(asyncParam, result);
        }