Статьи

Производительность с помощью WAMS: об объекте mpns (передача данных на Windows Phone пользователя)

WAMS

Когда дело доходит до мобильных сервисов, есть много вещей, которые вы можете сделать с данными пользователя. Одним из них является обновление Live Tiles своих приложений, а также отправка им уведомлений о тостах. Чтобы понять, как работает mpns (служба push-уведомлений Microsoft), см. Изображение ниже и прочтите эту статью на MSDN:
http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff402558(v= vs.105) .aspx

график mpns

В Windows Azure есть довольно простой пример обновления Live Tiles:
http://www.windowsazure.com/en-us/develop/mobile/tutorials/push-notifications-to-users-wp8/ . Однако этот пример отправляет данные из приложения в Azure и обратно обратно на устройство пользователя. Это хорошее начало, если вы хотите понять, как оно работает, но оно не отражает наиболее распространенный сценарий: сервер загружает данные с закрытым приложением на пользовательском устройстве.

Самая важная часть: получение действующего push-канала из службы Push-клиентов

Теперь, когда мы знаем, как работает служба push-уведомлений, нам нужно наше приложение Windows Phone для получения действительного push-канала. Это делается с помощью нескольких строк кода в App.xaml.cs. Во-первых, нам нужен глобально объявленный push-канал:

public static HttpNotificationChannel pushTileChannel { get; set; }

С помощью этой глобальной переменной мы теперь можем получить действительный push-канал в наше приложение и в нашу мобильную службу:

public static void AcquirePushChannel()
        {
                  pushTileChannel = HttpNotificationChannel.Find("msicc-test");

                if (pushTileChannel == null)
                {
                    pushTileChannel = new HttpNotificationChannel("msicc-test");

                    pushTileChannel.Open();

       //this binds the push notification to your live tile       
       pushTileChannel.BindToShellTile();

       //this binds the push notification to toasts
       pushTileChannel.BindToShellToast();

 }        

                IMobileServiceTable<pushChannel> pushChannelTable = App.MobileService.GetTable<pushChannel>();
                var channel = new pushChannel { Uri = pushTileChannel.ChannelUri.ToString() };
                pushChannelTable.InsertAsync(channel);
           }

Метод Find («requiredNameOfChannel») создает или находит канал, эксклюзивный для вашего приложения, и должен быть одинаковым для всех ваших пользователей. Наконец, метод Open () открывает соединение вашего приложения со службой Push Client. Чтобы автоматически получать обновления для Tiles и Toast, мы используем методы BindToShellTile () и BindToShellToast ().
Важно для изображений: вам нужно разрешить URL-адреса, с которых могут быть изображения. Для этого вам нужно добавить желаемый URI в методе BindToShellTile (). Если у вас есть несколько URI, из которых получены изображения, просто создайте Collection of Uri и добавьте их в перегрузку метода BindToShellTile (). Обратите внимание, что должен быть разрешен только домен верхнего уровня (указание папок не поддерживается).

public static Collection<Uri> allowedDomains = 
            new Collection<Uri> { 
                                                new Uri("https://yourmobileservice.azure-mobile.net"), 
                                                new Uri("https://yourseconduri.com/") 
                                              };

pushTileChannel.BindToShellTile(allowedDomains);

Но это не все. Нам также нужно добавить push-канал uri в нашу таблицу Windows Azure, чтобы обновить данные пользователей. Вот для чего нужны последние три строки кодов. Я настоятельно рекомендую отделить таблицу push-каналов от таблицы пользовательских данных, чтобы можно было легко работать с этой таблицей. Чтобы избежать дублирования каналов (которые могут сильно раздражать пользователей и вас самих), мы должны обновить наш скрипт данных на стороне сервера:

function insert(item, user, request) {

   var channelTable = tables.getTable('pushChannel');
        channelTable
            .where({ uri: item.uri })
            .read({ success: insertChannelIfNotFound });
        function insertChannelIfNotFound(existingChannels) {
            if (existingChannels.length > 0) {
                request.respond(200, existingChannels[0]);
            } else {
                request.execute();
            }
        }
}

Таким образом, вы все настроены для обновления Live Tile вашего приложения и для уведомлений Toast. Но до сих пор наш мобильный сервис не отправляет данные в наше приложение.

Как обновить Live Tiles и отправлять уведомления о тостах из мобильных сервисов

После того, как наш серверный код извлечет все данные, нам, безусловно, нужно обновить живые плитки нашего пользователя или даже отправлять уведомления о тостах. Мы можем отправлять следующие типы плиток и уведомлений:

FlipTile является самым крутым из всех и имеет большинство вариантов, которые вы можете использовать. Вот почему я выбираю его вместо «обычной» плитки. Чтобы передать данные нашим пользователям, мы используем этот код:

//call the push channel table

var channelTable = tables.getTable('pushChannel');

//send toast and Tile:

channelTable
    .where({user:userid})
    .read({
        success: function(channels){
            channels.forEach(function(channel) 
                {
                    push.mpns.sendToast(channel.uri, {
                        text1: ToastText1,
                        text2: ToastText2
                        }, {
                    success:function(pushResponse) {
                        console.log("Sent toast: ", channel.id, pushResponse);
                    },
                    error: function (error){
                        console.error("error in Toast Push Channel: " +  channel.id, error)
                    }
                });
                push.mpns.sendFlipTile(channel.uri, {
                     backgroundImage: backgroundImage,
                     backTitle: backTitle,
                     backContent: BackContent,
                     smallBackgroundImage: SmallBackgroundImage,
                     wideBackgroundImage: WideBackgroundImage,
                     wideBackContent:  WideBackContent,

                }, {
                    success:function(pushResponse) {
                        console.log("Sent tile:" ,  channel.id, pushResponse);
                    },
                    error: function (error){
                        console.error("error in Push Channel: "  channel.id, error)
                    }
                });
            });
        }
    });

Как вы можете видеть, мы используем довольно много полей в полезной нагрузке объекта mpns. Вы можете нажать на типы выше, чтобы увидеть, какие поля поддерживаются для каждого типа. Изображения, которые вы отправляете своим пользователям, должны быть действительными URL-адресами изображений. Максимальный размер — 80 КБ. Если ваши изображения больше, они не будут отправлены! Объект mpns имеет как обратный вызов «success», так и «error». Ошибка обратного вызова автоматически записывается в журнал. Однако очень трудно определить, какой идентификатор вызывает ошибку в этом случае. Вот почему вы должны реализовать это так, как я делал выше. Таким образом, вы точно знаете, какой идентификатор вызывает ошибку и какой идентификатор получил свое обновление правильно. Мы также можем добавить некоторые дополнительные функции для ответа на вызовы об успешном завершении и ошибках. Мне все еще нужно сделать это на моем WAMS,и я напишу о мерах, которые я предпринял в различных случаях, как только я это сделал (я начал использовать Azure только несколько месяцев назад, поэтому я также все еще учусь). Если вам интересно, вот список всех возможных кодов ответов для объекта mpns:
http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff941100(v=vs.105).aspx#BKMK_PushNotificationServiceResponseCodes

Вывод

Как вы видите, Windows Azure Mobile Services позволяет нам очень легко отправлять обновления пользователю в течение менее чем нашего времени для его настройки. Есть несколько вещей, которые мы должны принять во внимание — на самом деле, большинство из этих моментов заняло у меня много времени, чтобы выяснить это (поскольку я вообще впервые использую push). Как всегда, я надеюсь, что этот пост будет полезен для некоторых из вас. До следующего поста, счастливого кодирования!