1. 序章

HTTP(Hypertext Transfer Protocol)は、ステートレスな要求/応答プロトコルです。 そのシンプルな設計により、非常にスケーラブルですが、すべての要求/応答とともに送信する必要のあるオーバーヘッドの量のために、高度にインタラクティブなリアルタイムWebアプリケーションには不適切で非効率的です。

HTTPは同期であり、リアルタイムアプリケーションは非同期である必要があるため、ポーリングやロングポーリング( Comet )などのソリューションは複雑で非効率的である傾向があります。

上記の問題を解決するには、サーバーとクライアントの両方で使用できる標準ベースの双方向の全二重プロトコルが必要です。これにより、 JSR 356 API –が導入されました。この記事では、その使用例を示します。

2. 設定

SpringWebSocketの依存関係をプロジェクトに含めましょう。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>5.2.2.RELEASE</version>
 </dependency>
 <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-messaging</artifactId>
    <version>5.2.2.RELEASE</version>
 </dependency>

spring-websocketおよびspring-messagingの依存関係の最新バージョンは常にMavenCentralから入手できます。

3. STOMP

Stream Text-Oriented Messaging Protocol(STOMP)は、クライアントとサーバーがほぼすべてのメッセージブローカーと通信できるようにする、シンプルで相互運用可能なワイヤー形式です。 これは、AMQP(Advanced Message Queuing Protocol)およびJMS(Java Messaging Service)の代替手段です。

STOMPは、クライアント/サーバーがメッセージングセマンティクスを使用して通信するためのプロトコルを定義します。 セマンティクスはWebSocketの上にあり、WebSocketフレームにマップされるフレームを定義します。

STOMPを使用すると、さまざまなプログラミング言語でクライアントとサーバーを開発できる柔軟性が得られます。 この現在の例では、クライアントとサーバー間のメッセージングにSTOMPを使用します。

4. WebSocketサーバー

WebSocketサーバーの構築について詳しくは、この記事をご覧ください。

5. WebSocketクライアント

WebSocketサーバーと通信するには、クライアントはUpgradeヘッダーが適切に設定されたサーバーにHTTPリクエストを送信してWebSocket接続を開始する必要があります。

GET ws://websocket.example.com/ HTTP/1.1
Origin: http://example.com
Connection: Upgrade
Host: websocket.example.com
Upgrade: websocket

WebSocketのURLはwsおよびwssスキームを使用し、2番目のスキームは安全なWebSocketを意味することに注意してください。

WebSocketのサポートが有効になっている場合、サーバーは応答でUpgradeヘッダーを送信して応答します。

HTTP/1.1 101 WebSocket Protocol Handshake
Date: Wed, 16 Oct 2013 10:07:34 GMT
Connection: Upgrade
Upgrade: WebSocket

このプロセス(WebSocketハンドシェイクとも呼ばれます)が完了すると、最初のHTTP接続が同じTCP / IP接続上のWebSocket接続に置き換えられ、その後、どちらの当事者もデータを共有できるようになります。

このクライアント側の接続は、WebSocketStompClientインスタンスによって開始されます。

5.1. WebSocketStompClient

セクション3で説明したように、最初にWebSocket接続を確立する必要があります。これは、WebSocketClientクラスを使用して行われます。

WebSocketClient は、以下を使用して構成できます。

  • StandardWebSocketClientTyrusなどのJSR-356実装によって提供されます
  • JettyWebSocketClient Jetty9以降のネイティブWebSocketAPIによって提供されます
  • SpringのWebSocketClientの実装

この例では、WebSocketClientの実装であるStandardWebSocketClientを使用します。

WebSocketClient client = new StandardWebSocketClient();

WebSocketStompClient stompClient = new WebSocketStompClient(client);
stompClient.setMessageConverter(new MappingJackson2MessageConverter());

StompSessionHandler sessionHandler = new MyStompSessionHandler();
stompClient.connect(URL, sessionHandler);

new Scanner(System.in).nextLine(); // Don't close immediately.

デフォルトでは、WebSocketStompClientSimpleMessageConverterをサポートします。 JSONメッセージを扱っているので、メッセージコンバーターを MappingJackson2MessageConverter に設定して、JSONペイロードをオブジェクトに変換します。

エンドポイントへの接続中に、 StompSessionHandler のインスタンスを渡します。これは、afterConnectedhandleFrameなどのイベントを処理します。

サーバーがSockJsをサポートしている場合は、StandardWebSocketClient。の代わりにSockJsClientを使用するようにクライアントを変更できます。

5.2. StompSessionHandler

StompSession を使用して、WebSocketトピックをサブスクライブできます。 これは、 StompSessionHandlerAdapter のインスタンスを作成することで実行できます。このインスタンスは、StompSessionHandlerを実装します。

StompSessionHandler は、STOMPセッションのライフサイクルイベントを提供します。 イベントには、セッションが確立されたときのコールバックと、失敗した場合の通知が含まれます。

WebSocketクライアントがエンドポイントに接続するとすぐに、 StompSessionHandler が通知され、 afterConnected()メソッドが呼び出され、StompSessionを使用してサブスクライブします。トピック:

@Override
public void afterConnected(
  StompSession session, StompHeaders connectedHeaders) {
    session.subscribe("/topic/messages", this);
    session.send("/app/chat", getSampleMessage());
}
@Override
public void handleFrame(StompHeaders headers, Object payload) {
    Message msg = (Message) payload;
    logger.info("Received : " + msg.getText()+ " from : " + msg.getFrom());
}

WebSocketサーバーが実行中であり、クライアントを実行していることを確認してください。メッセージがコンソールに表示されます。

INFO o.b.w.client.MyStompSessionHandler - New session established : 53b993eb-7ad6-4470-dd80-c4cfdab7f2ba
INFO o.b.w.client.MyStompSessionHandler - Subscribed to /topic/messages
INFO o.b.w.client.MyStompSessionHandler - Message sent to websocket server
INFO o.b.w.client.MyStompSessionHandler - Received : Howdy!! from : Nicky

6. 結論

このクイックチュートリアルでは、SpringベースのWebSocketクライアントを実装しました。

完全な実装は、GitHubにあります。