Приложение Websocket с несколькими пользователями

Я пытаюсь написать веб-приложение с помощью Spring WebSocket. Я следовал инструкциям в этом руководстве: https://spring.io/guides/gs/messaging-stomp-websocket/

На стороне сервера. Мой контроллер сообщений:

@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()) + "!");
}

Мой WebSocketConfig:

@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();
    }

}

Клиентская сторона: вот как я подключаюсь:

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);
        });
    });
}

Проблема:

Когда я просматриваю веб-сайт с нескольких устройств, каждое из подключений получает сообщения от всех других подключений.

Как я могу настроить сервер так, чтобы он мог обрабатывать каждое соединение как отдельное соединение. Итак, сервер будет отправлять сообщение на конкретный сеанс?


person Sagiv Mapgavker    schedule 16.06.2018    source источник


Ответы (1)


Целью брокера, использующего /topic, является доставка сообщений каждому подписчику, чтобы получить сообщение для каждого соединения, вы должны использовать очередь /user

Это можно сделать, настроив контроллер на использование SendToUser вместо Отправить

@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()) + "!");
    }
}

Затем вы можете подписаться на очередь пользователей, используя

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

Затем, когда клиент позвонит:

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

Только клиент, отправивший hello сообщение, получит ответ greetings, а не все подключенные клиенты.

person mpromonet    schedule 16.06.2018