Создаём сервис уведомлений для Windows Phone 7 на языке Ruby

Windows Phone 7 поддерживает Push-уведомления, которые позволяют делать такие вещи, как отправка уведомления для WP7 приложения, или обновление плитки приложения. Уведомления отправляются с помощью Microsoft Push Notification Service (MPNS) — бесплатного сервиса, который предоставляет Microsoft. Созданием уведомления занимаетесь Вы (точнее Ваш сервис) и передаете его MPNS, который затем направляет его WP7 устройству.
Я знаю как это реализовывается с помощью .Net и хотел реализовать тоже самое с помощью Ruby. Оказывается, это довольно просто.

Типы уведомлений
Существует три типа уведомлений, поддерживаемых WP7: тост-уведомления, тайл-уведомления и «сырые» (далее по тексту: сырые уведомления). Каждый из них имеет определенное назначение, поэтому мы должны понимать, что они делают, и когда их использовать. Вы можете прочесть описание использования для каждого из них: http://msdn.microsoft.com/en-us/library/ff402558(v=vs.92).aspx
Результатом тост-уведомления является предупреждение, которое появляется на экране в течение 10 секунд, но не нарушает то, что делает пользователь. Если нажать на это уведомление, то запустится связванное приложение. Этот тип уведомления используется для оповещений или других типов информационных сообщений, которые должны быть отображены пользователю, но не обязательны к выполнению действия прямо сейчас.
Тайл-уведомления изменяют плитку приложения, если плитка закреплена на стартовом экране. Вы можете изменить название, числовой счетчик, или даже заменить изображение для плитки. Начиная с обновления Mango, плитки поддерживают две стороны, и вы можете установить свойства каждой из сторон. Это удобный способ представления информации, без необходимости открытия приложения пользователем. Например, приложение электронной почты может обновлять число на счётчике, указывая количество новых сообщений.
Сырые уведомления просто передают данные приложению. Всё зависит от приложения, в соответствии с тем, что оно делает с этими данными.

URI уведомления
Для отправки уведомлений, вы должны знать URI на который нужно отправлять уведомления. Он создается приложением, работающем на WP7 устройстве. Раздел «Как это устроено» («How It Works») на странице http://msdn.microsoft.com/en-us/library/ff402558(v=vs.92).aspx содержит больше  информации об этом, но попросту приложение обращается к Microsoft Push Notification Service, который даёт ему уникальный URI, который затем передаётся вашему сервису уведомлений.
Я не собираюсь уделять большого внимания приложению для Windows Phone 7, так как оно находится не в фокусе этой статьи. Для тестирования я использовал клиентские приложения для Windows Phone 7 из примеров приложений, использующих уведомления, доступных на странице http://msdn.microsoft.com/en-us/library/ff431744(v=VS.92).aspx#BKMK_PushAndTiles .

Тело сообщений уведомлений
Сообщение уведомления отправляется с помощью HTTP запроса методом POST. Есть некоторые заголовки, которые должны быть установленыи, и формат тела зависит от типа отправляемого уведомления. Общими элементами для всех типов сообщений являются следующие HTTP заголовки:

  • Content-Type = text/html
  • Content-Length = length of the message
  • X-MessageID = unique ID
  • X-NotificationClass = int value

Первые два должны быть знакомы всем, кто работал с HTTP, но что это за X-MessageID и X-NotificationClass?
X-MessageID является необязательным заголовком, который позволяет указать уникальный идентификатор для этого сообщения, и вы сможете сравнить его со значением, возвращаемым в ответ на сообщение, сопоставив ответ и заголовок.
X-NotificationClass используется, чтобы указать, насколько важно это сообщение, так что MPNS  может объединять сообщения в партию, в зависимости от их важности и отправлять их на телефон разом. Это позволяет экономить батарею телефона, так как телефон должен получить только одну партию сообщений, а не неизвестное количество отдельных сообщений.
Но какие значения можно использовать в этом заголовке? Хотя их не трудно найти, но вот допустимые значения:

  • 1 – немедленное тайл-уведомление
  • 2 – немедленное тост-уведомление
  • 3 – немедленное сырое уведомление
  • 11 – тайл-уведомление в течение 450 секунд
  • 12 – тост-уведомление в течение 450 секунд
  • 13 – сырое уведомление в течение 450 секунд
  • 21 – тайл-уведомление в течение 900 секунд
  • 22 – тост-уведомление в течение 900 секунд
  • 23 – сырое уведомление в течение 900 секунд

Если вы отправляете сырое сообщение, это в значительной степени всё что вам нужно: зоголовки, тело, URI для отправки. Всё немного сложнее для тост-уведомлений и тайл-уведомлений.

Структура сообщения для тост-уведомления
Сообщение тост-уведомления имеет следующий формат:

<?xml version=’1.0′ encoding=’utf-8′?>

<wp:Notification xmlns:wp=’WPNotification’>
    <wp:Toast>
        <wp:Text1></wp:Text1>
        <wp:Text2></wp:Text2>
        <wp:Param></wp:Param>
    </wp:Toast>
</wp:Notification>

Для более подробной информации о тост-уведомлениях читайте http://msdn.microsoft.com/en-us/library/ff402558(v=vs.92).aspx.

Структура сообщения для тайл-уведомления
Сообщение тост-уведомления имеет следующий формат:

<?xml version=’1.0′ encoding=’utf-8′?>
<wp:Notification xmlns:wp=’WPNotification’>
    <wp:Tile>
        <wp:BackgroundImage></wp:BackgroundImage>
        <wp:Count></wp:Count>
        <wp:Title></wp:Title>
        <wp:BackBackgroundImage></wp:BackBackgroundImage>
        <wp:BackTitle></wp:BackTitle>
        <wp:BackContent></wp:BackContent>
     </wp:Tile>
</wp:Notification>

Для более подробной информации о тост-уведомлениях читайте http://msdn.microsoft.com/en-us/library/ff402558(v=vs.92).aspx.

WP7 Push-уведомления с помощью Ruby.
Следующий код демонстрирует, как отправить Push-уведомления с помощью Ruby:

require ‘net/http’
require ‘uri’

NONRAWTYPES=[:toast, :tile]
BASEBATCH={:tile=>1, :toast=>2, :raw=>3}
BATCHADDS={:delay450=>10, :delay900=>20}

def send_notification(params)
    msg=build_message(params)
    delay=calculate_delay(params[:type],params[:delay])

    uri=URI.parse(params[:uri])
    http=Net::HTTP.new(uri.host, uri.port)
    headers={
        ‘Content-Type’=>’text/html’,
        ‘Content-Length’=>msg.length.to_s,
        ‘X-NotificationClass’=>delay.to_s
    }
    if NONRAWTYPES.include?(params[:type])
        headers[‘X-WindowsPhone-Target’]= (params[:type]==:toast) ? ‘toast’ : ‘token’
    end

    http.post(uri.path, msg, headers)
end

private
def calculate_delay(type, delay)
    if type.nil?
        type = :raw     end
    delay.nil? ? BASEBATCH[type] : BASEBATCH[type]+BATCHADDS[delay]
end

def build_message(params)
    if NONRAWTYPES.include?(params[:type])
        msg_body=»<?xml version=’1.0′ encoding=’utf-8′?><wp:Notification xmlns:wp=’WPNotification’><wp:#{params[:type].capitalize}>»
        case params[:type]
        when :toast
            msg_body << «<wp:Text1>#{params[:title]}</wp:Text1>»
            msg_body << «<wp:Text2>#{params[:message]}</wp:Text2>»
            msg_body << «<wp:Param>#{params[:param]}</wp:Param>»
        when :tile
            msg_body << «<wp:BackgroundImage>#{params[:image]}</wp:BackgroundImage>»
            msg_body << «<wp:Count>#{params[:count].to_s}</wp:Count>»
            msg_body << «<wp:Title>#{params[:title]}</wp:Title>»
            msg_body << «<wp:BackBackgroundImage>#{params[:back_image]}</wp:BackBackgroundImage>»
            msg_body << «<wp:BackTitle>#{params[:back_title]}</wp:BackTitle>»
            msg_body << «<wp:BackContent>#{params[:back_content]}</wp:BackContent>»
        end
        msg_body << «</wp:#{params[:type].capitalize}></wp:Notification>»
    else
        msg_body=params[:message]
    end
    return msg_body
end

Чтобы использовать это, вам нужно передать следующие ключи и значения для send_notification:

  • :uri=> URI уведолений устройства/приложения. Генерируетмя приложением на WP7 устройстве.
  • :type=> Тип уведомления.Это действительно только для :tile и :toast; предполагается, что это:raw если вы не указали :type.
  • :title=> Заголовок уведомления. Это действительно для обоих типов уведомлений —  :tile и :toast.
  • :message=> Сообщение для типов уведомлений :toast или :raw.
  • :count=> Задает значение для числового счётчика на плитках . Действительно только для уведомлений типа :tile.
  • :param=> Параметр, передаваемый WP7 приложению, когда пользователь касается (нажимает) тост уведомления. Действительно только для уведомлений типа :toast.
  • :image=> url фонового изображения для плитки. Действительно только для уведомлений типа :tile.
  • :back_image=> url изображения для оборотной стороны плитки. Действительно только для уведомлений типа :tile.
  • :back_content=> Текст содержания сообщения для обратной стороны плитки. Действительно только для уведомлений типа :tile.
  • :back_title=> Текст заголовка для обратной стороны плитки. Действительно только для уведомлений типа :tile.
  • :delay=> Пакетная задержка для отправки сообщения из MPNS. Может быть :delay450 или :delay900; если :delay не указан, то интервал задержки отсутствует — немедленное уведомление.

Как это испытать
Я проверил это с помощью примеров приложений с уведомлениями из Windows Phone 7 SDK. Вы можете скачать их на странице http://msdn.microsoft.com/en-us/library/ff431744(v=VS.92).aspx#BKMK_PushAndTiles. Для этих примеров требуется Visual Studio 2010, установленная на Windows машине, но они нормально функционировать из эмулятора; устройство WP7 не требуется. Обратите внимание, что ни один из примеров не отправляет свой URI, но вместо этого он отображается, чтобы вы могли ввести его вручную в своем сервисе уведомлений.
Вот шаги, которые нужно выполнить:
1. Запустите WP7 приложение в эмуляторе и скопируйте URI, сгенерированное приложением.
2. Вызовите send_notification с параметрами, соответствующими для нужного типа уведомления. Например для тост-уведомления я использовал :uri=>“url из приложения”, :type=>:toast, :title=>‘foo’, :message=>‘bar’.
3. Обратите внимание на то, что это привело к воздействию на приложение.

В реальном сценарии вместо того, чтобы отправлять вручную, вы бы использовали для хранения значения веб-сервис. Например, хранили бы URI вместе с другими данными пользователя. Тогда можно, например, запросить подмножество пользователей с одним и тем же почтовым индексом для приложения, дающего информацию о погоде, и отправить уведомление всем им.

Эта статья является переводом оригинальной статьи «Sending Windows Phone 7 Notifications from Ruby», расположенной по адресу: http://blogs.msdn.com/b/silverlining/archive/2011/10/12/sending-windows-phone-7-notifications-from-ruby.aspx?wa=wsignin1.0
Автор: Larry Franks
Перевод: Сергей Урусов

Создаём сервис уведомлений для Windows Phone 7 на языке Ruby: 3 комментария

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *