水曜日, 13 9 月 2006

Cometを実装してみる? この記事(Cometを実装してみる?)を「はてなブックマーク」に追加 この記事をクリップ! この記事(Cometを実装してみる?)を「del.icio.us」に追加

« SCIM + Anthy | Main | YouTube動画のタイムライン画像を作る »
先日、Lingrというサイトを見てちょっと感動してしまいました。
上記のサイトで何が出来るのかというといわゆるチャットなんですが
Cometという技術を使っていてブラウザとサーバ間の通信が非同期で行われているそうです。
試してみると確かに自分以外の人の発言がリアルタイムに表示されてサクサク気持ちいいです。
確認のためブラウザを2つ立ち上げて片方で発言すると即座にもう片方に表示されます、素晴らしい!

ここで使われているCometという技術は従来ブツ切りであったブラウザとWebサーバ間の接続を
維持した状態でデータのやり取りを行うということらしいです。(詳しくは知らない…)
そのためブラウザからのプル型だけでなく任意のタイミングでサーバからデータを送信できる
プッシュ型での通信も行えるため他の書き込みも即座に表示されていたわけです。

このCometとても気になって色々調べては見ましたが具体的な実装方法が見つかりませんでした。
もしかしたら海外のサイトをくまなく探したらあるのかも知れません…。
サーバと接続を維持したまま…うーんどうするんだろう分からない、HTTPじゃ無理じゃないの?
でLingrを眺めていてどういうデータが流れているのかtcpdumpで見ていると何となく分かった気が。
どうやらAjaxでWebサーバに接続した後、そのまま何もレスポンスを返さず待機しているようです。
そして何らかのイベント(発言など)が起こった時にサーバ側で待機していたプロセスを再開し
ブラウザにレスポンスを返してそれが表示されたらまた裏でWebサーバに接続して待機する…、
それの繰り返しによりまるでプッシュ型の通信を行っているかのように見えているみたいです。
推測なので実はちょっと違うのかも知れませんが。

それなら自分でもCometの実装ができるかもと思い作ったら出来ました。Lingrと同じでチャットですけど…。
今回はサーバ側Servletを使いましたが他の言語でも出来ると思います、きっと。
動作のフローはまずブラウザからAjaxでWebサーバに接続を行います。
接続を行ったらServletの中でwait()をかけます、タイムアウトは30秒にしました。
そして入室や発言の動作でリクエストを送るとサーバ側では入室/発言のメッセージをServletContextに保存し
notifyAll()でwait状態になっているスレッドを再開させ各スレッドがServletContextから
保存されているメッセージを読み出してそれをクライアントに返すというだけの仕組みです。

ちゃんと検証していないのでブラウザによっては挙動が変かも知れません。
場合によっては死んだコネクションが残りブラウザが不安定になるかもです。
IEとFirefoxなど違う種類のブラウザでこのページを同時に開き
片方で発言すればもう片方のブラウザでもすぐに表示が行われるのが確認できると思います。


Connecting...

便利!これは夢がひろがりんぐな技術ですよ!と言いたいんですが
少なくとクライアントの数はサーバと持続した接続が必要なわけで
サーバ側のリソースをどうするか考えなくちゃダメですよね。
従来のWebアプリケーションを作る場合とは違う考え方が必要そうです。

Technorati Tags:

Posted by tsujitako at 11:22 午後 in Ajax/