Bayeux プロトコルの仕様について
はじめに
Pub/Sub Messaging
を勉強するにあたって、Bayeuxプロトコルでの実装があるとのことだったので、Bayeux プロトコル日本語訳を読んでメモを取ってみました。
枯れた仕様(検索であまり当たらない)な気もしていますが、せっかく読んだので公開しようかと思います。
Bayeuxプロトコル概要
- Webサーバー間でメッセージを非同期にやりとりするためのプロトコル
- メッセージは名前付きチャネルを経て、ルーティング及び送達される
- サーバ <=> クライアント
- ajaxを利用したサーバープッシュ型のテクニック=「comet」
- 準拠要求
- 全てのMUST及びREQUIREDを満たし、かつ、全てのSHOULDを満たすものは、"完全準拠(unconditionally compliant)"
- 1つでもSHOULDを満たさないモノは「条件付き準拠(conditionally compliant)」
- ワード定義
HTTPプロトコル
- リクエスト/レスポンス型のプロトコル
- クライアント -> サーバー
- サーバー -> クライアント
- ステータスライン
- プロトコルバージョン
- 基本的にサーバー -> クライアントへはクライアントの要求なしに通信を走らせない
- Bayeuxでは、双方向の非同期通信を走らせるためサーバー・クライアント間で複数コネクションをサポートしている
- 通常アクセス用コネクション
- ロングポーリング用コネクション
- (MUST NOT)Bayeuxプロトコルも、サーバーが全てのアプリケーションに対して処理を行うために3本以上のコネクションをはらない
様々なルール
- (MUST) クライアントはブラウザのシングルオンポリシーを尊守しなければならない
- シングルオンポリシー = JSからはそれがダウンロードされたサーバー以外への接続は許可されない
- 2コネクション処理
- (MUST) Bayeux実装はHTTPのパイプライン処理を制御し、リクエスト順を保持して実行しなければならない
- ポーリング
- レスポンスを受け取った後、メッセージをサーバーに対して送信する
- 次のメッセージを受け取れるようにする処理
- Bayeux実装は、ロングポーリングと呼ばれる形式のポーリングをサポートする必要がある
- レスポンスを受け取った後、メッセージをサーバーに対して送信する
- 接続ネゴシエーション
- 接続の際、コネクション/認証/を交換して合意するネゴシエーションが行われる
- その際、ハンドシェークメッセージがかわされる
- クライアントの状態
-------------++------------+-------------+----------- +------------ State/Event || handshake | Timeout | Successful | Disconnect || request | | connect | request || sent | | response | sent -------------++------------+-------------+----------- +------------ UNCONNECTED || CONNECTING | UNCONNECTED | | CONNECTING || | UNCONNECTED | CONNECTED | UNCONNECTED CONNECTED || | UNCONNECTED | | UNCONNECTED -------------++------------+-------------+------------+------------
// BNF記法 alpha = lowalpha | upalpha lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" alphanum = alpha | digit mark = "-" | "_" | "!" | "~" | "(" | ")" | "$" | "@" string = *( alphanum | mark | " " | "/" | "*" | "." ) token = ( alphanum | mark ) *( alphanum | mark ) integer = digit *( digit )
- チャネル
channel_name = "/" channel_segments channel_segments = channel_segment *( "/" channel_segment ) channel_segment = token
メッセージフィールド定義
名 | 説明 |
---|---|
channel | - メッセージの配送先および配送元を示す - リクエスト: 配送先 - レスポンス: 配送元 |
supportedConnectionTypes | - /meta/handshake へ送受信の際に利用 - どの転送タイプを用いるか決める - (MUST) long-polling,callback-polling等が存在 |
clientId | - クライアントをユニークに識別するもの - /meta/handshake ,投稿メッセージ以外の全てのメッセージに付与が必須 |
id | 全てのメッセージに付与可能 |
timestamp | - ISO 8601形式(YYYY-MM-DDThh:mm:ss.ss ) - GMTで表記 |
successful | -リクエストの成否 - /meta/* 系のレスポンスに必須 |
error | エラー |
メタメッセージ定義
handshake
クライアントは、/meta/handshake
channelに対してメッセージを送ることで接続ネゴシエーションを開始する
handshake request (MUST field)
field | 説明 |
---|---|
channel | /meta/handshake という値 |
version | クライアントで処理されるバージョン |
supportedConnectionTypes | 接続タイプの文字列 |
handshake response
field | 説明 |
---|---|
channel | /meta/handshake という値 |
version | クライアントで処理されるバージョン |
supportedConnectionTypes | クライアント・サーバー共にサポートする接続タイプ |
clientId | クライアント固有のID |
successful | true/false |
connect
クライアントは、/meta/connection
channelにメッセージを送ることでコネクションを開始する。
connection request
field | 説明 |
---|---|
channel | /meta/connection という値 |
clientId | クライアント固有のID |
connectionType | 接続タイプ |
connection response
field | 説明 |
---|---|
channel | /meta/connection という値 |
successful | true/false |
clientId | クライアント固有のID |
subscribe
チャネルへの登録を行うために、/meta/subscribe
にリクエストを行い、配信登録を行う。
subscribe request
field | 説明 |
---|---|
channel | /meta/subscribe という値 |
clientId | クライアント固有のID |
subscription | 購読するチェネル名/チャネルパターン/配列 |
subscribe response
field | 説明 |
---|---|
channel | /meta/subscribe という値 |
successful | true/false |
clientId | クライアント固有のID |
subscription | 購読するチェネル名/チャネルパターン/配列 |
イベントメッセージ定義
イベントメッセージ投稿
channelに対して、イベントを投稿する処理のこと
publish request
field | 説明 |
---|---|
channel | 投稿するchannel名 |
data | JSONオブジェクトの形をしたメッセージ |
publish response
field | 説明 |
---|---|
channel | 投稿したchannel名 |
successful | true/false |
イベントメッセージ配信
channelからクライアントへイベントを配信する
field | 説明 |
---|---|
channel | 投稿するchannel名 |
data | JSONオブジェクトの形をしたメッセージ |
ポーリング
long-polling
特徴
- 配送すべきメッセージが届くまでコネクションをオープンにし続ける
- 伝送遅延を最小化
- フェールセーフとして、classicalな数秒ごとのポーリング処理を行う
- POSTメッセージのボディで伝送される
- 形式
application/x-www-form-urlencoded
text/json