Невозможно отправить сообщение, специфичное для пользователя, с помощью Spring Websocket STOMP

Я пытаюсь создать чат-приложение, используя Spring WebSocket и Stomp.
Я использую Spring 4.1.1, Stomp.js, ActiveMQ 5.9.
Этот пользователь может отправлять сообщения каждому из своих друзей, которые также вошли в систему, войдя в приложение. Для отправки сообщения конкретному пользователю я делаю следующие шаги:
1) Пользователь регистрируется в
2) Пользователь подписывается на пункт назначения «/ user / queue / messaging».
Это будет использоваться для отправки личных сообщений пользователей друг к другу.
3) когда пользователь хочет отправить сообщение, он отправляет его по назначению:
/ user / {user_id} / queue / messaging, где user_id - это идентификатор пользователя получателя.
Я пытаюсь отправить это от клиента, использующего метод отправки STOMP.js.
4) Ожидаемое поведение: теперь, если получатель вошел в систему и его идентификатор сеанса, например, DFT0GH, то сообщение на шаге e должно быть доставлено в место назначения очереди с именем сообщения- userDFT0GH. Вместо этого он доставляется в очередь того же пользователя, который его отправил.

Пожалуйста, найдите мой пример сценария:
1) Пользователь Джон входит в систему. Он подписывается на / user / queue / messaging
Его идентификатор пользователя - john.
Его идентификатор сеанса - ABCD01.
Очередь создается с именем на брокере activemq в качестве сообщения - userABCD01

2) Пользователь Алиса входит в систему.
Она подписывается на / user / queue / messaging.
Его идентификатор пользователя - alice.

3) пользователь Джон отправляет сообщение через метод отправки STOMP.js Алисе, используя пункт назначения как «/ user / alice / queue / messaging»

4) теперь вместо доставки сообщения в очередь обмена сообщениями - UserXYZ01, оно доставляется в место назначения очереди Джона, то есть сообщение - userABCD01. Почему это так?

Когда я отладил это, я обнаружил следующую строку в методе private DestinationInfo parseUserDestination (сообщение сообщения) класса DefaultUserDestinationResolver:

  if (SimpMessageType.MESSAGE.equals(messageType)) {
        ........
    sessionIds = (sessionId != null ?
                Collections.singleton(sessionId) : this.userSessionRegistry.getSessionIds(user));      
    }

В этом sessionId регистрируется идентификатор сеанса пользователя (принципала), который не равен нулю, поскольку пользователь вошел в систему, и поэтому его sessionIds возвращаются, и сообщение доставляется в его очередь, даже если предполагаемый пользователь-получатель отличается.
Когда я проверяю sessionIds usersessionregistry collection Я нахожу запись [alice]: XYZ01.
Не следует ли выше строки возвращать идентификатор сеанса, если пользователь вместо входа в сеанс пользователя для определения очереди назначения.?

Извините, я пробую это впервые. Поэтому, пожалуйста, дайте мне знать, если я что-то пропущу здесь и есть ли
1) какой-либо способ удовлетворить мой вариант использования
2) или сам мой вариант использования недействителен.

Заранее спасибо.


person Shailesh Vaishampayan    schedule 17.11.2014    source источник
comment
Кажется, это ошибка, появившаяся начиная с Spring 4.1.0. Ссылка PFB на JIRA, которую я открыл: jira.spring.io/browse/SPR-12444   -  person Shailesh Vaishampayan    schedule 19.11.2014


Ответы (1)


Просто чтобы этот вопрос не попал в список без ответа - это действительно ошибка, и вы указали ее как SPR- 12444.

Это будет исправлено в Spring Framework 4.1.3.

В качестве побочного примечания я хотел бы указать, что если вы развертываете свое приложение с несколькими экземплярами, реестры сеансов не разделяются между экземплярами по умолчанию, поэтому это вызовет проблемы при отправке сообщения от Алисы (с сеансом к серверу №1) к bob (сеанс к серверу №2).

person Brian Clozel    schedule 23.11.2014
comment
Спасибо, Брайан, за дополнительную информацию. - person Shailesh Vaishampayan; 23.11.2014
comment
Привет, Брайан, меня интересует второй пункт вашего ответа, но я не понимаю, что вы имеете в виду. В приведенном вами примере отправляется сообщение типа simpMessagingTemplate.convertAndSend (/ user / + username + /queue/chat.message, message) ;. Чем это отличается от подхода, описанного в вопросе, где Джон отправляет сообщение Алисе через / user / alice / queue / messaging? - person Marios; 11.12.2014
comment
Да, извините за это - я вернусь к этому ответу с чем-то более точным. - person Brian Clozel; 11.12.2014