WebSocketを使って簡単に文字列のやり取りができるアプリケーションが必要だったので、Vert.xを使って書いてみた。
Groovyを使っているのは、Groovyが好きなのと、ラクに書きたかったのと、これを発展させた先でJavaのAPIを呼ぶ必要があったから。
Groovyで書くWebSocketサーバー側
def wsMap = [:] as java.util.concurrent.ConcurrentHashMap
// ws://localhost:8080/user_id にアクセスしてもらう前提
vertx.createHttpServer().websocketHandler { ws ->
// URLからユーザーIDを取得
def userId = ws.path.replaceAll(/^\//, "") /// このコメントはQiitaでの解釈がおかしくなるのを防ぐため…
// ユーザーIDとアクセスしてきたオブジェクトの組み合わせを保持
wsMap.put(userId, ws)
// クライアントから送信されてきた時のHandler
ws.dataHandler { data ->
// "送信先ユーザーID:メッセージ" が送られてくる想定
def (toId, msg) = data.toString().split(':')
if (wsMap.containsKey(toId)) {
// 送り先が存在すればメッセージを送る
vertx.eventBus.send(wsMap[toId].textHandlerID, msg)
} else {
// 送り先が存在しなければ送り主に返す
ws.writeTextFrame("sender don't find")
}
}
// クライアントから切断された時のHanlder
ws.closeHandler {
wsMap.remove(ws.textHandlerID)
println "close : ${ws.textHandlerID}"
}
}.listen(8080, "0.0.0.0") // アドレスをlocalhostにすると外から繋がらなくなる
HTML + JavaScriptで書くクライアント側
<!DOCTYPE html>
<html>
<head>
<title>WebSocket trial</title>
<meta charset="UTF-8">
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
</head>
<body>
<input type="text" id="user_id">
<button id="openButton">接続</button>
<input type="text" id="send_id">
<input type="text" id="message">
<button id="sendButton">送信</button>
<button id="closeButton">切断</button>
<div id="out_message"></div>
</body>
<script>
var socket;
$("#openButton").on('click', function() {
socket = new WebSocket("ws://localhost:8080/" + $("#user_id").val());
socket.onopen = function(event) {
console.log("Web Socket opened");
};
socket.onmessage = function(event) {
console.log("Received data from websocket: " + event.data);
$("#out_message").html("Received data from websocket: " + event.data);
}
socket.onclose = function(event) {
console.log("Web Socket closed");
};
});
$("#sendButton").on("click", function(event) {
var user_id = $("#send_id").val();
var message = $("#message").val();
socket.send(user_id + ":" + message);
});
$("#closeButton").on("click", function(event){
console.log("close button click");
socket.close(1000, "Close button clicked.");
});
</script>
</html>
参考URL
Vert.x Groovy manual
Vert.x で WebSocket - なんとなくな Developer のメモ