JavaEE7にはwebsocketを実装したパッケージ(javax.websocket)が提供されています。
これを使ったサンプルコードを書いてみました。
ブラウザから入力された数字の数だけ、適当な文字列(数字列)を接続している全ブラウザに表示するコードです。
まずはJava側。Servletクラスとかを継承しなくていいみたいです。
注意が必要なのは、RemoteEndpoint.Async.sendText()はFuture型のオブジェクトを返すということ。つまり、sendText()メソッドの処理は非同期で行われます。
sendText()はその仕様として処理が終わる前に、再び呼び出されるとjava.lang.IllegalStateExceptionを送出します。そのため、for文などを用いて繰り返し、メッセージを送りたい場合はFuture.get()などを用いて、処理が終わるのを待ってから次のメッセージを送るようにします。
import java.util.Collections;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/endpoint")
public class Main {
static Set<session> sessions = Collections.synchronizedSet(new HashSet<session>());
@OnMessage
public void onMessage(String message) {
int count = Integer.valueOf(message);
run(count);
}
@OnOpen
public void open(Session sess) {
sessions.add(sess);
}
@OnClose
public void close(Session sess) {
sessions.remove(sess);
}
public void sendMessageToBrowser(String message) {
for (Session s : sessions) {
Future future = s.getAsyncRemote().sendText(message);
try {
future.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void run(int count){
Random rnd = new Random();
for(int i = 0; i < count; i++){
String s = String.valueOf(rnd.nextInt());
sendMessageToBrowser(s);
}
}
}
続いてhtml。
<!DOCTYPE html>
<html>
<head>
<title>WebSocketテスト</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="http://code.jquery.com/jquery-1.9.0.js"></script>
<script type="text/javascript">
var socket;
$(document).ready(function(){
var server="ws://localhost:8080/temporary/endpoint";
socket = new WebSocket(server);
socket.onmessage = function(message){
$('#messageFromServer').append(message.data + "<br/>");
};
$('#send').click(function(){
var text = $('#msg').val();
socket.send(text);
})
});
</script>
</head>
<body>
<div id="messageFromServer">
input the integer</div>
<input id="msg" type="text"/>
<button id="send">go</button>
</body>
</html>
参考文献
WebSocketをネタにJava EE 7正式版を試してみる