Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

初めに

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

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

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

今回は以上。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away