2013年10月24日木曜日

APNs(Apple Push Notificatoin Service)を理解する


◆ 目的
Apple社のネットワークを利用した通知サービス、
APNS(Apple Push Notificatoin Service)の動きを理解する。

APNsとは、iPhoneなどのデバイスに
サードパーティ製アプリケーションのサーバからの通知を
Apple製の端末に転送するサービスである。


iPhoneやiPadでYahoo!メールの着信があると新着通知が飛んでくる。
誰がいつ通知を飛ばしてくるのだろうか。
iOSでプッシュメールが使えるYahoo!メールを題材に、
着信を報せるプッシュ対応の実装を確認できる部分確認しつつ、
また見えない部分は想定して動作を把握してみたい。



◆ 登場ノード
・クライアント
  iPhoneなどのデバイスを所持

・メッセジングサービス提供サーバ
  mta(smtp, submission), imapを提供
  また、ユーザ情報とそのユーザが通知機能を
  有効にしているかどうかをデータベースで管理

・APNs
  Apple側の新着通知サービス提供サーバ

・Feedback Service
  Apple側の無効デバイスを管理、提供するサーバ



◆ 動作
1. クライアントのデバイスをメッセジングサービス提供サーバに登録
  クライアントがimapで接続し認証を通し(login)、
  その後、capabilityプロトコルを発行する。
  capabilityをlogin後に実行するのは、
  ユーザが通知サービスを利用しているかどうか分からないからである。

  imapサーバが認証されたユーザ情報をシステム内部のデータベースで参照し、
  ユーザが通知機能を利用するよう設定しているかどうかを確認する。

  ②の応答がYESなら、imapサーバがcapabilityの応答として、
  XAPPLEPUSHSERVICEコマンドが使えることをクライアントへ示す。
  XAPPLEPUSHSERVICEとはApple Push Notificatonを行うためのimap拡張コマンドである。

  クライアントはXAPPLEPUSHSERVICE応答があった場合、
  その返答としてデバイス情報をimapサーバ側へ送る。

  imapサーバ側はその情報をユーザを管理しているデータベースに記録する。
  当然ここはimapのプロトコルではなく、独自の拡張機能の処理による。

  データベースを正常に更新できればimapサーバ側はXAPPLEPUSHSERVICEコマンドで
  クライアントへ登録完了応答を返す。


2. メッセジングサービス提供サーバが新規メールを受信
  smtpなりでメッセジングサービス提供サーバのmtaサーバが
  メッセージを受信し対象ユーザのメールボックスへ格納する。


3. メッセジングサービス提供サーバがAPNsに新着通知パケットを送信
  メールを受け取るとユーザのデバイス情報をAPNsへ新着通知パケットとして送信する。
  利用ポートは2195/tcpである。

  APNs通知パケットの詳細はLocal and Push Notificaton programming Guideを参照のこと。
  両者間の通信はSSL/TLSで暗号化されている。
  ということはApple側と通信用の証明書が必要だということである。


4. クライアントが新着通知を受信 
  クライアントが定期的にAPNsへ新着の有無を確認する。

  APNsが接続してきたデバイスの新着を確認できた場合、
  APNsがクライアントの端末へ着通を知らせる。

  着信時にメッセージの概要が表示されることがある。
  新着通知パケットにそのようなペイロードはない。
  ②の後にimapで新着メッセージを再取得しにいっていた。

  ちなみに、iOSの標準メーラが実際に新着メールを取得するトリガは、
  APNsサーバから受信するNotificationだけではないようである。

  IMAPクライアントがNOOP、またはSEARCHのプロトコルを発行し、
  その応答として、タグなしのEXISTSとRECENTが
  返ってきた場合にもトリガになるようである。

  (NOOPとその応答例)
  5 NOOP
  * 3 EXISTS
  * 4 RECENT
  5 OK

  (SEARCHとその応答例)
  5 UID SEARCH 1:* DELETED
  * SEARCH
  * 300 EXISTS
  * 5 RECENT
  5 OK UID SEARCH completed

  EXISTS応答はそのメールボックスでのメッセージの数を報告する。 
  クライアントからの特定コマンドの応答以外にも、
  新規メールを受信などして、メールボックスのサイズが変わるときにも発生する。
  突然このようなタグなし応答が返ってくることがある。
  * 301 EXISTS

  RECENT 応答はRecentフラグが設定されたメッセージの数を報告する。
  こちらもまた、メールボックスのサイズが変わったときには発生する。

  ただしこの応答はサービス提供事業者ごとに相違があった。
  例えば、Dovecotを使ったimapサーバでは、
  delay-newmailオプションなどを操作することで
  動きを変えられるようである。


さて、APNsにて新着通知が端末に送信できない状態が続くとどうなるのであろうか。
  その場合、APNsにて無効デバイスとして登録される。
  その処理が次の5.である。


5. deviceの無効化
  APNsにて新着通知が端末に送信できない状態が続くと、
  Apple側のFeedback Serviceに無効デバイスとして登録される。

  無効デバイスを管理、提供するサービスがFeedback Serviceである。

  メッセージングサービス提供サーバ側で定期的に無効デバイスの有無を
  Feedback Serviceへチェックしに行き、デバイスリストを取得する。利用ポートは2196/tcpである。

  リストの取得が確認されたのち、Feedback Serviceはそのリストを削除する。

  メッセージングサービスを提供する側では、
  ユーザ情報管理データベースから、デバイス情報を削除する。

Feedback ServiceはAPNsとは独立している。
そのため、こちらに無効デバイスとして登録されたとしても、
その後新着通知を受けた場合は着信を受け取ることは可能である。
メッセージングサービスを提供する側のリソース削減の効果が大きい。


(参考)
Appleが管理するAPNsの障害情報は以下で確認できる。
https://developer.apple.com/system-status/