如何通过spring websocket STOMP向特定订阅发送消息? [英] How to send message to a specific subscription over spring websocket STOMP?
问题描述
我在带有弹簧靴的 websockets 上使用 STOMP.是否可以向特定订阅发送消息?我根据 id 字段的 STOMP 标头订阅 STOMP 端点="nofollow noreferrer">stomp 文档 我希望使用此 id 来确定应该接收消息的客户端,但 spring 似乎不使用此 id.我不能只使用 sendToUser 因为两个客户端可以具有相同的用户 ID,例如如果用户打开了两个浏览器窗口.只有一个特定的窗口应该收到消息.
I am using STOMP over websockets with spring boot. Is there a possibility to send a message to a specific subscription? I subscribe to the STOMP endpoints using a STOMP header containing an id field according to the stomp documentation I want this id to be used to determine the clients who should receive a message, but spring seems not to use this id. I can not just use sendToUser because two clients can have the same user id e.g. if a user has two opened browser windows. Only one specific window should receive the message.
在以下示例中,我有两个连接的客户端,它们使用相同的用户,但 STOMP 标头中的 ID 不同.
In the following example I have two connected clients which are using the same user, but different ids in the STOMP header.
Client1-ID:a32d66bf-03c7-47a4-aea0-e464c0727842
Client1-ID: a32d66bf-03c7-47a4-aea0-e464c0727842
Client2-ID:b3673d33-1bf2-461e-8df3-35b7af07371b
Client2-ID: b3673d33-1bf2-461e-8df3-35b7af07371b
在春季,我执行了以下 Kotlin 代码:
In spring I have executed the following Kotlin code:
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
没有迹象表明我已传递给 stomp 标头.
There is no sign of the id I have passed to the stomp header.
是否可以将消息发送到由我随标题传递的 id 确定的特定订阅?
Is it possible to send a message to one specific subscription determined by the id I have passed with the header?
推荐答案
我搞定了.
首先,我的客户端设置有问题.我在连接头中设置了订阅 ID,如下所示:
First of all, there was something wrong with my client setup. I have set the subscription id in the connection header like this:
this.stompClient.webSocketFactory = (): WebSocket => new SockJS("/ws");
this.stompClient.connectHeaders = { id: subscriptionId };
this.stompClient.activate();
但是订阅头必须在订阅头中设置:
But the subscription header has to be set in the subscription header:
this.stompClient.subscribe(this.commonEndpoint,
this.onMessageReceived.bind(this),
{ id: subScriptionId });
如果我这样做,spring 就会正确地使用这个 id 作为订阅 id,而不是使用一些像 sub-7 这样的默认值.
If I do this, spring is correctly using this id as the subscription id, instead of using some default like sub-7.
根据那个线程,我可以向特定会话而不是用户发送消息.
According to that thread I can send messages to specific sessions instead of user.
使用以下代码,我可以向特定订阅发送消息:
With the following code I can send a message to a specific subscription:
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())
}
}
这篇关于如何通过spring websocket STOMP向特定订阅发送消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!