注:ネタバレがあります。
私が、デュラララ!!のチャットを再現する道のりは、竜ヶ峰帝人がダラーズのサイトを立ち上げたものを後から追っていくようなものだ。
竜ヶ峰帝人は、池袋でオフ会をしてあれだけのメンバーが集まるようなコミュニティサイトを立ち上げたんだから、きっとチャットもCometを実装したに違いない。彼の足跡を辿るようにして、私もCometの実装にとりかかった。Cometの実装パターンはいろいろあるが、その中でも一番修正が少なくて済みそうなXHR long-pollingという方法をとることにした。
この方法をPHPでやるとすると、AjaxでPHPにリクエスト → 新しい発言があるまでPHPが無限ループ → 発言が見つかるとデータレスポンスを返す → クライアントがデータを料理して表示 → 最初に戻る という流れになる。
PHPで無限ループするところでは、sleep(1)をかませるのが王道。一秒ごとに新しい発言がないかチェックするわけだ。しかし、このsleep()関数が第一の鬼門だった。チャットアプリは当然ログインしているわけで、セッションを張った状態になっている。このセッションが張られた状態で、sleep()の無限ループがつづいていると、その後に別のスクリプトに出したリクエストが帰ってこない。これは、どうしたものかと調べてみると、sleep()はスクリプト単位ではなく、セッション単位で機能するということ。とりあえず、sleep()に入る直前にsession_write_close()することで解決できた。
そして、Cometにおいて最大の難関にさしかかる。それはIEの対応。Cometは少なくても2コネクションを同時に使う。ひとつは発言のPOST、もうひとつは無限ループしてるスクリプトへのGET。IEだと、同時に2コネクションしか使うことができない。2個もあれば十分じゃないかと思ったら、チャット中に他のページに行くこと(3つ目のコネクションを作ること)ができないことが分かった。これはたぶんTCPの仕様じゃなかったかと思う。だからIEは間違ってない。FFやChromeが寛大なだけだ。
調べてみると、Cometではこの対策として複数のドメインをたらいまわす方法がとられているらしい。Ajaxではドメインを超えて通信できなので、IFRAMEの出番になる……。
ここまでのことを竜ヶ峰帝人は、高校生にしてやりとげたというのか!私が高校生だったころなんて、オブジェクト指向はおろか参照渡しもわからなかったと言うのに。帝人のウェブ技術に脱帽。
トラバURL : http://suin.asia/trackback/458
氷川 XOOPS Module 開発室