Search code examples
javaspring-bootwebsocketspring-websocketspring-messaging

Change websocket scope (from application to session/view)


I created a basic web socket with a tutorial.

Here is a configuration:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

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

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

And here is the message handling controller:

@MessageMapping("/chat")
@SendTo("/topic/messages")
public OutputMessage send(Message message) throws Exception {
    return new OutputMessage("Hello World!");
}

Everything works, but from my investigation, it looks like the WebSockets by default has an application scope (by connecting to the channel I can see all calls, from all users).

What I want to do is to be able to see only calls from the current user session or current view only. Any ideas on how to apply these configurations?


Solution

  • I was able to solve this puzzle, so I'm sharing with you my findings.

    First, I found information that a simple in-memory message broker can not handle this:

        /*
         * This enables a simple (in-memory) message broker for our application.
         * The `/topic` designates that any destination prefixed with `/topic`
         * will be routed back to the client.
         * It's important to keep in mind, this will not work with more than one
         * application instance, and it does not support all of the features a
         * full message broker like RabbitMQ, ActiveMQ, etc... provide.
         */
    

    But this was misleading, as it can be easily achieved by @SendToUser annotation. Also, the important thing that now on the client-side, you need to add an additional prefix /user/ while subscribing to the channel, so the solution would be:

    1. On the server-side: change @SendTo("/topic/messages") into @SendToUser("/topic/messages").
    2. On the client-side: /topic/messages into the /user/topic/messages.