サーバpushざっくりまとめ
DESCRIPTION
ポーリング、Ajax、Comet、Server Sent Events、WebSocket サーバPUSH方式の大雑把な比較TRANSCRIPT
サーバPUSH ざっくりまとめ
2014/8/11 (2013/10に一度お蔵入り)
!
囬り道 康博
目的
•PUSHについて以下のことを確認 •何でWebSocketがいいんだっけ •従来の方式は何がよくないんだっけ •そもそも何があったっけ
概要•各方式をざっくり確認+比較 •ポーリング •Ajax • Comet • Server Sent Events •WebSocket •図は以前書いたWebSocket / WebRTCの技術紹介から
ポーリング (1/4)• クライアント契機でHTMLを取得 • 疑似PUSH
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
ポーリング (1/4)• クライアント契機でHTMLを取得 • 疑似PUSH
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
ポーリング (1/4)• クライアント契機でHTMLを取得 • 疑似PUSH
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
ポーリング (1/4)• クライアント契機でHTMLを取得 • 疑似PUSH
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
画面を更新
ポーリング (1/4)• クライアント契機でHTMLを取得 • 疑似PUSH
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
画面を更新
…
ポーリング (2/4)•初期の疑似PUSH •昔のBBSやチャット •HTTPクライアントがHTTPサーバへ定期的にアクセスして画面を再描画
•リアルタイム性はアクセス間隔に依存
ポーリング (3/4)
•メリット •昔(とても昔)のブラウザでも動く •特殊なことはやっていない
ポーリング (4/4)•デメリット •リアルタイム性が低い •リアルタイム性を上げるために更新頻度を上げるとサーバ負荷上がる
•差分でなくフルのHTMLを毎回取得する •クライアントは定期的にサーバへアクセスする •クライアントはサーバに新しい情報があるかどうか(だけを)知る術がない
Ajax (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
画面を更新
…
• クライアント契機でXML/jsonを取得 • 疑似PUSH
Ajax (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
画面を更新
…
• クライアント契機でXML/jsonを取得 • 疑似PUSH この辺がAjax
Ajax (2/4)•Ajax = Asynchronous JavaScript + XML • XHR(XMLHttpRequest)で実装 • XMLでなくテキストでもいい •なのでJSONが使われることが多い(と思う)
•「ちょっとマシなポーリング」ができる
Ajax (3/4)•メリット •ポーリング方式より通信負荷が低い •サーバから必要なデータだけ持ってくる •画面全体のHTMLを再取得しない
•「全データを予め取得するのが非現実的」で「状況に応じてデータを取得する」用途に向く
•Googleマップとか
Ajax (4/4)•デメリット • PUSHの観点ではポーリングと変わらない •サーバからデータを送るにはクライアントからのアクセスが必要
•というかそもそもPUSHのリアルタイム性を上げるための仕様じゃない
Comet (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• サーバ契機でHTMLやXML/jsonを取得 • サーバからの即応性が改善された擬似PUSH
Comet (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• サーバ契機でHTMLやXML/jsonを取得 • サーバからの即応性が改善された擬似PUSH
Comet (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• サーバ契機でHTMLやXML/jsonを取得 • サーバからの即応性が改善された擬似PUSH データ発生まで
レスポンスを保留
Comet (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• サーバ契機でHTMLやXML/jsonを取得 • サーバからの即応性が改善された擬似PUSH データ発生まで
レスポンスを保留
Comet (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• サーバ契機でHTMLやXML/jsonを取得 • サーバからの即応性が改善された擬似PUSH データ発生まで
レスポンスを保留
画面を更新
Comet (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• サーバ契機でHTMLやXML/jsonを取得 • サーバからの即応性が改善された擬似PUSH データ発生まで
レスポンスを保留
次のPUSH用の リクエストを投げる
画面を更新
Comet (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• サーバ契機でHTMLやXML/jsonを取得 • サーバからの即応性が改善された擬似PUSH データ発生まで
レスポンスを保留
次のPUSH用の リクエストを投げる
画面を更新
Comet (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• サーバ契機でHTMLやXML/jsonを取得 • サーバからの即応性が改善された擬似PUSH データ発生まで
レスポンスを保留
次のPUSH用の リクエストを投げる
画面を更新
Comet (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• サーバ契機でHTMLやXML/jsonを取得 • サーバからの即応性が改善された擬似PUSH データ発生まで
レスポンスを保留
この辺でデータが発生するとラグ
次のPUSH用の リクエストを投げる
画面を更新
Comet (2/4)•ロングポーリング •一般に、サーバは可及的速やかにレスポンスを返す • Cometでは「PUSHしたい時」までレスポンスを返さない
•つまりポーリングよりポーリング間隔が長い •双方向通信 •クライアント to サーバは通常のHTTP •サーバ to クライアントはComet
Comet (2/4)•ロングポーリング •一般に、サーバは可及的速やかにレスポンスを返す • Cometでは「PUSHしたい時」までレスポンスを返さない
•つまりポーリングよりポーリング間隔が長い •双方向通信 •クライアント to サーバは通常のHTTP •サーバ to クライアントはComet
この辺がロング
Comet (3/4)
•メリット •リアルタイム性がポーリング方式より高い
Comet (4/4)•デメリット •仕組み上、ごく短時間に連続でPUSHすることができない •一度PUSHすると、クライアントから次のPUSH用の接続を待たないといけない
•サーバは最大でポーリングの2倍のリソース(曖昧)を消費する •「サーバ to クライアント(Comet)」で1つ •「クライアント to サーバ(HTTP)」で1つ •ポーリング方式より不利というだけで、根本的にはどの方式でも同じ問題がついて回る(C10K問題)
Comet (4/4)•デメリット •仕組み上、ごく短時間に連続でPUSHすることができない •一度PUSHすると、クライアントから次のPUSH用の接続を待たないといけない
•サーバは最大でポーリングの2倍のリソース(曖昧)を消費する •「サーバ to クライアント(Comet)」で1つ •「クライアント to サーバ(HTTP)」で1つ •ポーリング方式より不利というだけで、根本的にはどの方式でも同じ問題がついて回る(C10K問題)
あくまでも 最大だよ
Server Sent Events (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• Cometを洗練させたWeb標準(W3C CR) • 本格的なPUSH
Server Sent Events (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• Cometを洗練させたWeb標準(W3C CR) • 本格的なPUSH
Server Sent Events (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• Cometを洗練させたWeb標準(W3C CR) • 本格的なPUSH データ発生のたびに
送信する
Server Sent Events (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• Cometを洗練させたWeb標準(W3C CR) • 本格的なPUSH
分割(chunked)データ扱い
データ発生のたびに送信する
Server Sent Events (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• Cometを洗練させたWeb標準(W3C CR) • 本格的なPUSH
分割(chunked)データ扱い
データ発生のたびに送信する
画面を更新
Server Sent Events (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• Cometを洗練させたWeb標準(W3C CR) • 本格的なPUSH
分割(chunked)データ扱い
クローズしていないのでさらに送れる
データ発生のたびに送信する
画面を更新
Server Sent Events (1/4)
クライアント サーバ
HTTPリクエスト
HTTPレスポンス
• Cometを洗練させたWeb標準(W3C CR) • 本格的なPUSH
分割(chunked)データ扱い
クローズしていないのでさらに送れる
データ発生のたびに送信する
画面を更新
•Server Sent Events (SSE) •新しいロングポーリング方式 • Chunked Transfer Coding • HTTPサーバがレスポンスを「分割(chunked)データ」として宣言する
•サーバはPUSHが必要になる度にクライアントへデータを送る
•データ = 「HTTPレスポンスの一部」をPUSHしても通信が維持される
Server Sent Events (2/4)
•メリット •リアルタイム性がポーリングより高い • Cometに比べて、「一度サーバPUSHを受けた後にクライアントが再接続」する手間とラグがない
•サーバ側の実装が従来の延長で可能 •WebSocketのような新規格への対応が不要
Server Sent Events (3/4)
•デメリット •HTTPクライアント(ブラウザ等)がServer Sent Eventsに対応していないといけない
•古いブラウザだと動かない •具体的にはIE(11でも×)とかAndroid標準ブラウザ(4.4未満は×)
• Cometと同じく、サーバは最大でポーリング方式の2倍のリソースを消費する
Server Sent Events (4/4)
(補足) Streaming API •Twitterのアレ • Ajax + Chunked Transfer Coding •機能上の特徴はServer Sent Eventsと同等 •クライアント側の処理がServer Sent Eventsより複雑 • Server Sent Eventsの仕様ができるより前に、同等のことをHTTP 1.1 + Ajaxで実現したもの
•独自仕様の「Server Sent Eventsっぽい何か」と捉えても良い •と解釈しているんだけど、情報がいまいち出てこなくて正しいかわからない
WebSocket (1/5)
サーバ
• HTTPの縛りを外して作られたWeb標準 (RFC 6455 / W3C CR) • 本格的なPUSH
WebSocket
メッセージ
WebSocket (1/5)
サーバ
• HTTPの縛りを外して作られたWeb標準 (RFC 6455 / W3C CR) • 本格的なPUSH
WebSocket
メッセージ
WebSocket (1/5)
サーバ
• HTTPの縛りを外して作られたWeb標準 (RFC 6455 / W3C CR) • 本格的なPUSH
WebSocket
メッセージ
データ発生のたびに送信する
WebSocket (1/5)
サーバ
• HTTPの縛りを外して作られたWeb標準 (RFC 6455 / W3C CR) • 本格的なPUSH
画面を更新
WebSocket
メッセージ
データ発生のたびに送信する
WebSocket (1/5)
サーバ
• HTTPの縛りを外して作られたWeb標準 (RFC 6455 / W3C CR) • 本格的なPUSH
画面を更新
WebSocket
メッセージ
データ発生のたびに送信する
WebSocket
メッセージ
クライアント
WebSocket (2/5)
サーバ
WebSocket
メッセージ
クライアント
送信完了前に別の送信を開始しても可
WebSocket (2/5)
サーバ
WebSocket
メッセージ
クロスしても可
クライアント
送信完了前に別の送信を開始しても可
WebSocket (2/5)
サーバ
WebSocket (3/5)•効率的な双方向通信のために作られた、HTTPと別の規格 •WebSocketプロトコルは通信仕様、IETF管轄 • http://tools.ietf.org/html/rfc6455 •単に使う分にはそれほど意識しなくてもいい •知っているに越したことはないが
•WebSocket APIはWebSocketをJavaScriptから使うためのAPI、W3C管轄
• http://www.w3.org/TR/websockets/
WebSocket (4/5)•メリット •HTTPプロトコルと比較してヘッダが軽量=通信負荷が低い
•リアルタイム性が高い •サーバ to クライアントとクライアント to サーバで同じ経路
•サーバにやさしい、リソース的な意味で •標準化策定済み
WebSocket (5/5)•デメリット •サーバ、クライアントともWebSocket規格への準拠が必要 •古いWebサーバやブラウザは非対応 • IE10未満とか、Android 4.4未満の標準ブラウザ
•既存の通信機器を通過できない可能性がある •例えば80番port = HTTPの前提で監査しているルータ等にWebSocket通信を流すと、異常データ扱いで弾かれることがある
• httpsだと中身が見えないので比較的通りやすい
PUSH方式の比較リアルタイム性 サーバの
負荷 (低)Webサーバの
対応ブラウザの 対応
ポーリング /Ajax △~× ×~△ ○ ○
Comet ○ ○ ○ ○Server Sent Events ○ ○ ○ △
WebSocket ○ ○ △ △
まとめ•WebSocket • Server Sent Events • Comet • Ajax •ポーリング
まとめ•WebSocket • Server Sent Events • Comet • Ajax •ポーリング
越えられない壁
まとめ•WebSocket • Server Sent Events • Comet • Ajax •ポーリング
おすすめ
非おすすめ越えられない壁
蛇足•HTTP2がないね •そうすね、近いうちにRFC出そうですね •あっちのPUSHは「好きな時にサーバPUSH」じゃなく「Webページに必要そうなデータをサーバ契機で予め送信」のPUSH
• PUSH方式選択のポイントは(サポート対象の)ブラウザ •古いブラウザのサポートがmustな場合、新しい方式は辛いよ(今後も含めて)
•今のWebサーバやブラウザは大抵WebSocketに対応済み •でも通信経路的に使えないケースもあるから注意だよ •悩んだらとりあえずSocket.IOで安定