Spring WebSockets:ユーザーチャットを構築する

Spring WebSockets:ユーザーチャットを構築する

1. 前書き

このチュートリアルでは、use Spring WebSockets to send STOMP messages to a single user.の方法について説明します。これは、すべてのメッセージをすべてのユーザーにブロードキャストしたくない場合があるため、重要です。 さらに、これらのメッセージを安全な方法で送信する方法を示します。

WebSocketの概要については、起動して実行する方法についてのthisの優れたチュートリアルをご覧ください。 また、セキュリティの詳細については、thisの記事を確認してWebSocketの実装を保護してください。

2. キュー、トピック、およびエンドポイント

Spring WebSocketとSTOMPを使用しているthree main ways to say where messages are sent and how they are subscribed toがあります。

  1. Topics –任意のクライアントまたはユーザーに開かれた一般的な会話またはチャットトピック

  2. Queues –特定のユーザーとその現在のセッション用に予約済み

  3. Endpoints –一般的なエンドポイント

それでは、それぞれのコンテキストパスの例を簡単に見てみましょう。

  • “/topic/movies”

  • “/user/queue/specific-user”

  • “/secured/chat”

 we must use queues to send messages to specific users, as topics and endpoints don’t support this functionalityに注意することが重要です。

3. 設定

それでは、特定のユーザーにメッセージを送信できるようにアプリケーションを構成する方法を学びましょう。

public class SocketBrokerConfig extends
  AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/secured/user/queue/specific-user");
        config.setApplicationDestinationPrefixes("/spring-security-mvc-socket");
        config.setUserDestinationPrefix("/secured/user");
    }

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

どのエンドポイントがシングルユーザー用に予約されるかを決定するので、ユーザーの宛先を必ず含めましょう。

また、すべてのキューとユーザーの宛先の前に“/secured”を付けて、認証が必要になるようにします。 保護されていないエンドポイントの場合、(他のセキュリティ設定の結果として)“/secured”プレフィックスを削除できます。

pom.xmlの観点からは、追加の依存関係は必要ありません。

4. URLマッピング

次のパターンに準拠するURLマッピングを使用して、クライアントにキューをサブスクライブさせます。

"/user/queue/updates"

このマッピングは、UserDestinationMessageHandlerによってユーザーセッション固有のアドレスに自動的に変換されます。

たとえば、“user123”という名前のユーザーがいる場合、対応するアドレスは次のようになります。

"/queue/updates-user123"

サーバー側では、次のURLマッピングパターンを使用してユーザー固有の応答を送信します。

"/user/{username}/queue/updates"

これも、すでにクライアント側にサブスクライブしている正しいURLマッピングに変換されます。

したがって、the essential ingredients here are two-fold:

  1. 指定したユーザー宛先プレフィックス(AbstractWebSocketMessageBrokerConfigurerで構成)を付加します。

  2. マッピング内のどこかで“/queue”を使用します。

次のセクションでは、これを行う方法を正確に見ていきます。

5. convertAndSendToUser()の呼び出し

SimpMessagingTemplateまたはSimpMessageSendingOperationsからconvertAndSendToUser()を非静的に呼び出すことができます。

@Autowired
private SimpMessagingTemplate simpMessagingTemplate;

@MessageMapping("/secured/room")
public void sendSpecific(
  @Payload Message msg,
  Principal user,
  @Header("simpSessionId") String sessionId) throws Exception {
    OutputMessage out = new OutputMessage(
      msg.getFrom(),
      msg.getText(),
      new SimpleDateFormat("HH:mm").format(new Date()));
    simpMessagingTemplate.convertAndSendToUser(
      msg.getTo(), "/secured/user/queue/specific-user", out);
}

お気づきかもしれません:

@Header("simpSessionId") String sessionId

The @Header annotation allows access to headers exposed by the inbound message.たとえば、複雑なインターセプターを必要とせずに、現在のsessionIdを取得できます。 同様に、we can access the current user via Principal.

重要なのは、この記事で採用しているアプローチでは、URLマッピングに関して@sendToUserアノテーションをさらにカスタマイズできることです。 そのアノテーションの詳細については、thisのすばらしい記事をご覧ください。

クライアント側では、JavaScriptでconnect()initialize a SockJS instance and connect to our WebSocket server using STOMP:に使用します

var socket = new SockJS('/secured/room');
var stompClient = Stomp.over(socket);
var sessionId = "";

stompClient.connect({}, function (frame) {
    var url = stompClient.ws._transport.url;
    url = url.replace(
      "ws://localhost:8080/spring-security-mvc-socket/secured/room/",  "");
    url = url.replace("/websocket", "");
    url = url.replace(/^[0-9]+\//, "");
    console.log("Your current session is: " + url);
    sessionId = url;
}

また、提供されたsessionIdにアクセスし、それを「secured/room URLマッピング」に追加します。 This gives us the ability to dynamically and manually supply a user-specific subscription queue:

stompClient.subscribe('secured/user/queue/specific-user'
  + '-user' + that.sessionId, function (msgOut) {
     //handle messages
}

すべての設定が完了すると、次のように表示されます。

 

image

そして、サーバーコンソールで:

image

6. 結論

このトピックの詳細については、公式のSpringblogofficial documentationを確認してください。

いつものように、この記事で使用されているコードサンプルはover on GitHubで入手できます。