Периодические обновления
Периодические обновления – это отличное доказательство того, что Microsoft по-настоящему прислушивается к мнению разработчиков. Когда была выпущена Developer Preview Windows 8, в Сентябре 2011, многие разработчики были сильно заинтересованы в реализации динамических плиток, но это могло быть реализованы лишь с помощью push-уведомлений и Windows Push Notification Service, даже если плитку нужно было обновлять не слишком часто. Другими словами, push-уведомления – это избыточно для приложений, которым каждый раз лишь нужно получить немного данных из веб-сервиса для создания обновления. Разработчики спрашивали: "Возможно ли, чтобы мое приложение исполнялось в фоновом режиме, периодически запрашивало данные с моего сервиса и затем выполняло обновление плиток и индикаторов событий?".
Это был совершенно справедливый вопрос, но, как описано выше, фоновые задачи очень тщательно контролируются и они разрешены только для специальных сценариев. Услышав этот вопрос, команда Microsoft, которая занимается плитками и уведомлениями, изучила проблему и обнаружила, что создание нового класса фоновых задач для подобных целей – это избыточно для низкочастотных обновлений плиток. Более того, они обнаружили, что даже если приложение может использовать фоновую задачу для этих целей, все они будут выполнять примерно одно и то же: получать данные с сервиса и заполнять шаблон плитки или индикатора событий. Поэтому, вместо добавления новой фоновой задачи, они добавили новый API для периодических обновлений, управляемых системой.
Этот API состоит из следующих методов классов TileUpdater (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.tileupdater.aspx ) и BadgeUpdater (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.badgeupdater.aspx ):
- TileUpdater.startPeriodicUpdate и BadgeUpdater.startPeriodicUpdate Выполняют настройку Windows на запрос обновления с заданного URI с указанной периодичностью (смотрите ниже). Эти вызовы удаляют любые URI ранее зарегистрированные для плитки. Приложение может задать необязательные дату и время, когда должны начаться регулярные обновления, и во всех случаях первый запрос происходит немедленно (очень полезно для отладки). Подходящее время для этих вызовов – старт приложения, возобновление приложения, и когда изменяются настройки, которые могут вызывать необходимость смены URI.
- TileUpdater.stopPeriodicUpdate и BadgeUpdater.stopPeriodicUpdate Останавливает текущий процесс периодических обновлений, но не очищает существующие обновления плитки.
- TileUpdater.startPeriodicUpdateBatch Используется лишь для обновления плитки, идентичен startPeriodicUpdate , но принимает массив размером до 5 URI, автоматически создавая очередь обновлений с результатами (заменяя предыдущие URI). Отметим, что TileUpdater.enableNotificationQueue должен быть установлен в true перед использованием этого метода, как описано выше, в разделе "Циклические и запланированные обновления, обновления со сроком действия"
Во всех этих случаях каждый из URI представлен объектом Windows.Foundation.Uri (http://msdn.microsoft.com/library/windows/apps/windows.foundation.uri.aspx ), а периодичность опроса является значением перечисления PeriodicUpdateRecurrence (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.periodicupdaterecurrence.aspx ). Значения этого перечисления – halfHour, hour, sixHours, twelveHours, и daily (полчаса, час, шесть часов, двенадцать часов, раз в день), дают понятное описание периодичности обновления и предназначены для содержимого, которое изменяется сравнительно редко, наподобие информации о погоде, ежедневных предложений из магазинов (в таком случае используется время начала), или сведений о фазах луны. Для того, что требует более срочной доставки, наподобие напоминаний о встречах, сведений о пробках на дорогах, текущей информации о спортивных играх или о состоянии онлайнового аукциона, нужно использовать push-уведомления.
В дополнение, все эти обновления могут задействовать теги и срок действия, как и локальные обновлений. Единственная деталь заключается в том, что в любой заданный интервал опроса, веб-сервис может возвратить лишь один пакет с полезной информацией – отсюда необходимость в startPeriodicUpdateBatch. Тем не менее, если включена очередь оповещений и обновления с одного веб-сервиса содержат различные теги, динамическая плитка будет вести себя так же, как если бы эти обновления были отправлены локально: наиболее свежее обновление для каждого тега (до пяти) будет отображаться в общем цикле.
Подсказка. API периодических обновлений не предоставляет средств для авторизации на сервисе. Обычно это и не нужно, так как периодические обновления не разрабатываются для конкретного пользователя. Однако, вы можете включить в URI зашифрованные учетные данные, с помощью строки запроса. Так же вы можете использовать возможность Корпоративная аутентификация (Enterprise Authentication), если приложение исполняется на компьютере, входящем в домен.
Со стороны приложения ситуация с периодическими обновления показана в примере "Push-уведомления и периодические уведомления, клиентская часть" (http://code.msdn.microsoft.com/windowsapps/Push-and-periodic-de225603 ). В частности, посмотрите Сценарии 4 и 5, где представлены обычные средства для использования методов TileUpdater и BadgeUpdater с заданным URI сервиса, как я уже описывал. Несколько строк кода (взятых из js/scenario4.js) выглядят так:
var notifications = Windows.UI.Notifications; var updater = notifications.TileUpdateManager.createTileUpdaterForApplication(); updater.enableNotificationQueue(true); updater.startPeriodicUpdate(urisToPoll[0], recurrence); updater.startPeriodicUpdateBatch(urisToPoll, recurrence);
Настоящая работа по периодическим обновлениям, однако, проводится самим сервисом, который ответственен за то, чтобы возвращать подходящий XML, из которого Windows может создать обновление. Если даже мы можем запустить приложение-клиент, нам нужен и какой-то сервис, к которому мы можем делать запросы, и, к несчастью, Windows SDK не предоставляет нам его. Поэтому давайте сами исправим эту ситуацию с помощью собственного сервиса.
Так как вы, вероятно, используете пример приложения-клиента для экспериментов с вашим собственным сервисом обновлений, несмотря на это, вам следует сделать пару изменений, в частности, для очистки существующих обновлений в функциях, которое останавливает опрос. В js/scenario4.js, измените функцию stopTilePolling следующим образом:
function stopTilePolling() { var updater = notifications.TileUpdateManager.createTileUpdaterForApplication(); updater.clear(); updater.stopPeriodicUpdate(); WinJS.log && WinJS.log("Stopped polling.", "sample", "status"); } Аналогично, измените stopBadgePolling в js/scenario5.js следующим образом: function stopBadgePolling() { var updater = notifications.BadgeUpdateManager.createBadgeUpdaterForApplication(); updater.clear(); updater.stopPeriodicUpdate(); WinJS.log && WinJS.log("Stopped polling.", "sample", "status"); }
Без этих изменений, старые обновления будут присутствовать на плитке даже после того, как вы остановите обновления. Если вы затем измените свой веб-сервис, но у него будет ошибка в XML, вы не увидите никаких изменений на плитке и может думать, что обновление работает, в то время, как на самом деле это не так. Поверьте мне, выполнение этих небольших изменений упростит вашу жизнь!
Веб-сервисы для обновлений
Создание веб-сервиса для периодических обновления подразумевает создание веб-страницы, доступной по некоторому URI, единственная цель которой – отвечать на XmlHttpRequest отправкой XML –одержимого для объектов TileNotification или BadgeNotification. В идеале, такая страница так же обрабатывает параметры масштабирования, доступности и локализации, предоставленные в строке запроса, как описано ранее в разделе "Использование локальных изображений и изображений, полученных из веб"
Эта страница может быть реализована с использованием любого желаемого языка и инструмента, такого, как PHP или ASP.NET. На самом деле, если только вы не любите программировать в Блокноте, вам нужно использовать какой-нибудь хороший инструмент для веб-разработки. Visual Studio Express для Windows 8 не предназначен для подобных задач, в отличие от полной версии Visual Studio 2012. Так же вы можете взглянуть на Visual Studio Express 2012 для Web, как на другой вариант; подробнее об этом ниже. Если вы используете ASP.NET, напомню, что вы можете применить Notifications Extensions Library для упрощения создания XML для плитки.
Некоторые примеры страниц, которые предоставляют обновления для плиток даны в материале "Эффективное использование плиток (часть 2)" ( http://blogs.msdn.com/b/windowsappdev_ru/archive/2012/04/25/10297724.aspx) в блоге для разработчиков приложений для Windows 8. Основываясь на этих примерах, вот простая (но функциональная однострочная PHP-страница, которая отправляет XML для обновление для индикаторы событий, содержащее текущий день месяца:
<?php echo "<badge value='".date("j")."'/>"; ?>
Для того, чтобы она вернула нам XML подходящего формата, нам слудует так же включить заголовочный элемент, который так же участвует в работе:
<?php echo '<?xml version="1.0" encoding="utf-8"?>'; echo "<badge value='".date("j")."'/>"; ?>
Поместите этот код в .php-файл (смотрите HelloTiles/dayofmonthservice.php в дополнительных материалах) на любом веб-сервере, к которому у вас есть доступ, и – вуаля! Получился очень простой сервис, который доставляет обновления для индикатора событий. Вы можете использовать его в Сценарии 5 примера "Push-уведомления и периодические уведомления, клиентская часть" - введите URI вашей страницы в соответствующее поле, нажмите кнопку для начала выполнения запросов и затем проверьте плитку примера на Начальном экране. Через несколько секунд вы должны увидеть день месяца, который выглядит как индикатор событий. (Конечно, в этом сверхпростом примере дата отразит локальное время веб-сервера, а не время устройства, которые могут полностью различаться. Настоящий сервис должен различать часовой пояс и другие особенности расположения пользователя).
Совет. Обновления плиток и индикаторов событий очень чувствительны к правильно отформатированному XML. Если в вышеприведенный XML-код не включить закрывающий элемент / в код для badge, обновление не будет отображено. Для того, чтобы не было подобных тривиальных ошибок, и создана Notifications Extensions Library, по крайней мере, для ASP.NET. Надеюсь, что некоторые инициативные читатели могут обдумать подобный проект для PHP и других серверных языков.
Возвращаясь к материалу из блога для разработчиков приложений для Windows, упомянутому ранее, я хочу отметить, что пример на ASP.NET, который там дан, тот, что начинается с @{ использует синтаксис ASP.NET Razor (обычно – в файле .cshtml), представленный в Microsoft WebMatrix ( http://www.asp.net/web-pages). Razor/WebMatrix, вместе с инструментами, такими как Visual Studio Express 2012 для Web и другими дополнительными материалами, можно установить посредством веб-установщика (http://www.microsoft.com/web/downloads/platform.aspx ). Для того, чтобы познакомиться с Razor, который работает практически так же, как PHP, начните с материала "Пошаговое руководство. Создание веб-сайта с использованием синтаксиса Razor в Visual Studio" (http://msdn.microsoft.com/library/gg606533.aspx ).
Для того, чтобы вы смогли быстрее с этим разобраться, вот шаги, которые нужно выполнить в Visual Studio Express 2012 для Web для создания простого сервиса обновлений плиток на основе Razor-кода из вышеупомянутого сообщения блога:
- Выполните команду Файл > Создать веб-сайт (File > New Web Site) из меню.
- В диалоговом окне Новый веб-сайт (New Web Site) выберите ASP.NET Web Site (Razor v1), задайте имя и папку для проекта, и нажмите OK. Назовите этот сайт HelloTiles.
- Как только будет создан проект, вы должны увидеть открытый файл Default.cshtml.
- Скопируйте и вставьте следующий Razor-код в этот файл, заменив его содержимое по умолчанию. Небольшой фрагмент C#-кода в верхней части, для переменной weekday, понадобится нам в следующем разделе для демонстрации отладки. Он не используется при создании XML. Здесь, отмечу, что я тестировал и создавал XML-содержимое с использованием дизайнера плиток из сценария 5 примера "Плитки и индикаторы событий приложения" (http://code.msdn.microsoft.com/windowsapps/App-tiles-and-badges-sample-5fc49148 ) (смотрите
рис.
5.1. Это сэкономило мне много времени благодаря тому, что мне не пришлось гадать, не содержит ли мой XML ошибок.
@{ // // Здесь может быть размещен любой другой код для получения динамического содержимого, // необходимого для обновления плитки. Здесь мы лишь возвращаем статический XML // для того, чтобы показать структуру сервиса. // var weekDay = DateTime.Now.DayOfWeek; } <?xml version="1.0" encoding="utf-8" ?> <tile> <visual lang="en-US"> <binding template="TileSquarePeekImageAndText02" branding="none"> <image id="1" src="http://www.kraigbrockschmidt.com/images/Liam07.png"/> <text id="1">Liam--</text> <text id="2">Giddy on the day he learned to sit up!</text> </binding> <binding template="TileWideSmallImageAndText04" branding="none"> <image id="1" src="http://www.kraigbrockschmidt.com/images/Liam08.png"/> <text id="1">This is Liam</text> <text id="2">Exploring the great outdoors!</text> </binding> </visual> </tile>
- Откройте вебсайт в Internet Explorer, воспользовавшись командой Отладка > Начать отладку (Debug > Start Debugging) или кнопку Internet Explorer на панели управления (там, где параметры Локальный компьютер (Local Machine или Имитатор (Simulator) в Visual Studio Express 2012 для Windows 8). Это приведет к запуску Internet Explorer с URI наподобие http://localhost:52568/HelloTiles/Default.cshtml, где номер порта – это то, что указывает на URI сайта, исполняющегося в отладчике. Если вам нужно настроить ваш локальный сервер, смотрите следующий раздел "Использование локального хоста"
- Запустите пример "Push-уведомления и периодические уведомления, клиентская часть", перейдите в Сценарий 4, вставьте этот URI в поле URI1 и нажмите кнопку Start periodic updates (Начать периодические обновления).
- Если все хорошо, вы должны увидеть прямоугольную плитку обновленную, как показано ниже. (Да, я снова тут бессовестно показываю фото моего сына… ну что я скажу? Вы должны давать отцам время на отдых!)
- Если вы используете команду панели приложения Начального экрана для того, чтоы уменьшить плитку, что приведет к использованию полезного XML-содержимого для квадратной плитки, вы должны увидеть, как она переключится на другую неуместную фотографию моего сына и на текст для обзора:
Полный код этого веб-сайта вы можете найти в упражнении HelloTiles в дополнительных материалах к этой лекции. Так же просто, он предоставляет базовый фреймворк, в который вы можете добавить код для создания более динамичных результатов. В верхней части файла, внутри блока @{ }, вы можете писать любой необходимый код на C#.
Вообще говоря, реальный сервис, который предоставляет обновления плиток и индикаторов событий, возможно, будет соединен на серверной стороне с каким-то более полезным источником информации, возможно, с постоянно выполняющимся процессом, который может отслеживать состояние других сайтов, извлекать необходимые данные и создавать обновления. Эти обновления могут быть возвращены в ответе страницы, как мы видели здесь, или переданы WNS и переданы напрямую конкретному клиенту. Скоро мы вернемся к этой теме в разделе "Push-уведомления и Windows Push Notification Service".
На данный момент, более актуален вопрос о том, как отлаживать такие сервисы? К счастью, инструменты Visual Studio упрощают эту задачу с применением локального хоста (localhost).