Sagiv Mapgavker
Sagiv Mapgavker

Reputation: 31

Websocket application with multiple users

I try to write web application with Spring WebSocket. I followed the instruction in this tutorial: https://spring.io/guides/gs/messaging-stomp-websocket/

Server side: My message controller is:

@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
    Thread.sleep(1000); // simulated delay
    return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
}

My WebSocketConfig is:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

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

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/gs-guide-websocket").withSockJS();
    }

}

Client side: this is how i connect:

function connect() {
    var socket = new SockJS('/gs-guide-websocket');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        stompClient.subscribe('/topic/greetings', function (greeting) {
            window.alert(JSON.parse(greeting.body).content);
        });
    });
}

The Problem:

When I browse to the website from multiple devices, each of the connections get the messages from all other connections.

How can I configure the server to be capable of handling each connection as individual connection.. So the server will send a message to specific session?

Upvotes: 2

Views: 5617

Answers (1)

mpromonet
mpromonet

Reputation: 11962

The purpose of the broker that use /topic is to deliver messages to each subscriber, in order to get message per connection, you should use the /user queue

This could be done configuring the controler to use SendToUser instead of SendTo

@Controller
public class GreetingController {
    @MessageMapping("/hello")
    @SendToUser("/greetings")
    public Greeting greeting(HelloMessage message) throws Exception {
        Thread.sleep(1000); // simulated delay
        return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
    }
}

Next you can subscribe to the user queue using

stompClient.subscribe('/user/greetings', function (greeting) {
    window.alert(JSON.parse(greeting.body).content);
});

Then when the client will call:

stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));

Only the client that send hello message will receive the greetings answer and not all connected clients.

Upvotes: 1

Related Questions