Commet

最近、ちょこちょことCometという言葉を耳にしていましたが、なんとなく非同期通信を実現する技術というくらいにしか理解していませんでした。
@IT-Tomcat 6で実現! Ajaxを超える通信技術Comet」という記事をきっかけに、ちょっと深掘りして理解したので、私なりに説明してみようと思います。

まず、Cometがどんなものかについては、以下のように説明されています。

@IT-Tomcat 6で実現! Ajaxを超える通信技術Cometより:

 Cometでは、まずクライアントから発行されたリクエストをサーバ側で受けた後に、HTTPコネクションをサーバで開きっぱなしにするため、クライアントに対して送信するはずのサーバからのレスポンスを待たせます。こうすることで、データ送信のタイミングをサーバ側へ委譲します。こうして、自分が送信したリクエストの内容を反映させる場合や、ほかの人が送信したリクエストに対してサーバが処理したいときに、レスポンスを返します。

これは別に新しい技術でも何でもなくて、「リクエストに対するレスポンスを一気に返さなくても、たいていのブラウザはとりあえず返ってきた分までを表示する」という特性を利用したものです。
例えば、時間がかかる処理を行う際に、とりあえず「処理中です・・・」という文字を出力しておいて、処理が終了した際に別のページにリダイレクトするためのJavaScriptを出力して画面遷移する、という小技を使っているアプリケーションは、Cometという言葉が出てくる前からあったと思います。

@ITの記事の3ページ目の画面キャプチャをよく見るとわかるのですが、左下に「待機中・・・」と表示されています。
(ブラウザからすると、単に「まだレスポンスが全部返ってきてないなぁ」と思っているだけです)


と、擬似的に非同期な表示を実現しているロジックは単純なものです。Cometという用語で説明されている考え方を実現するだけであれば、従来のプラットフォーム上で十分実現できます。

ただし、Cometはその特性上、「HTTPリクエストを開きっぱなしにする」ので、従来のプラットフォーム上でCometを実装しようとすると、以下のような問題があります。

  • 複数のリクエストに対して複数のスレッド(※)が立ち上がるので、それらのスレッドの間でデータのやり取りをしようとすると若干手間がかかる。
  • HTTPリクエストを開きっぱなしにすることに伴い、複数のリクエストに対する複数のスレッドが立ち上がったままになると、サーバー側のリソースを消費する。

(※)正確には、「スレッドまたはプロセス」ですが、いちいちそう表記するのは煩雑なので、単に「スレッド」と表記しています


2番目の問題については、「Lingr and Comet - 技術解説編」でも、以下のように書かれています。

ところが、先ほども言ったようにCometではコネクションはつなぎっぱなしになっていますから、いつまで経ってもプロセスやスレッド(およびメモリ資源)が解放されません。しかも、それらのスレッドは仕事もせずにアイドリングしており、メモリとCPUを浪費しているだけです。これは重大な問題です。どのぐらい重大かというと、そもそも千や万のオーダーの同時接続を実現することができません。

取りあえず実装するだけなら従来のプラットフォームで十分なのに、今回Tomcat6がわざわざ「Comet対応」を謳っているのは、上記の問題点を軽減しているからだと思われます。

@ITの記事の3ページ目ソースコードのサンプルが載っているのですが、これを見ると、1つのスレッドで複数のリクエストへのレスポンスを管理するということが簡単に実現できるようです。これは、確かに便利そうです。
また、複数のコネクションを1つのスレッドで管理できるようになっているのであれば、HTTPリクエストを開きっぱなしにしていてもスレッドが複数立ち上がったままにはならないようになっているのでしょう(詳細を調べたわけではなく、予想ですが)。

であれば、大量クライアントに対しても、サーバー側のリソースが大量に食いつぶされるということも軽減されていそうです。


というわけで、Tomcat6での「Comet対応」はそれなりに有意義なものだと思うのですが、そもそものCometというものは特別な技術でもなんでもないというのが私の理解です。

なぜ、さも新しい技術のような雰囲気でこの言葉が出てきたのかは、よくわかりません。。。