https://d226lax1qjow5r.cloudfront.net/blog/blogposts/creating-a-websocket-server-with-spring-boot/springboot_websocket.png

Spring BootでWebSocketサーバーを作成する

最終更新日 June 24, 2021

所要時間:1 分

ウェブソケットは、サーバーとブラウザー間の通信を可能にするプロトコルである。通信が双方向かつリアルタイムであるため、RESTful HTTPよりも優れている。このため、クライアントが定期的に更新をポーリングする代わりに、サーバーがいつでもクライアントに通知することができます。

この連載では、JavaでWebSocketサーバーを作成する3つの異なる方法を紹介します。 Spring BootSpark Frameworkそして Java API for WebSockets.

前提条件

使用するのは Gradleを使います。

さらに、JDKのコピーがインストールされていることを確認する必要がある。このチュートリアルではJDK 8を使用します。

Spring BootでWebSocket

Spring Bootを使えば、実行可能なJARの中にプロダクショングレードのSpringアプリケーションを作成できる。

プロジェクトの作成

を使用することができます。 Spring Initializrを使ってアプリケーションを起動し、必要なパッケージを選択します。

この例では Websocket依存関係が必要です。また、Gradleを使うつもりなので、Gradleプロジェクトを生成するように変更したい。

Spring Initializer HomepageSpring Initializer Homepage

Generate Projectボタンをクリックすると、zipファイルがダウンロードされます。お好きなディレクトリに解凍してください。

WebSocketハンドラの作成

WebSocketメッセージにはテキストとバイナリの両方があります。この両方のメッセージを処理できるハンドラを作成することになります。

という新しいクラスを作成する。 WebSocketHandlerという新しいクラスを作成する。 AbstractWebSocketHandlerを継承した com.example.websocketdemoパッケージを継承した AbstractWebSocketHandlerには2つのメソッドを実装する必要があります、 handleTextMessagehandleBinaryMessageの2つのメソッドを実装する必要があります。

デモンストレーションのために、受信したメッセージを送信者にエコーで返すエコー・サーバーを作成する。

以下の実装を追加する:

@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
    System.out.println("New Text Message Received");
    session.sendMessage(message);
}

@Override
protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws IOException {
    System.out.println("New Binary Message Received");
    session.sendMessage(message);
}

WebSocketハンドラの登録

を使用するには WebSocketHandlerを使うには、Springの WebSocketHandlerRegistry.以下は2つのことを実現する:

  1. を登録する。 WebSocketHandlerを登録する。 /socketパスに登録されます。

  2. これにより、すべてのブラウザークライアントがサーバーにメッセージを送信できるようになる。特定のオリジンを持つ必要はありません。

という新しいクラスを作成する。 WebSocketConfigurationという新しいクラスを作成する。 WebSocketConfigurerインターフェイスを実装した com.example.websocketdemoパッケージに実装します。

注釈 WebSocketConfiguration@Configuration@EnableWebSocketの注釈を付ける。

WebSocketConfigurerメソッドを実装する必要がある。 registerWebSocketHandlersメソッドを実装する必要があります。

以下の実装を登録する。 WebSocketHandler:

@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry.addHandler(new WebSocketHandler(), "/socket").setAllowedOrigins("*");
}

テキスト・メッセージに加えてバイナリ・メッセージも扱うことになるので、バイナリ・メッセージの最大サイズを設定することをお勧めします。これはサーバコンテナに格納される値です。この値をオーバーライドするには、新しいサーバコンテナファクトリを WebSocketConfiguration.

以下のコードを追加して、新しい ServletServerContainerFactoryBeanを注入する。 WebSocketConfigurationメソッドの上に registerWebSocketHandlersメソッドを追加します:

@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
    ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
    container.setMaxBinaryMessageBufferSize(1024000);
    return container;
}

1MBまでの画像をアップロードすることができます。

アプリケーションをテストするクライアントを作成する

WebSocketサーバーをテストするためにクライアントを作成する必要があります。テキスト・メッセージとバイナリ・メッセージの両方を送信するテストが必要です。これはJavaScriptで実現できます。

以下を index.htmlフォルダ内に src/main/resources/staticフォルダーの中に追加する:

<html>
<head>
    <style>
        #messages {
            text-align: left;
            width: 50%;
            padding: 1em;
            border: 1px solid black;
        }
    </style>
    <title>Sample WebSocket Client</title>
</head>
<body>
<div class="container">
    <div id="messages" class="messages"></div>
    <div class="input-fields">
        <p>Type a message and hit send:</p>
        <input id="message"/>
        <button id="send">Send</button>

        <p>Select an image and hit send:</p>
        <input type="file" id="file" accept="image/*"/>

        <button id="sendImage">Send Image</button>
    </div>
</div>
</body>
<script>
    const messageWindow = document.getElementById("messages");

    const sendButton = document.getElementById("send");
    const messageInput = document.getElementById("message");

    const fileInput = document.getElementById("file");
    const sendImageButton = document.getElementById("sendImage");

    const socket = new WebSocket("ws://localhost:8080/socket");
    socket.binaryType = "arraybuffer";

    socket.onopen = function (event) {
        addMessageToWindow("Connected");
    };

    socket.onmessage = function (event) {
        if (event.data instanceof ArrayBuffer) {
            addMessageToWindow('Got Image:');
            addImageToWindow(event.data);
        } else {
            addMessageToWindow(`Got Message: ${event.data}`);
        }
    };

    sendButton.onclick = function (event) {
        sendMessage(messageInput.value);
        messageInput.value = "";
    };

    sendImageButton.onclick = function (event) {
        let file = fileInput.files[0];
        sendMessage(file);
        fileInput.value = null;
    };

    function sendMessage(message) {
        socket.send(message);
        addMessageToWindow("Sent Message: " + message);
    }

    function addMessageToWindow(message) {
        messageWindow.innerHTML += `<div>${message}</div>`
    }

    function addImageToWindow(image) {
        let url = URL.createObjectURL(new Blob([image]));
        messageWindow.innerHTML += `<img src="${url}"/>`
    }
</script>
</html>

アプリケーションの開始

これでWebSocketサーバーは完成です。アプリケーションのディレクトリ内で gradle bootRunコマンドを使ってアプリケーションを起動します。

アプリケーションは以下からアクセスできます。 http://localhost:8080にアクセスしてください:

Sample JavaScript-enabled client for testing the WebSocket serverSample JavaScript-enabled client for testing the WebSocket server

connected "メッセージは、JavaScriptクライアントが接続できたことを示す。

入力フィールドに入力して送信ボタンをクリックし、テキストメッセージを送信してみてください。また、画像をアップロードしてみてください。どちらの場合も、同じメッセージと画像がエコーバックされるはずです。

Sample JavaScript-enabled client showing a text and binary message echoed backSample JavaScript-enabled client showing a text and binary message echoed back

結論

このチュートリアルでは、バイナリメッセージとテキストメッセージの両方を受信できるWebSocketサーバーをSpring Bootを使って作成する方法を学びました。このチュートリアルの完成したコードは リポジトリにあります。リポジトリにあります。

スパーク・フレームワークを試しましたか?以下の方法をご覧いただきたい。 Spark Frameworkを使用してWebSocketサーバーを作成する.

のエンドポイントとしてWebSocketを使用できることをご存知ですか? 呼び出し制御オブジェクト?次の例を見てください。 Voice WebSocketを使ったブラウザへのストリーミングコール.

シェア:

https://a.storyblok.com/f/270183/150x150/a3d03a85fd/placeholder.svg
Steve Crowヴォネージの卒業生

スティーブは自称数学者で、悪口の王様。グレイハウンド、曲がりくねったパズル、ヨーロッパのボードゲームをこよなく愛する。 非数学系の人には数学を、非Java系の人にはJavaの話をしていないときは、コーヒーを飲みながらコードをハックしている。