初めに
タイトル通り。JavaSEでJettyを使ってWebSocket(JSR-356使用)サーバーを立てたので最小構成のメモ。
方法
必要なものはたった二つ。
- エンドポイント用のクラス(JSR-356準拠)
- サーバーを起動するMainメソッド
pom.xml
標準のjavax.websocket-api
とJettyのjavax-websocket-server-impl
に依存する。
・・・
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>javax-websocket-server-impl</artifactId>
<version>9.3.8.v20160314</version>
</dependency>
・・・
EndPoint
JSR-356に準拠して書くだけ。標準仕様なのでJettyは関係ない。
EchoServer
package com.tatesuke.lab.jetty_standalone_websocket_server;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
/**
* 言われたことを返すだけの単純なWebScoketServerEndPoint
*/
@ServerEndpoint("/echo")
public class EchoServer {
@OnOpen
public void onOpen(Session session) {
/* セッション確立時の処理 */
System.out.println("onOpen");
}
@OnMessage
public String onMessage(String message) {
System.out.println("onMessage " + message);
return "You said \"" + message + "\".";
}
@OnError
public void onError(Throwable t) {
t.printStackTrace();
}
@OnClose
public void onClose(Session session) {
System.out.println("onClose");
}
}
Main関数
サーバーを起動するロジックをかいてやる。
Main.java
package com.tatesuke.lab.jetty_standalone_websocket_server;
import javax.websocket.server.ServerContainer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
/**
* JettyによるStandalone Websocket Serverのmainメソッド
*/
public class Main {
public static void main(String[] args) throws Exception {
Server server = null;
try {
// Serverを生成
server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(8080);
connector.setHost("127.0.0.1");
server.addConnector(connector);
// ServletContextHandlerを生成
ServletContextHandler context = new ServletContextHandler(
ServletContextHandler.SESSIONS);
context.setContextPath("/lab");
server.setHandler(context);
// ServerContainerを生成
ServerContainer wscontainer = WebSocketServerContainerInitializer
.configureContext(context);
wscontainer.addEndpoint(EchoServer.class);
// Server起動
server.start();
server.join();
} finally {
// Server終了
if (server != null) {
server.stop();
}
}
}
}
動作確認
上記のプログラムを実行したら、下記のHTMLを保存してブラウザで実行する。
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>echo-websocket-client-sample</title>
</head>
<body>
<div>
<input placeholder="Type text and click button" type="text">
<button>send</button>
</div>
<div id="echoArea"></div>
<script>
var button = document.querySelector("button");
button.addEventListener("click", function() {
var elem = document.querySelector("input[type=text]");
var text = elem.value;
elem.value = "";
var ws = new WebSocket('ws://localhost:8080/lab/echo');
ws.onopen = function() {
ws.send(text);
}
ws.onmessage = function(event) {
var echoArea = document.querySelector("#echoArea");
var msg = event.data;
echoArea.insertAdjacentHTML("afterbegin", msg + "<br>");
ws.close();
}
});
</script>
</body>
</html>
テキストエリアに文字を入力してボタンを押すと、サーバーから返された文字を表示する。
さすが標準仕様。あっけなく動く。
今回は以上。