상속: TableStorageEntity
예제 #1
0
        public async Task SaveChangesWithMergeAsync(InboxEntity inboxEntity)
        {
            const int MaxRetries = 5;
            Exception lastError = null;
            for (int i = 0; i < MaxRetries; i++)
            {
                try
                {
                    if (i > 0)
                    {
                        // Attempt to sync up our inboxEntity with the cloud before saving local changes again.
                        // We can drop the result. Just requerying is enough to solve the problem.
                        await this.Get(inboxEntity.RowKey).ExecuteSegmentedAsync(null);
                    }

                    await this.SaveChangesAsync();
                    return;
                }
                catch (DataServiceRequestException ex)
                {
                    lastError = ex;
                }
            }

            // Rethrow exception. We've failed too many times.
            ExceptionDispatchInfo.Capture(lastError).Throw();
        }
예제 #2
0
        public async Task SaveChangesWithMergeAsync(InboxEntity inboxEntity)
        {
            const int MaxRetries = 5;
            Exception lastError  = null;

            for (int i = 0; i < MaxRetries; i++)
            {
                try {
                    if (i > 0)
                    {
                        // Attempt to sync up our inboxEntity with the cloud before saving local changes again.
                        // We can drop the result. Just requerying is enough to solve the problem.
                        await this.Get(inboxEntity.RowKey).ExecuteSegmentedAsync(null);
                    }

                    await this.SaveChangesAsync();

                    return;
                } catch (DataServiceRequestException ex) {
                    lastError = ex;
                }
            }

            // Rethrow exception. We've failed too many times.
            ExceptionDispatchInfo.Capture(lastError).Throw();
        }
예제 #3
0
		public static InboxEntity Create() {
			var entity = new InboxEntity();

			var rng = RNGCryptoServiceProvider.Create();
			var inboxOwnerCode = new byte[CodeLength];
			rng.GetBytes(inboxOwnerCode);
			entity.InboxOwnerCode = Utilities.ToBase64WebSafe(inboxOwnerCode);
			entity.RowKey = Guid.NewGuid().ToString();

			return entity;
		}
예제 #4
0
        public static InboxEntity Create()
        {
            var entity = new InboxEntity();

            var rng            = RNGCryptoServiceProvider.Create();
            var inboxOwnerCode = new byte[CodeLength];

            rng.GetBytes(inboxOwnerCode);
            entity.InboxOwnerCode = Utilities.ToBase64WebSafe(inboxOwnerCode);
            entity.RowKey         = Guid.NewGuid().ToString();

            return(entity);
        }
예제 #5
0
 public void AddObject(InboxEntity entity)
 {
     this.AddObject(this.TableName, entity);
 }
예제 #6
0
        private async Task AlertLongPollWaiterAsync(InboxEntity inbox)
        {
            Requires.NotNull(inbox, "inbox");

            await this.PushNotifyInboxMessageAsync(inbox);

            var id = inbox.RowKey;
            TaskCompletionSource<object> tcs;
            lock (LongPollWaiters)
            {
                if (LongPollWaiters.TryGetValue(id, out tcs))
                {
                    LongPollWaiters.Remove(id);
                }
            }

            if (tcs != null)
            {
                tcs.TrySetResult(null);
            }
        }
예제 #7
0
 public void AddObject(InboxEntity entity)
 {
     this.AddObject(this.TableName, entity);
 }
예제 #8
0
 private async Task PushNotifyInboxMessageAppleAsync(InboxEntity inbox)
 {
     if (MvcApplication.IsApplePushRegistered)
     {
         if (!string.IsNullOrEmpty(inbox.ApplePushNotificationGatewayDeviceToken))
         {
             int count = await this.RetrieveInboxItemsCountAsync(inbox.RowKey);
             MvcApplication.PushBroker.QueueNotification(new AppleNotification()
                 .ForDeviceToken(inbox.ApplePushNotificationGatewayDeviceToken)
                 .WithBadge(count));
         }
     }
 }
예제 #9
0
        private async Task PushNotifyInboxMessageGoogleAsync(InboxEntity inbox)
        {
            if (!string.IsNullOrEmpty(inbox.GoogleCloudMessagingRegistrationId))
            {
                var notifications = new GooglePushNotifications(this.HttpClient, ConfigurationManager.AppSettings["GoogleApiKey"], inbox.GoogleCloudMessagingRegistrationId);

                bool invalidChannel = false;
                try
                {
                    bool successfulPush = await notifications.PushGoogleRawNotificationAsync(CancellationToken.None);
                    invalidChannel |= !successfulPush;
                }
                catch (HttpRequestException)
                {
                    invalidChannel = true;
                }

                if (invalidChannel)
                {
                    inbox.GoogleCloudMessagingRegistrationId = null;
                    this.InboxTable.UpdateObject(inbox);
                }
            }
        }
예제 #10
0
        private async Task PushNotifyInboxMessageWinPhoneAsync(InboxEntity inbox)
        {
            if (!string.IsNullOrEmpty(inbox.WinPhone8PushChannelUri))
            {
                var notifications = new WinPhonePushNotifications(this.HttpClient, new Uri(inbox.WinPhone8PushChannelUri));

                int count = await this.RetrieveInboxItemsCountAsync(inbox.RowKey);
                bool invalidChannel = false;
                try
                {
                    var pushTile = notifications.PushWinPhoneTileAsync(inbox.WinPhone8TileTemplate, count: count);
                    Task<bool> pushToast = Task.FromResult(false);
                    if (!string.IsNullOrEmpty(inbox.WinPhone8ToastText1) || !string.IsNullOrEmpty(inbox.WinPhone8ToastText2))
                    {
                        var line1 = string.Format(CultureInfo.InvariantCulture, inbox.WinPhone8ToastText1 ?? string.Empty, count);
                        var line2 = string.Format(CultureInfo.InvariantCulture, inbox.WinPhone8ToastText2 ?? string.Empty, count);
                        if (inbox.LastWinPhone8PushNotificationUtc.HasValue && inbox.LastAuthenticatedInteractionUtc.HasValue && inbox.LastWinPhone8PushNotificationUtc.Value > inbox.LastAuthenticatedInteractionUtc.Value)
                        {
                            // We've sent a toast notification more recently than the user has checked messages,
                            // so there's no reason to send another for now.
                            pushToast = Task.FromResult(true);
                        }
                        else
                        {
                            pushToast = notifications.PushWinPhoneToastAsync(line1, line2);
                        }
                    }

                    Task<bool> pushRaw = Task.FromResult(false);
                    if (!string.IsNullOrEmpty(inbox.WinPhone8PushChannelContent))
                    {
                        pushRaw = notifications.PushWinPhoneRawNotificationAsync(inbox.WinPhone8PushChannelContent);
                    }

                    await Task.WhenAll(pushTile, pushToast, pushRaw);
                    invalidChannel |= !(pushTile.Result || pushToast.Result || pushRaw.Result);
                }
                catch (HttpRequestException)
                {
                    invalidChannel = true;
                }

                if (invalidChannel)
                {
                    inbox.WinPhone8PushChannelUri = null;
                    inbox.WinPhone8PushChannelContent = null;
                    inbox.WinPhone8ToastText1 = null;
                    inbox.WinPhone8ToastText2 = null;
                }
                else
                {
                    inbox.LastWinPhone8PushNotificationUtc = DateTime.UtcNow;
                }

                this.InboxTable.UpdateObject(inbox);
            }
        }
예제 #11
0
        private async Task PushNotifyInboxMessageWinStoreAsync(InboxEntity inbox, int failedAttempts = 0)
        {
            if (string.IsNullOrEmpty(inbox.ClientPackageSecurityIdentifier) || string.IsNullOrEmpty(inbox.PushChannelUri))
            {
                return;
            }

            var client = await this.ClientTable.GetAsync(inbox.ClientPackageSecurityIdentifier);
            string bearerToken = client.AccessToken;
            var pushNotifyRequest = new HttpRequestMessage(HttpMethod.Post, inbox.PushChannelUri);
            pushNotifyRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", bearerToken);
            pushNotifyRequest.Headers.Add("X-WNS-Type", "wns/raw");
            pushNotifyRequest.Content = new StringContent(inbox.PushChannelContent ?? string.Empty);

            // yes, it's a string, but we must claim it's an octet-stream
            pushNotifyRequest.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

            var response = await this.HttpClient.SendAsync(pushNotifyRequest);
            if (response.IsSuccessStatusCode)
            {
                inbox.LastWindows8PushNotificationUtc = DateTime.UtcNow;
                this.InboxTable.UpdateObject(inbox);
            }
            else
            {
                if (failedAttempts == 0)
                {
                    var authHeader = response.Headers.WwwAuthenticate.FirstOrDefault();
                    if (authHeader != null)
                    {
                        if (authHeader.Parameter.Contains("Token expired"))
                        {
                            await client.AcquireWnsPushBearerTokenAsync(this.HttpClient);
                            this.ClientTable.UpdateObject(client);
                            await this.ClientTable.SaveChangesAsync();
                            await this.PushNotifyInboxMessageWinStoreAsync(inbox, failedAttempts + 1);
                            return;
                        }
                    }
                }

                // Log a failure.
                // TODO: code here.
            }
        }
예제 #12
0
        private async Task PushNotifyInboxMessageAsync(InboxEntity inbox)
        {
            Requires.NotNull(inbox, "inbox");

            await Task.WhenAll(
                this.PushNotifyInboxMessageWinStoreAsync(inbox),
                this.PushNotifyInboxMessageWinPhoneAsync(inbox),
                this.PushNotifyInboxMessageGoogleAsync(inbox),
                this.PushNotifyInboxMessageAppleAsync(inbox));
        }