LoginSignup
5
6

More than 5 years have passed since last update.

JavaSEでJettyを使ってWebSocket(JSR-356)サーバーを立てた

Posted at

初めに

タイトル通り。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>

テキストエリアに文字を入力してボタンを押すと、サーバーから返された文字を表示する。

さすが標準仕様。あっけなく動く。

今回は以上。

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6