我正在通过Spring Boot在Websocket上使用STOMP。是否可以向特定订阅发送消息?我根据stomp documentation使用包含 id 字段的STOMP标头订阅了STOMP端点,我希望使用此ID来确定应接收消息的客户端,但是spring似乎不是使用这个ID。我不能只使用 sendToUser ,因为两个客户端可以具有相同的用户ID,例如如果用户有两个打开的浏览器窗口。只有一个特定的窗口应该收到该消息。
在下面的示例中,我有两个连接的客户端,它们使用相同的用户,但STOMP标头中的ID不同。
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
我没有传递给stomp标头的ID的迹象。
是否可以将消息发送到一个由我与标头一起传递的ID确定的特定订阅?
答案 0 :(得分:0)
我知道了。
首先,我的客户端设置有问题。我已经在连接头中设置了订阅ID,如下所示:
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 });
如果我这样做,spring会正确地使用此ID作为订阅ID,而不是使用 sub-7 之类的默认值。
根据thread,我可以将消息发送到特定的会话,而不是用户。
使用以下代码,我可以向特定的订阅发送消息:
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())
}
}