見習いプログラミング日記

Java EE を中心に色々なことを考えてみます。目指せ本物のプログラマ。

AeroGear SimplePushServer でプッシュ通知

日本Javaユーザグループ主催のJavaOne報告会2013で、プッシュ通知についてLTの機会を頂きましたが、SimplePushが何者なのかを補足します。

SimplePushとは

Mozillaは全てのWebブラウザで動作する一貫したAPIセットとしてWebAPIという考え方を提唱しています。その中に含まれるAPIの一つがSimplePushです。Push通知サーバの参照実装はGo言語により実装されており、GitHubでコードが公開されています。このプッシュ通知機能の特徴は、あくまで『サーバの何らかの状態変化をクライアントに通知する』ことが目的であり、更新データ自体は送りません。通知時に付加できる情報は『バージョンID』のみです。この一意なバージョンIDによって、例えば通知に応じた最新メッセージをサーバから取得するといった実装が可能となります。

AeroGear SimplePush

SimplePushをサーバをJavaで実装し、クライアントをJavaScriptライブラリとして実装したのがAeroGear SimplePushです。JBossコミュニティの中の1つのプロジェクトとして生まれ、AeroGear自体は元々モバイルアプリ開発においてクロスプラットフォーム性を確保するために作られているようですが、そのサブセットのSimplePushサーバは独立して使用することができ、実際デモアプリにおいてもクライアントはモバイルではなくデスクトップブラウザを使用しています。オープンソースで、ライセンスはApache License, Version 2.0です。

SimplePushのプロトコル

SimplePushの登録や通知の流れはMozillaのページから確認できます。そのなかでも重要な登録と通知のフローについて補足します。

プッシュ通知登録のフロー

f:id:n_agetsuma:20131020143954p:plain

  1. (UserAgent→PushServer) UserAgent(主にブラウザ)をPushServerに登録します。UserAgentとPushServerはWebSocket上でjsonを送り合って通信します。
  2. (PushServer→UserAgent) 登録が成功すると、PushServerはUserAgentにEndpointURLと呼ばれるURLを払い出します。このURLに対してHTTP PUTを送信すると通知が送られます。
  3. (UserAgent→App Server) 仕様の範囲にはありませんが、通常Push通知はAPサーバから行われるので、何らかの手段によってPushServerから払い出されたEndpointURLをAPサーバに通知する必要があります。デモではRESTエンドポイントをAPサーバ側に作って、PushServerへの正常登録完了のJavaScriptコールバック関数よりEndPointURLを通知しています。
プッシュ通知のフロー

f:id:n_agetsuma:20131020144643p:plain

  1. (App Server→PushServer) EndpointURLに対してHTTP PUTするとプッシュ通知が依頼できます。この時に送れる情報はversion=Nで示す、バージョンIDのみです。データ自体を送ることはできません。あくまでSimplePushは『通知』することが目的で、アプリケーションのデータを送ることはスコープ外です。Java EE サーバであれば、JAX-RS2.0からClientAPIが追加されているのでHTTP PUTを送信する際に便利です。
  2. (PushServer→UserAgent) messageTypeに"notification"を設定したjsonを送って通知を行います。APサーバから依頼を受けたときに受け取ったバージョンIDもjsonに含まれます。
  3. (UserAgent→PushServer) messageTypeに"ack"を設定したjsonを送って、通知を受け取ったことをPushServerに知らせます。
  4. (UserAgent→App Server) プッシュ通知受信後の流れについてはプロトコルの範囲外ですが、プッシュ通知のコールバック処理として、Appサーバから情報を取得することが多いと思います。

これを使って何ができそうか

企業システムで何ができそうか色々と考えてみました。あくまで想像してみただけなので、実現可能性は考えられていません。

  • モバイルを含む社内端末に一斉通知する。飛行機の最新の遅延情報とその理由のアップデート等、お客さまによく聞かれるリアルタイム情報をPush通知で送られると便利かもしれません。今まではGoogle Cloud Messasing等のインターネット上のサービスと連携が必要なことから、企業内システムにおいてプッシュ通知はセキュリティ管理上厳しい面もありましたが、AeroGear SimplePushであれば社内ネットワークに構築可能です。
  • 現在、数秒に1回ポーリングして最新情報を更新しているシステムにおけるトラフィックの軽減。少なくともAppサーバと通知サーバが分離できるので、負荷の分散はできそうです。
  • 抽象的な表現ですが、急いで情報を伝えたくて、かつアクションを起こして欲しいもの。アクションの必要がないなら、無理にPush通知する必要はないと思います。

調査契機となったJavaOne2013のセッション

Notify Your Mobile Clients by Integrating Push Networks and Java EE 7 [CON5073]
当日のスライドはJavaOne2013のページからダウンロードできます。

デモコード

作成したデモコードはGitHubで公開しています。是非みなさんで遊んでみてください。

https://github.com/n-agetsu/PushNotificationDemo