Как отправить сообщение на указанную c подписку через весенний веб-сокет STOMP? - PullRequest
0 голосов
/ 02 марта 2020

Я использую STOMP поверх веб-сокетов с пружинной загрузкой. Есть ли возможность отправить сообщение на указанную c подписку? Я подписываюсь на конечные точки STOMP, используя заголовок STOMP, содержащий поле id в соответствии с документацией stomp Я хочу, чтобы этот идентификатор использовался для определения клиентов, которые должны получить сообщение, но весна Кажется, не использовать этот идентификатор. Я не могу просто использовать sendToUser , потому что два клиента могут иметь один и тот же идентификатор пользователя, например, если у пользователя два открытых браузера windows. Только одно указанное c окно должно получить сообщение.

В следующем примере у меня есть два подключенных клиента, которые используют одного и того же пользователя, но разные идентификаторы в заголовке STOMP.

Client1- ID: a32d66bf-03c7-47a4-aea0-e464c0727842

Client2-ID: b3673d33-1bf2-461e-8df3-35b7af07371b

Весной я выполнил следующий Kotlin код:

val subscriptions =  userRegistry.findSubscriptions {
            it.destination == "/user/topic/operations/$operationId/runs"
        }
        subscriptions.forEach{
            println("subscription id: ${it.id}");
            println("session id: ${it.session.id}");
            println("user id ${it.session.user.name}");
        }

Вывод:

subscription id: sub-7
session id: mcjpgn2i
user id 4a27ef88-25eb-4175-a872-f46e7b9d0564
subscription id: sub-7
session id: 0dxuvjgp
user id 4a27ef88-25eb-4175-a872-f46e7b9d0564

Нет никаких признаков идентификатора, который я передал в заголовок топа.

Можно ли отправить сообщение одной указанной подписке c, определенной по идентификатору, который я передал с заголовком?

1 Ответ

0 голосов
/ 03 марта 2020

Я получил это работает.

Прежде всего, что-то не так с моей настройкой клиента. Я установил идентификатор подписки в заголовке соединения следующим образом:

this.stompClient.webSocketFactory = (): WebSocket => new SockJS("/ws");
this.stompClient.connectHeaders = { id: subscriptionId };
this.stompClient.activate();

Но заголовок подписки должен быть установлен в заголовке подписки:

this.stompClient.subscribe(this.commonEndpoint,
        this.onMessageReceived.bind(this),
        { id: subScriptionId });

Если я это сделаю, весна правильно использует этот идентификатор в качестве идентификатора подписки, вместо использования некоторых по умолчанию, таких как sub-7 .

В соответствии с этим поток Я могу отправлять сообщения на указанный c сеансы вместо пользователя.

С помощью следующего кода я могу отправить сообщение на указанную c подписку:

val subscriptions = userRegistry.findSubscriptions {
            it.destination == "/user/topic/operations/$operationId/runs"
        }
subscriptions.forEach {
    if(it.id === mySubscriptionId){
        val headerAccessor = 
        SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE)
        headerAccessor.sessionId = it.session.id
        headerAccessor.setLeaveMutable(true)

        simpMessagingTemplate.convertAndSendToUser(it.session.id,  
            "/topic/operations/runs", messageResponseEntity,
            headerAccessor.getMessageHeaders())

     }
}
...