TomcatでComet

Tomcat 6では入出力処理をNIO APIに置き換えるなどして、I/O周りが大幅にパワーアップしているらしい。そして、新しいAdvanced IOを利用してCometなサーブレットを作成できるようになったそうだ。とりあえず遊んでみた。

catalina.jarをクラスパスに追加

Comet関連のAPIJ2EE標準のAPIではなくTomcatプロジェクトの独自実装であるため、Comet関連クラスはservlet.jarではなく、Tomcat自身(catalina.jar)に含まれている。Cometなサーブレットをコンパイルするにはcatalina.jarにクラスパスを通さなくてはならない。開発環境がEclipse 3.2+Tomcatプラグインならば

  1. プロジェクトを右クリック、Properties → Build Path → Configure Build Path を開く
  2. Add Valiableを選択
  3. TOMCAT_HOMEを選択
  4. Extendをクリックし、libの中にあるcatalina.jarを追加

で、追加できる。

Advanced I/Oを有効にする

デフォルトではAdvanced IOは使用されないためCometは無効になっている。server.xmlのConnector要素を書き換える。

<Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" />

protocol属性を以下のように修正

<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" 
               connectionTimeout="60000" 
               redirectPort="8443" />

Cometを処理する - CometProsessorインターフェース

サーブレットはCometProsessorを実装する事でCometイベントを処理できるようになる。実装するメソッドは一つ。

public void event(CometEvent cometEvent) throws IOException, ServletException;

CometEvent

eventメソッドが呼ばれるのは、アクセスされたとき(BEGIN)、リクエストボディの読み込み準備完了した時(READ)、コネクションが閉じられる時(END)、タイムアウト等のエラー終了時(ERROR)。CometEvent#getEventTypeメソッドを使うと、現在の状態が分かるので処理を振り分ける。最初からイベント毎にメソッドを分割しておいてくれればいいのに。