WebSocketを使用したmashup を作るにあたり、以前から知られているCometについては、
サーバからpushする技術ぐらいにしか理解していなかった為、少し調べてみました。
■ 目的
従来のWebページはクライアントからリクエストがあった時のみ、サーバからレスポンスが返ってくる。
その際、クライアントからはHTTPコネクションを生成し、サーバからレスポンスが返るとコネクションはクローズする。
上記の手法でも通常は問題は無いが、リアルタイム性を求められるアプリケーション等の場合は不都合である。
(例えば、チャットや株価情報など)
その場合、AJAX等で非同期にサーバへHTTP通信をする手法が考えられるが、
サーバ/クライアントに負荷が掛かったり、他ユーザからの更新情報をリアルタイムに受け取る事は難しい。
こうした経緯からCometと呼ばれる概念(Cometは複数の技術の総称)が生まれた。
なお、Comet, AJAXの名称は共に洗剤から由来している。
■ トランスポート処理手法
ポーリング
サイトあるいはアプリケーションから、更新有無を問い合わせるリクエストを定期的に送信するという非常に単純な仕組み。
デメリットとして等間隔(例えば、5秒など)でリクエストを送信するが、サーバ側で高負荷になっていた場合も常にリクエストを出し続けてしまう事が起こり得る。この場合、サーバ側に未処理リクエストが溜まり続けてしまう。
ロングポーリング
クライアントからリクエストをサーバに送信し、すぐに返却可能なデータがある場合はすぐにレスポンスを返すが、まだ返却可能なレスポンスデータが存在しない場合は、レスポンスを返さずに未応答リクエストとしてサーバ側で保持する。
データの用意が出来た段階で、保持していた接続を見つけてレスポンスを返す。
Meebo で使用されて、有名となった。
ロングポーリングの発展系として、スマートポーリングと呼ばれる手法がある。
スマートポーリングはレスポンスデータが返って来なかった場合にリクエスト頻度を下げるポーリング手法である。
例えば、空レスポンスであったら、次回のリクエスト間隔は1.5倍にするなど。
永久フレーム
ロングポーリングは永久フレームから生まれた手法である。
永久フレームとは、非表示のインラインフレーム(iframe)を開き、
チャンク形式エンコーディングを利用して送信する。
この方式は非常に大きなドキュメントを段階的にロードする為に考案された。
但し、IEでは永久フレームを使用した場合、チャンクを受け取る度に「カチッ」という効果音がなってしまう為、
使用に耐えないものであった。
そこで登場したのが、GoogleがGoogle Talk考案したhtmlfileというActiveXオブジェクトを用いる手法である。
この手法により、IE問題はクリアされ永久フレームは有効な手法として広まった。
XHRストリーミング
サーバと通信をする為の最も良い方法はXMLHttpRequestを使用する事である。
通常、ポーリングやロングポーリングのデータ転送で使用されている。
XHRストリーミングでは、XHR通信を行った後にreadystateをチェックし続け、
接続が切れる前に同一コネクションを使用して会話をする。
現状、最善の手法であるが、いくつかデメリットが存在する。
通常Webサーバはリクエストを受けるとすぐにレスポンスを返すように最適化されているが、
ストリーミングでは接続を保持し続ける必要がある為、注意が必要である。
また、クライアント側においてははXHRストリーミングがパフォーマンス上の問題を引き起こすケースがある。
ストリーミングのレスポンスがあまりに長く続くと、ブラウザのメモリ消費が過大となり、クラッシュしてしまう。
解決方法としては、一定数のレスポンス後に一旦レスポンスを終了し、新たにリクエストを生成すれば良い。
なお、IEではXHRストリーミングを正式サポートしていないので注意が必要である。
■ 今後の動向
前述までのCometを使用したとしても、大量コネクション保持やサポート問題等の為、完全なソリューションではない。
そこで、HTML5からforkしたWebSocketに期待が集まっている。
現在策定中のWebSocketはCometのデメリットを補いつつ、リアルタイムアプリケーションを容易に構築出来る可能性を秘めている。
調査にあたり、続・ハイパフォーマンスWebサイト ―ウェブ高速化のベストプラクティス を参照させてもらいました。