2010年9月16日木曜日

Android Cloud to Device Message - C2DM - 2

■ C2DMに必要なもの

 ・Mobile Device (デバイス)
   ・Marketアプリがインストールされている
   ・2.2以上のAndroidが走っている
   ・Googleアカウントと紐付いている
   ・C2DMを利用するAndroidアプリをインストールする

 ・Third-Party Application Server (アプリケーションサーバ)
   ・開発者が用意
   ・デバイス上のAndroidアプリに、C2DM Server経由でデータを送る

 ・C2DM Servers (C2DMサーバ)
   ・Third-Party Application Serverからメッセージを取り出し、
    それをデバイスに送る役割を果たすGoogleのサーバ


■ C2DMの認証に必要なもの

 ・Sender ID (Android app用)
   ・アプリの開発者にひもづいたemailアカウント
   ・デバイスにメッセージを送ることを許されたAndroidアプリの
    登録プロセスで利用される
   ・開発者ごとに異なる

 ・Application ID (Android app用)
   ・manifest中のパッケージ名
   ・Androidアプリごとに異なる

 ・Registration ID (Android app / Application Server用)
   ・メッセージを受け取ることを許しているAndroidアプリに対して、
    C2DMサーバから発行されるID
   ・特定のデバイス上の特定のアプリに結びついている
   ・デバイス上のAndroidアプリごとに異なる

 ・Google User Account
   ・ユーザーごとに異なる

 ・Sender Auth Token (Application Server用)
   ・Third-party application server 上に保存された
    ClientLogin Auth トークン
   ・メッセージを送るPOSTリクエストのヘッダに含まれる


■ C2DMへの登録

 1. REGISTER Intent で受信登録
  ・Register Intent
   (com.google.android.c2dm.intent.REGISTER)
   をC2DMサーバに送る
    ・register Intent は、Sender ID と Application ID を含む

 2. Registaration ID の取得
  ・登録成功時にC2DMサーバから発行される REGISTRATION Intent の
   ブロードキャストを受け取って、Registration ID を取得する
  ・Registration IDを更新ため、REGISTRATION Intent が複数回
   呼ばれることに対応する必要がある

 3. Registaration ID の送付
  ・Registration IDをアプリケーション・サーバに送る
  ・Registration IDは、アプリケーションが明示的に自分を登録から
   外した時か、GoogleがアプリのRegistration IDを更新する時まで
   存続する


■ メッセージの送信

 ・アプリケーション・サーバ
  ・一つの特定アプリ(=特定のデバイス上のアプリ)について
   一つのClientLogin tokenを持ち、複数のregistration IDを持つ
  ・それぞれのregistration IDは、特定のアプリについて、
   メッセージング・サービスを利用する特定のデバイスを表現している

 1. アプリケーション・サーバは、GoogleのC2DMサーバにメッセージを送る。

 2. Google側は、デバイスが立ち上がっていない場合には、メッセージを
  キューに入れて蓄えておく。

 3. デバイスがオンラインになったら、Googleは、デバイスにメッセージを送る。

 4. デバイス側では、システムが特定のアプリに対して適当なパーミッション
  設定をし、そのターゲットのアプリだけがメッセージを取得できるように、
  Intent Broadcastを使って、メッセージをブロードキャストする。
  メッセージを受け取るために事前に動いている必要はない。

 5. アプリは、メッセージを処理する。処理が複雑なものであれば、
  wake lockを取得して、バックグラウンドのServiceで処理する。


■ メッセージの受信

 1. システムは、送られたメッセージを受け取り、メッセージのpayloadから、
  生のkey/valueペアを直接に受け取る。

 2. システムは、ターゲットのAndroidアプリに、key/valueペアを、
  com.google.android. c2dm.intent.RECEIVE Intentの
  Extrasに詰めて渡す。

 3. Androidアプリは、RECEIVE Intentから、keyを用いて生のデータを
  取り出し、データを処理する。




■さっそく自分のアプリに組み込むべし

 1. ChromeToPhone を参考にして、My Google Chrome Extension を
  作成

   省略

 2. Chrome Extension から送られたメッセージを処理して、
  C2DMサーバへ送るためのアプリーション・サーバを
  Google App Engine 上につくる(別にGoogle App Engine
  じゃなくて自サバでも Amazon でもよし)

  ●必要な機能
   ・クライアントとコミュニケーションできること。

   ・C2DMサーバにHTTPリクエストを送れること

   ・リクエストを処理し、必要に応じてキューのデータを
    処理できること。例えば、exponential back offが可能である事。

   ・ClientLogin Auth tokenとクライアントのregistration IDを
    保存できること。

  ●メッセージを送る
   https://android.apis.google.com/c2dm/send に、
   POSTリクエスト
を送る


   POSTリクエストのヘッダー設定

    Content-Type : application/x-www-form-urlencoded

    Content-Length : Contentのバイト長

    Authorization : GoogleLogin auth=[AUTH_TOKEN]
      ac2dm サービスに関連するClientLogin Auth トークン


   POSTリクエストの Content に含まれるフィールド

    ・registration_id
      端末上のAndroidアプリから取得したregistration ID。必須。

    ・collapse_key
      デバイスがオフラインの時など、最後のメッセージだけが
      クライアントに送られるように、類似したメッセージの
      グループを折りたたむために使う、任意の文字列。
      端末がオンラインに復帰した時、沢山のメッセージが
      送られないためのもの。必須。
      メッセージの順序の保証はないので、本当に「最後」の
      メッセージではないかもしれないことに注意

    ・data. (optional)
      key/valueペアで表現されたPayloadデータもし、あれば、
      を持ったアプリケーション・データとして、Intentの中に
      含まれることになる。 オプショナル。
      key/valueペアの数に制限はないが、メッセージの全体の
      サイズには、制限がある。

    ・delay_while_idle (optioanl)
      デバイスが動いていないとき、メッセージをすぐには送らない
      ことを示す。サーバは、デバイスがアクティブになるのを待って、
      それぞれのcollapse_key毎に、その値の、最後のメッセージを
      送信する



   レスポンス(200)
    Header
    ・Update-Client-Auth=[Updated Auth Token]
      ・新しい Auth Token が発行された場合、この Field がレスポンスに入る

    Body
    ・id=[ID of sent message]

    ・Error=[error code]
      ・QuotaExceeded
         あまりに多くのメッセージを送っている。少し後に再試行せよ。
 
      ・DeviceQuotaExceeded
         特定のデバイスに、あまりに多くのメッセージを送っている。
         少し後に再試行せよ。

      ・InvalidRegistration
         registration_idが存在しないか、間違っている。
         このデバイスへのメッセージ送信を中止すべき。

      ・NotRegistered
         registration_idは、もはや有効ではない。
         例えば、ユーザがアプリをアンストールしたか、
         notificationを切った場合とか。
         このデバイスへのメッセージ送信を中止せよ。

      ・MessageTooBig
         メッセージのペイロードが大きすぎる。
         制限を確認して、メッセージのサイズを小さくせよ。

      ・MissingCollapseKey
         Collapse keyは、必須である。リクエストに
         Collapse keyを含めよ

   レスポンス(503)
     サーバは、一時的に利用できない。後で、レスポンス中の
     Retry-Afterヘッダを使って、再試行する。
     アプリケーション・サーバは、exponential back off を実装すべきしなければならない。
     問題をおこしたサーバは、ブラックリストに載せられる危険もある。

   レスポンス(401)
     ClientLogin AUTH_TOKEN が、正しくない。


 3. Android アプリを作る

  長くなったので次のエントリで。



 

0 件のコメント:

コメントを投稿