1.概要

このクイックチュートリアルでは、Spring WebSocketsを使用して特定のセッションまたは特定のユーザーにメッセージを送信する方法を説明します。

上記のモジュールの紹介については、

この記事へ

を参照してください。

2. WebSocketの設定

まず最初に、メッセージブローカーとWebSocketアプリケーションエンドポイントを設定する必要があります。

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig
  extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic/", "/queue/");
    config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/greeting");
    }
}


@ EnableWebSocketMessageBroker

を使用して、

__

STOMP ** を使用して、WebSocketを介したブローカーによるメッセージングを有効にしました。


AbstractWebSocketMessageBrokerConfigurer

を拡張することは必須ではありませんが、簡単な例として、インポートされた設定をカスタマイズする方が簡単です。

最初の方法では、接頭辞

“/topic”



“/queue”

を付けて宛先にクライアントにメッセージを戻す単純なメモリーベースのメッセージブローカーを設定します。

そして2番目に、ストンプエンドポイントを

“/greeting”

に登録しました。

SockJSを有効にしたい場合は、レジスタ部分を修正する必要があります。

registry.addEndpoint("/greeting").withSockJS();

3.インターセプターによるセッションIDの取得

セッションIDを取得する** 方法の1つは、ハンドシェイク中にトリガーされてリクエストデータから情報を取得するSpring Interceptorを追加することです。

このインターセプターは__WebSocketConfigに直接追加できます。

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {

registry
  .addEndpoint("/greeting")
  .setHandshakeHandler(new DefaultHandshakeHandler() {

      public boolean beforeHandshake(
        ServerHttpRequest request,
        ServerHttpResponse response,
        WebSocketHandler wsHandler,
        Map attributes) throws Exception {

            if (request instanceof ServletServerHttpRequest) {
                ServletServerHttpRequest servletRequest
                 = (ServletServerHttpRequest) request;
                HttpSession session = servletRequest
                  .getServletRequest().getSession();
                attributes.put("sessionId", session.getId());
            }
                return true;
        }}).withSockJS();
    }

4. WebSocketエンドポイント

Spring 5.0.5.RELEASEからは、**

@ SendToUser

アノテーションが改善され、“

/user/\ {sessionId”を介してユーザーの宛先にメッセージを送信できるようになったため、カスタマイズは不要です。 “

/user/\ {user}/…​

”ではなく、}/…​

つまり、アノテーションは入力メッセージのセッションIDに依存して機能し、セッション専用の宛先に効果的に応答を送信します。

@Controller
public class WebSocketController {

    @Autowired
    private SimpMessageSendingOperations messagingTemplate;

    private Gson gson = new Gson();

    @MessageMapping("/message")
    @SendToUser("/queue/reply")
    public String processMessageFromClient(
      @Payload String message,
      Principal principal) throws Exception {
    return gson
          .fromJson(message, Map.class)
          .get("name").toString();
    }

    @MessageExceptionHandler
    @SendToUser("/queue/errors")
    public String handleException(Throwable exception) {
        return exception.getMessage();
    }
}

ここで、

@ SendToUser

は、メッセージ処理メソッドの戻り値を

Message

として、先頭に「

/user/\ {username}

」を付加して指定した送信先に送信することを示しています。

5. WebSocketクライアント

function connect() {
    var socket = new WebSocket('ws://localhost:8080/greeting');
    ws = Stomp.over(socket);

    ws.connect({}, function(frame) {
        ws.subscribe("/user/queue/errors", function(message) {
            alert("Error " + message.body);
        });

        ws.subscribe("/user/queue/reply", function(message) {
            alert("Message " + message.body);
        });
    }, function(error) {
        alert("STOMP error " + error);
    });
}

function disconnect() {
    if (ws != null) {
        ws.close();
    }
    setConnected(false);
    console.log("Disconnected");
}


WebSocketConfiguration

内のマッピング用に「

/greeting

」を指す新しい

WebSocket

が作成されます。

クライアントを「

/user/queue/errors

」と「

/user/queue/reply

」にサブスクライブすると、最後のセクションのコメント情報が使用されます。

ご覧のとおり、

@ SendToUser

は ”

queue/errors

“を指していますが、メッセージは ”

/user/queue/errors

“に送信されます。

6.まとめ

この記事では、Spring WebSocketを使用してメッセージをユーザーまたはセッションIDに直接送信する方法を検討しました

いつものように、例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-mvc-java[over on GitHub]から入手可能です。