Cometクライアントってコネクション管理どうなってんの
はてなの人気エントリをぺぺーと流し読みしていたら、去年はAJAXとCometがWebを変えた、というようなくだりが目に入った。Comet?ええ、恥ずかしながら初耳です。
と、いうわけでヒマな会議中に情報収集。
要は、サーバからのコンテンツPUSHを実現する手法論を指しているようだ。
たとえば、クライアントからのリクエスト(ポーリング)に対して、レスポンスを保留しちゃおう、ということらしい。チャットとかでサーバ側のコンテンツに変更があったらレスポンス返す、という感じで、その間HTTPコネクションは張りっぱなし。このポーリング方法はlong-pollともいうらしい。prototype.js でもひょろっと実装できるみたいだ。なるほどね。原理としては、ここの絵がわかりやすかった。
で、ここでふと疑問。long-poll なんて、どんなクライアント環境でも現実的に機能できるものなのかしら。タイムアウトにならないのかな。
タイムアウトについて調べてみると、RFC2616やら、その周辺解説やらキーワード辞書やらに当たる。
ほとんどのサーバでは、一定時間接続がないとその接続を切断するようなタイムアウト値を持っています。
(※) 例えば、Apache の場合、あらゆる初期値は “httpd.conf” という設定ファイルに記述されますが、そのうち「接続を確立してから最初のリクエストを発行するまでの時間」は Timeout、また「パイプラインを利用して、既に確立されたコネクションから次のリクエストを受け付けるまでの時間」は KeepAliveTimeout にて設定される値になります。
うーん、これはサーバ側実装についての話が殆どだな。RFCを見るに、Connection: Keep-Alive でリクエストした際、レスポンスに Keep-Alive ヘッダとして、タイムアウトまでの待ち時間や受付可能最大リクエスト数が返される、という感じらしい。
でも、このKeep-AliveってTCPレベルの話だよな.. TCPセッションをどんだけ効率的に再利用するか、という話であって、僕が知りたいのはブラウザの振る舞いなんだけど..
たとえば、ブラウザから(javascriptとかで) long-poll を発行したとき、ブラウザはずっと応答を待ち続けるんだろうか。勝手に再送したりしないんだろうか。このあたりがわかってないと、クライアントが応答待ちで固まったり(非同期に使うから、それは考えなくても良いのかな)、サーバ側に未応答のセッションが堆積したりという事態が発生すると思うんだけど。
で、ちょっと調べてみたが、なかなかブラウザ側の仕様についての一次情報は少ない。が、この辺やこの辺の議論、MSの技術情報を読む感じだと、ブラウザは30秒または5分というタイムアウト値(と見なし.. 再リクエストしたり、レスポンスを無視したりするのかな..)を持っていそうな気配だ。
「リクエストの送信を完了してから30秒以内に
ヘッダーを含む1バイトもレスポンスが無い場合は
リトライとして再度リクエストを送信する」仕様のようです。
Internet Explorer では、仕様により、サーバーからデータが返されるまでのタイムアウト時間が設定されています。タイムアウトまでの時間は、バージョン 4.0 および 4.01 の場合は 5 分、バージョン 5.x および 6 の場合は 60 分です。これにより、サーバーに問題がある場合に、サーバーからデータが返されるまで Internet Explorer が無期限に待ち続けることはありません。
30秒でヘッダを含めてまったく応答が無いと再リクエストする、というのは、本当なら危なっかしい仕様だ。long-poll が勝手に再発行されてしまうのではないか。
などと、見てるだけではいろいろ分からないことも多い。ちょっと手を動かしてみて、検証してみないとダメかな。
ちなみにサーバ側でレスポンスを保留(suspend)する部分は、HTTP処理のカスタマイズになるので、実装が厄介そうだ。Jetty6 だと、ここの実装をかなり簡便にしてくれるらしい。使ったこと無いけど、これを機会に試してみようかな。
最近のコメント