Несколько пользовательских сеансов не получают сообщение о подписке - Spring Stomp WebSocket

Я использую платформу Spring Stomp WebSocket для отправки сообщений подписки клиентам. Мы используем ActiveMQ в качестве брокера сообщений и используем javascript-клиент Stomp. Spring 4.1.5 и в этой архитектуре сообщения отправляются с использованием

simplemessagingTemplate.convertAndSendToUser(user, "/queue/msg", serverMsg, map);

Чтобы гарантировать, что только правильный пользователь получит свое сообщение, я также использую QueueSubscriptionInterceptor, который реализует ChannelInterceptor. Сообщения доставляются по назначению правильно. Сообщения принимаются с использованием JS-клиента следующим образом.

  stompClient.subscribe('/user/guest/queue/msg', function(greeting){              
                    x = JSON.parse(greeting.body);
                    ...
                    }

Все идет нормально. Однако при наличии нескольких пользовательских сеансов сообщение получает только один сеанс. Например, если два «гостевых» пользователя вошли в систему, я бы хотел, чтобы все два «гостевых» пользователя получили сообщение. Кажется, этого не происходит. Заглядывая в логи, вижу, что сообщение вроде как отправлено ..

2015-04-11 14:39:40 DEBUG StompBrokerRelayMessageHandler:738 - Forwarding SEND /queue/msg-user1 session=_system_ application/json;charset=UTF-8 payload={"my message to you...)
2015-04-11 14:39:40 DEBUG StompBrokerRelayMessageHandler:738 - Forwarding SEND /queue/msg-user0 session=_system_ application/json;charset=UTF-8 payload={"my message to you...)

Я вижу, что сообщение получает только один клиент, а другой нет. Читая документацию Spring, я понимаю, что это поведение по умолчанию. Может кто подскажет, что я делаю не так.

Спасибо.


person myspri    schedule 11.04.2015    source источник


Ответы (2)


Вам следует использовать семантику тем вместо очередей.

Очередь позволяет использовать сообщение один раз, но тема позволяет использовать его один раз для каждого подписчика. Так что что-то вроде / topic / user / guest / msg, вероятно, подойдет.

person Petter Nordlander    schedule 12.04.2015
comment
Я попытался перейти к теме вместо очереди. Все еще не мог заставить его работать. Журнал показывает следующее: Переведено / user / guest / topic / msg - ›[/ topic / msg-user2, / topic / msg-user3]. Использование convertAndSendToUser автоматически добавляет / user / и, таким образом, создает / user / guest / topic / msg. - person myspri; 13.04.2015

Установите заголовок подтверждения в кадре подключения. Это приведет к тому, что сервер будет продолжать отправлять вам то же сообщение, пока вы не отправите обратно кадр подтверждения. Что я делаю ниже, вызывая приветствие.ack (), как только получаю сообщение. Установка его на «индивидуальный клиент» будет означать, что сервер должен получать подтверждения от всех сеансов конкретного клиента, или он будет продолжать отправлять одно и то же сообщение при каждом ПОДКЛЮЧЕНИИ. Надеюсь это поможет!! Используйте приведенный ниже код для справки.

   function connect() {
    var socket = new SockJS('/powerme-notification-websocket');
    stompClient = Stomp.over(socket);
    stompClient.connect(
        {client_id:'testClient'}, function (frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        stompClient.subscribe('/user/topic/releaseLock', function (greeting) {
        stompClient.subscribe('/queue/releaseLock-testClient', function (greeting) {
            console.log(greeting);
            showGreeting(greeting.body);
            greeting.ack();
        },{durable:true,
            'auto-delete':false,
        ack:'client-individual',
        id:'testClient'});

    }); 
}

Ссылки: https://stomp.github.io/stomp-specification-1.2.html#ACK

person Malkeith Singh    schedule 18.10.2018
comment
Для связи через веб-сокет мы используем протокол STOMP. Так же, как протокол http: put, post, get и т. Д., STOMP имеет подключения, подписку, подтверждение и т. Д., Которые называются фреймами. Первый кадр, который мы отправляем, - это кадр подключения, который сообщает серверу о параметрах подключения, которые мы определяем с помощью заголовков. заголовок ack сообщает серверу, что он должен получить подтверждение от клиента о доставке сообщения. Если сервер не получает кадра подтверждения для сообщения, он будет повторно отправлять его клиенту при каждом CONNECT. - person Malkeith Singh; 18.10.2018
comment
Ознакомьтесь с документацией STOMP: stomp.github.io/stomp-specification-1.2. html # ACK - person Malkeith Singh; 18.10.2018