12/6 プログラムに一部追記しました。
Cometの原理
httpで接続したコネクションを接続しっぱなしにして、レスポンスのストリームにデータを流し込むことでプッシュを実現します。
クラス構成
サーバー側では少なくとも3つのクラスが必要です
- Cometサーバ実装クラス ・・・ プッシュするためのコネクションを確保するクラス。サーブレットです
- Cometハンドルクラス ・・・ CometHandlerを実装したクラス。ここにプッシュで送信する処理を記述します。
- ユーザプログラム ・・・ Cometを利用するプログラムです。
関連ライブラリ
Glassfishには
- grizzly-comet.jar
Cometサーバプログラム
クライアントとの接続を確保します。まず、init内では
- Cometエンジンの登録
- Cometエンジンの設定
- Cometエンジンの呼び出し
- Cometハンドラーへのコネクションストリームの受け渡し
- Cometハンドラーの登録
//初期設定 @Override public void init(ServletConfig config) throws ServletException { cometContextPath = config.getServletContext().getContextPath() + "/comet"; System.out.println("cometContextPath:"+cometContextPath); CometContext context = CometEngine.getEngine().register(cometContextPath); context.setExpirationDelay(10 * 60 * 60 * 1000); } protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); //CometHandlerクラスの登録 CometHandler handler = new MyHandler(); handler.attach(out); CometContext context = CometEngine.getEngine().getCometContext(cometContextPath); context.addCometHandler(handler); }Cometハンドラー Cometハンドラーとは何か?それは、Cometでの配信時の処理を記述するクラスです。ここで大切なのは、onEventメソッドです。これは、Pushする際に呼ばれるメソッドです。ここでwriterに対して書き込みを送ることで、クライアントにその内容が配信されます。なぜでしょう?それは、ここのwriterというのは、上記のサーバプログラムでハンドラーを登録する際にattachメソッドにて受渡したHttpServletResponseのWriterの事なのです。
public class MyHandler implements CometHandler<PrintWriter> { private PrintWriter writer = null; public void onEvent(CometEvent event) throws IOException { if (CometEvent.NOTIFY == event.getType()) { String id = (String) event.attachment(); writer = response.getWriter(); writer.write(id); writer.flush(); event.getCometContext().resumeCometHandler(this); } public void onInitialize(CometEvent event) throws IOException { System.out.println("Init"); } public void onTerminate(CometEvent event) throws IOException { onInterrupt(event); } public void onInterrupt(CometEvent event) throws IOException { writer.close(); event.getCometContext().removeCometHandler(this); } //クライアントとのストリームを受け取る public void attach(PrintWriter writer) { this.writer = writer; } private void removeThisFromContext() throws IOException { response.getWriter().close(); CometContext context = CometEngine.getEngine().getCometContext(cometContextPath); context.removeCometHandler(this); }ユーザプログラム ユーザプログラムでの記述は下記の通りです。以下はサーブレットの例ですが、ポイントは最後の行です。notifyメソッドを呼ぶことで、CometハンドラークラスのonEventが呼ばれることになります。つまり、プッシュしたい時にnotifyを呼び出せば良いわけです。引数は、ハンドラーのonEventメソッドでeventのアタッチメントとして取り出すことができます。
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletConfig config=this.getServletConfig(); String id = request.getParameter("id"); CometContext context = CometEngine.getEngine().getCometContext(cometContextPath); context.notify(id); }以上の3つを見比べることで、Cometが何をやっているのかわかるでしょう。コメットのサーバの設定や、クライアントプログラムの記述については、後日書こうかと思ってます。
0 件のコメント:
コメントを投稿