2008年01月04日
AjaxとCometを用いたチャットサイトを作った
この正月ひたすらプログラミングしてCometを使用したチャットサイトを作った。
http://anime-freaks.net/chat/
Cometとはプル型の通信しかできないHTTPの使い方をちょっとひねって、サーバ側からプッシュ型の通信をできるようにした技術。
従来のWebチャットでは定期的なリロード時間がn秒として、誰かが発言してからそれを受信するまで平均n/2秒の遅延が発生していた。
しかしこの技術を使うことで、誰かが発言すれば次の瞬間全クライアントがその発言を受信することが可能になる。
Cometを用いたリアルタイムWebチャットはLingrが有名だ。
Lingrはチャットルームに"入室"しないと発言ができず、またチャットルームは誰かが作成した誰かの部屋だ。
今回作成するのは2chのような誰もが自由に匿名で書き込みができ、なおかつチャットルームは誰かの所有物ではなくオープンなスペースになる。もちろん個人のプライベートなチャットルームも作成可能にする予定。
これにより"入室"しないと発言できないLingrより敷居は低くなり、より活発な(そして荒れ気味にもなる)チャットプラットホームを実現することができる。使用用途は主に実況系を想定している。
以下感想。
Cometを用いたチャットの中心プログラムはすぐにできたけど、Ajax部分や慣れないTomcatの設定あたりで結構時間がかかったな。相変わらずIEとFirefoxなどブラウザごとにJavascriptの挙動が違うので苦労した。後はいろいろ調べてApacheとtomcatを連携させたと思ったらApacheの方がCometに対応してなくて結局Comet部分は連携できなかったり・・・・。
あとHTTPの仕様的には同じサーバにTCPのコネクションを同時に2本まで接続することを推奨していて、これにより一つのチャットルームに入るだけで2本全部消費してしまうのが結構めんどかったな。
1本は新規メッセージ取得用、もう1本はメッセージ投稿用だ。
このときほかにもう1本コネクションを張っていると、3本目のメッセージ投稿のコネクションを張ることができず、ほかのコネクションが切れるまで待ってしまう。よってメッセージを投稿することができない。
この問題はとりあえずチャットルームごとにドメインを分けることで解決した。
Firefoxはこれで解決したが、なぜかIEはコネクションを解放しないのか使っていないはずのコネクションを持ち続けて新しい接続を繋いでくれない。ちょっとIEでの挙動は調査が必要だ。
TCP Monitorで見るとページを読み込み終わってもTCPセッションが接続したままになることがあるからそれが原因かも。
あと先人の苦労としてLingrでの記事。
梅田サロン中止のお詫び、およびアーキテクチャ変更についての技術詳細レポート
というのがある。やはりちゃんと考えないとスケーラビリティの確保が大変なようだ。
うちのサーバも今のアーキテクチャじゃ対応できないのでそのうち変更しないとなぁ。
まぁ基本の考え方はよくあるDBのレプリケーションのようにマスターと多数のスレーブという構成でいけそうだ。
あと今回は、できる限り応答速度を速めるためにそれぞれの処理を多数のスレッドでのバケツリレーのように処理するようにした。こうしておくと今後のチャットサーバのクラスタ化にも役に立つだろう。
このときマルチスレッドでアクセスするので、データに対する処理にデリケートにならないといけないのだけど、Javaの強力な並行処理用パッケージが非常に助かった。同期がいらずノンブロッキングでスレッドセーフなキューのConcurrentLinkedQueueなんて涙が出るほどすばらしい。同期のいらなくて読み書き可能のCopyOnWriteArrayListも非常にうれしい。簡単にアトミックなカウンタが使えるAtomicLongも地味に助かる。
やっぱマルチスレッドはJavaだなと改めて思った2008年の正月だった。
CometとAjaxでチャットを作れて自分的にはだいぶ満足したが、作成したものはもったいないので世に出した方がよいとの助言を受けて、勢いに任せてドメインまでとってしまった。
とりあえずアニメ系の実況サイトにする予定。なぜアニメ系かというと俺がオタだから。最近は忙しくてアニメ見ることも少なくなって、アニオタというよりコンピュータGeekと言った感じだけど。
ドメインもとったことだしもうちょっと安定性を高めてしっかりしたものにしてみよう。
後は自然言語処理を用いていろいろとおもしろいアイデアがあるのでそれも試してみたいな。
あ、年末に注文していたキーボードは連休明けの8日に届く予定です。今はオンタリオ国際空港で出発待ちらしい。
ちょうどキーボードを必要としていた時期を見事に避けて届きやがります。
今年の正月はTVも見ずにプログラミングしてたので正月感が全くない。
世間的には"あけましておめでとう"なんだよな。ということで今年もよろしくお願いします。
Trackback on "AjaxとCometを用いたチャットサイトを作った"
このエントリーのトラックバックURL:
"AjaxとCometを用いたチャットサイトを作った"へのトラックバックはまだありません。
今、AjaxとCometを使用してチャットを作成中なのですが、ネットで検索してもなかなかサンプルが見つからずに苦労しております。
そんな時、このサイトを拝見し、動作が作成中のものと似ていたので、よろしければ作成したソースを見本に開発をしていきたいのですが、ソースを送っていただくことは出来ませんでしょうか?
こんにちは。
ソースをお渡しするのはできませんが、以下のURLが参考になるはずです。
Tomcat上でCometを用いたブラウザへのデータ送信サンプルです。
http://journal.mycom.co.jp/special/2007/tomcat6/014.html
Cometのキモはこれだけですので、後はAjaxで非同期通信をすればよいだけです。
Ajaxの方はWeb上に山ほどサンプルがあるのでそちらを参考にしてください。