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 件のコメント:
コメントを投稿