Cometを試してみる(その2)
Category in Webサイト開発日記, comet, tomcat
Cometを利用してリアルタイムなチャットのシステムを作成してみます。
Eclipse3.3を起動して動的Webプロジェクトを作成します。
プロジェクト名をTomcat6Test としておきます。
test パッケージに TestCometServlet.java を作成します。
-
package test;
-
-
import java.io.IOException;
-
import java.io.PrintWriter;
-
import java.util.ArrayList;
-
import java.util.List;
-
-
import javax.servlet.ServletException;
-
import javax.servlet.http.HttpServlet;
-
import javax.servlet.http.HttpServletRequest;
-
import javax.servlet.http.HttpServletResponse;
-
-
import org.apache.catalina.CometEvent;
-
import org.apache.catalina.CometProcessor;
-
-
public class TestCometServlet extends HttpServlet implements CometProcessor {
-
-
private static final long serialVersionUID = -7518449035898058102L;
-
-
private List<httpservletresponse> responses = new ArrayList<httpservletresponse>();</httpservletresponse></httpservletresponse>
-
-
-
final HttpServletRequest request = event.getHttpServletRequest();
-
final HttpServletResponse response = event.getHttpServletResponse();
-
-
if ("POST".equals(request.getMethod())) { // 送信されたメッセージ
-
// 全てのクライアントへ送信
-
sendMessage(user + "> " + message + "
-
");
-
-
event.close();
-
return;
-
}
-
-
if (event.getEventType() == CometEvent.EventType.BEGIN) { // コネクション確率
-
// タイムアウトの設定
-
event.setTimeout(60 * 1000 * 30);
-
-
response.setContentType("text/html;charset=UTF-8");
-
writer.println("");
-
writer.println("");
-
writer.println("");
-
writer.flush();
-
-
addResponce(response);
-
-
} else if (event.getEventType() == CometEvent.EventType.READ) { // データ入力
-
removeResponce(response);
-
-
writer.println("");
-
-
event.close();
-
-
} else if (event.getEventType() == CometEvent.EventType.END) { // リクエスト終了
-
removeResponce(response);
-
-
writer.println("");
-
-
event.close();
-
-
} else if (event.getEventType() == CometEvent.EventType.ERROR) { // エラー
-
removeResponce(response);
-
-
event.close();
-
}
-
}
-
-
protected synchronized void addResponce(HttpServletResponse response) {
-
responses.add(response);
-
}
-
-
protected synchronized void removeResponce(HttpServletResponse response) {
-
responses.remove(response);
-
}
-
-
for (int i = 0; ((responses != null) && (i <responses.size())); i++) {
-
try {
-
printWriter.println(message);
-
printWriter.flush();
-
-
e.printStackTrace();
-
}
-
}
-
}
-
-
}
初めにリクエストがPOSTかどうかを判定しています。POSTの場合はメッセージの送信としてsendMessageメソッドを呼び出しています。
BEGINイベント
GETで初めて接続があった際ここに来ます。ページのヘッダ等をクライアントへ返して、レスポンスはListに格納しておきます。
メッセージの送信が無いとすぐにタイムアウトになってしまうので、タイムアウトの設定を30分にしておきます。
sendMessageメソッド
Listに格納されたレスポンス全てにメッセージを返します。接続のあったクライアント全てに送信される事になります。
WebCotent/jsp に TestCometChat.jsp を作成します。
-
<%@ page language="java" contentType="text/html; charset=UTF-8"
-
pageEncoding="UTF-8"%>
-
-
-
-
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-
-
-
-
-
このページにはフレームが使用されていますが、お使いのブラウザではサポートされていません。
フレーム上部はメッセージ送信、下部は受信用になります。
下部にてTestCometServletにGETしています。
引き続いて送信用の TestCometChatSender.jsp になります。
-
<%@ page language="java" contentType="text/html; charset=UTF-8"
-
pageEncoding="UTF-8"%>
-
-
-
-
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-
-
<script src="../js/TestCometChat.js" type="text/javascript"></script> <form method="post" action="--WEBBOT-SELF--"> User:
-
<input name="user" size="20" type="text" /> Message:
-
<input name="message" size="60" type="text" /> <input value="送信" onclick="postMessage(user.value, message.value, '../TestCometServlet', true)" type="button" /> </form>
userとmessageをPOSTします。
ebCotent/js に TestCometChat.js を作成します。
-
function createHttpRequest() {
-
-
if(window.ActiveXObject){
-
try {
-
//MSXML2
-
return new ActiveXObject("Msxml2.XMLHTTP");
-
-
} catch (e) {
-
try {
-
//MSXML
-
return new ActiveXObject("Microsoft.XMLHTTP");
-
-
} catch (e2) {
-
return null;
-
}
-
}
-
-
} else if(window.XMLHttpRequest){
-
return new XMLHttpRequest();
-
-
} else {
-
return null;
-
}
-
}
-
-
function postMessage( user , message , fileName , async ) {
-
var httpoj = createHttpRequest();
-
-
httpoj.open( 'POST' , fileName , async );
-
httpoj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
-
-
httpoj.onreadystatechange = function() {
-
if (httpoj.readyState==4) {
-
on_loaded(httpoj);
-
}
-
}
-
-
httpoj.send( 'user=' + user + '&message=' + message )
-
}
-
-
function on_loaded(oj) {
-
res = oj.responseText;
-
//alert(res);
-
}
TestCometChatSender.jsp が使用するJavaScriptになります。
web.xmlにサーブレットの設定を追加します。
-
<servlet>
-
<servlet-name>TestCometServlet</servlet-name>
-
<servlet-class>test.TestCometServlet</servlet-class>
-
</servlet>
-
<servlet-mapping>
-
<servlet-name>TestCometServlet</servlet-name>
-
<url-pattern>/TestCometServlet</url-pattern>
-
</servlet-mapping>
Tomcatを起動し、ページにアクセスしてみましょう。
http://localhost:8080/Tomcat6Test/jsp/TestCometChat.jsp
実際にメッセージを入力してみます。
リアルタイムにメッセージの送信が行われているのが判ります。
(最初の送信ではバッファのフラッシュの問題なのか表示がうまくされませんが、何度か送信を行っていると表示される様になります。)
チャットシステムとしては不完全ですが、この様にCometを利用する事でサーバサイドのタイミングでデータを送信する事が出来るのが判ります。
|
|
|
del.icio.us
|