|
|
こんにちは,結城浩です。
今回は,サーバーからデータをプッシュするタイプのWebアプリケーションを作成する技法の「Comet」を紹介します。簡単なチャット・プログラムを通してCometの仕組みを学びましょう。
Cometとは
通常のWebアプリケーションは,クライアント(Webブラウザ)から送られてくるリクエストを受け取って動作します。つまり,WebアプリケーションはユーザーがWeb上のリンクをたどったり,ボタンを押したりすることをきっかけに動くのです。ここで,動きの主導権はクライアント側にあります。クライアントがサーバーから情報を「引き出す」ことによって動作するので,通常のWebアプリケーションはプル(pull)型と呼ぶことがあります。ユーザーがサーバーの情報を「引き出す」イメージですね。
ここで紹介するCometは,プル型と逆のプッシュ(push)型のWebアプリケーションを作る技術の一種です。プッシュ型のWebアプリケーションでは,サーバーがクライアント側に情報を「押し込む」動作になるのです。
…と,これでは話が抽象的なので,Webチャットのアプリケーションを例にとって,アプリケーションを構成するパターンを三つ紹介していきます。現在利用されている技術と,ここで紹介するCometの違いを理解してください。
パターン1●AjaxやCometを利用しない場合
図1は,AjaxやCometを利用しないシンプルなWebチャットの構成図です*1。ブラウザは,サーバーにアクセスして「現在のチャット・ログ」を取得します。これはクライアント側主導でサーバーから情報を引き出しているので「プル型」です。
図1●ポーリングを行う場合 |
複数の人が同じサーバーにアクセスしてチャットしている場合,最新のチャット・ログを得るために,ブラウザは定期的にサーバーにアクセスする必要があります。この,「定期的にサーバーにアクセスして最新情報を得る」方法を,ポーリング(polling)と呼びます。
たしかにこの方法で,チャットをWebアプリケーションとして実装できます。ただし,サーバーの情報が更新されていてもいなくても,ブラウザが定期的にサーバーにアクセスする必要があります。言い換えれば,ユーザーが多くなってくると,サーバーへのアクセス数が非常に多くなってしまいます。
パターン2●Ajaxを利用する場合
図2はAjaxを使ったWebチャットの構成図です。クライアント側からサーバーへ,2種類のアクセスを行っています。
図2●JavaScriptでポーリングを行う場合 |
まず,ブラウザからサーバーへアクセスします。このアクセスはチャットを利用する最初の1回だけで,チャットをするページが返されます。これが一つ目のアクセスです。二つ目は,ブラウザからではなくJavaScriptから行われるアクセスです。JavaScriptがサーバーにアクセスし,チャット・ログを表示するために必要な情報を得ます。この情報をJavaScriptで画面に反映します。
これは,ブラウザの画面の遷移に同期しないで,サーバーのデータを取得して画面を書き換える――いわゆるAjax的なアプローチになります。ただし,クライアント側主導でサーバーから情報を引き出していることはパターン1と変わりません。パターン2もプル型です。
最新のチャット・ログを画面に表示するためには,図1のときと同じように,JavaScriptは定期的にサーバーにアクセスしなくてはなりません。つまりポーリングを行う必要があるのです。
パターン3●Cometを利用する場合
図3はCometを使ったWebチャットの構成図です。クライアント側からサーバーへは3種類のアクセスを行っています。
図3●Cometでプッシュする場合 |
一つ目は先ほどと同じく,ブラウザからサーバーへのアクセスです。
二つ目は,「読み込み用のJavaScript」からサーバーへのアクセスです。このアクセスはHTTPを使うのですが,その振る舞いは変わっています。「読み込み用のJavaScript」からのリクエストを受け取ったサーバーは,すぐにはレスポンスを返さないのです。つまり,わざとクライアント側を「待たせて」おきます。クライアント側は「誰かがチャットに書き込む」というイベントを待つのです。
三つ目のアクセスは,「書き込み用のJavaScript」からサーバーへのアクセスです。このアクセスはユーザーがチャットに対して発言(書き込み)したときに起こります。サーバー側は「書き込み用のJavaScript」からのリクエストを受け取ると,そのことを,待たせておいたスレッドやプロセスに通知します。この通知は「いま書き込みがあったので,チャット・ログが更新されていますよ」という意味になります。
通知を受けたスレッドやプロセスは,「読み込み用のJavaScript」に対してレスポンスを返します。このレスポンスは,通常のHTTPレスポンスと何も変わりません。しかし,「サーバーに書き込まれたタイミングで返される」わけですから,サーバー主導で,情報がクライアント側に送られてきたと見なすことができます。つまり,これは(疑似的に)プッシュ型の通信を作り上げていることになるのです。
プッシュ型の通信ではありますが,特殊なソフトウエアを使っているわけではありませんね。「WebブラウザとJavaScript」という既存のソフトウエアだけで動きます。Cometは既存のWebアプリケーション動作環境の範囲内で,プッシュ型のWebアプリケーションを実現していることになります。
Cometを使ったチャットでは,クライアントは定期的にサーバーへアクセスする必要はありません。つまり,Cometを使うとポーリングは不要になります。「読み込み用のJavaScript」は,サーバーからのレスポンスを受け取った後,再度リクエストを発行します(そして待たされます)。しかしそれはあくまでサーバーに書き込みがあったときだけです。サーバーに更新がないときには,クライアントからサーバーにアクセスは発生しません。
Cometの良い点,悪い点
前節で見たように,Cometではポーリングが発生しなくなります。したがって,サーバーへのアクセス数を減らすことができます。また,サーバーに書き込みがあったタイミングで情報が送られてくるので,リアルタイム性も向上することになります。これらはCometの良い点です。
しかし,良い点ばかりでもありません。プッシュ型を実現するため,Cometではアプリケーションの動作中,「読み込み用のJavaScript」とサーバーとつながりっぱなしにしておく必要があります。これは,Cometの悪い点です。なぜなら,つながりっぱなしではサーバーの資源を確保し続けてしまうからです。この問題を解決し,Cometを有効に使うためには,これまでとは異なる要求を満たすWebサーバーが必要になってきます。