Header 在 Spring WebSocket 中使用 convertAndSendToUser 方法的问题
Header problems with use of convertAndSendToUser method in Spring WebSocket
我正在尝试使用 SimpMessageSendingOperations
或 SimpMessagingTemplate
直接向用户发送消息,但两者都不起作用。
simpMessagingTemplate.convertAndSend("/user/" + userSessionId + "/queue/greetings", "Message One");
messagingTemplate.convertAndSendToUser(userSessionId, "/queue/greetings", "Message Two");
我已经检查了内部 classes 以了解问题,似乎是 headers。
例如,如果我创建一个 StompHeaderAccessor
并专门添加任何 nativeHeaders
并添加 SessionId header 并将其作为 convertAndSendToUser
的最后一个参数发送。
StompHeaderAccessor headerAccessor = StompHeaderAccessor.create(StompCommand.SEND);
headerAccessor.setSessionId(purchaseReport.getSessionId());
headerAccessor.setNativeHeader("Any header", "Any header");
messagingTemplate.convertAndSendToUser(purchaseReport.getSessionId(), "/queue/greetings", "Message Two", headerAccessor.toMap());
因为在 SimpMessagingTemplate
class 里面有一个叫做 processHeadersToSend
的方法,如果有 Native header 它 returns 一样 headers 所以在 AbstractMessageSendingTemplate
class 中 headersToUse
变量的类型更改为 HashMap 并且行为不同。
我还创建了一个用 @SendToUser
注释的方法来理解这个想法,同样的行为发生了:
@MessageMapping({ "/hello/{id}/websocket" })
@SendToUser(value = "/queue/greetings")
String generate(@DestinationVariable Integer id, @Payload Report report,
SimpMessageHeaderAccessor headerAccessor) throws Exception {
messagingTemplate.convertAndSendToUser(headerAccessor.getHeader("simpSessionId").toString(),
"/queue/greetings", "This message doesn't work");
messagingTemplate.convertAndSendToUser(headerAccessor.getHeader("simpSessionId").toString(),
"/queue/greetings", "This one works because have native headers", headerAccessor.toMap());
return "This one send by annotation works too";
我想知道我做错了什么,或者我真的需要始终实例化 HeaderAccessor 并添加任何本机 headers 才能工作?
提前致谢。
我理解并解决了我的问题,我没有注意processHeadersToSend
中的JavaDoc描述。
convertAndSendToUser
接受 Map<String, Object>
参数作为 headers,但如果我想保留自己的 headers,正确的做法是发送 MessageHeaders
。
所以我创建了一个方法:
private MessageHeaders createHeaders(String sessionId) {
SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor
.create(SimpMessageType.MESSAGE);
headerAccessor.setSessionId(sessionId);
headerAccessor.setLeaveMutable(true);
return headerAccessor.getMessageHeaders();
}
然后这样调用 convertAndSendToUser
:
messagingTemplate.convertAndSendToUser(purchaseReport.getSessionId(),
"/queue/greetings",
payload,
createHeaders(sessionId));
谢谢。
我正在尝试使用 SimpMessageSendingOperations
或 SimpMessagingTemplate
直接向用户发送消息,但两者都不起作用。
simpMessagingTemplate.convertAndSend("/user/" + userSessionId + "/queue/greetings", "Message One");
messagingTemplate.convertAndSendToUser(userSessionId, "/queue/greetings", "Message Two");
我已经检查了内部 classes 以了解问题,似乎是 headers。
例如,如果我创建一个 StompHeaderAccessor
并专门添加任何 nativeHeaders
并添加 SessionId header 并将其作为 convertAndSendToUser
的最后一个参数发送。
StompHeaderAccessor headerAccessor = StompHeaderAccessor.create(StompCommand.SEND);
headerAccessor.setSessionId(purchaseReport.getSessionId());
headerAccessor.setNativeHeader("Any header", "Any header");
messagingTemplate.convertAndSendToUser(purchaseReport.getSessionId(), "/queue/greetings", "Message Two", headerAccessor.toMap());
因为在 SimpMessagingTemplate
class 里面有一个叫做 processHeadersToSend
的方法,如果有 Native header 它 returns 一样 headers 所以在 AbstractMessageSendingTemplate
class 中 headersToUse
变量的类型更改为 HashMap 并且行为不同。
我还创建了一个用 @SendToUser
注释的方法来理解这个想法,同样的行为发生了:
@MessageMapping({ "/hello/{id}/websocket" })
@SendToUser(value = "/queue/greetings")
String generate(@DestinationVariable Integer id, @Payload Report report,
SimpMessageHeaderAccessor headerAccessor) throws Exception {
messagingTemplate.convertAndSendToUser(headerAccessor.getHeader("simpSessionId").toString(),
"/queue/greetings", "This message doesn't work");
messagingTemplate.convertAndSendToUser(headerAccessor.getHeader("simpSessionId").toString(),
"/queue/greetings", "This one works because have native headers", headerAccessor.toMap());
return "This one send by annotation works too";
我想知道我做错了什么,或者我真的需要始终实例化 HeaderAccessor 并添加任何本机 headers 才能工作?
提前致谢。
我理解并解决了我的问题,我没有注意processHeadersToSend
中的JavaDoc描述。
convertAndSendToUser
接受 Map<String, Object>
参数作为 headers,但如果我想保留自己的 headers,正确的做法是发送 MessageHeaders
。
所以我创建了一个方法:
private MessageHeaders createHeaders(String sessionId) {
SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor
.create(SimpMessageType.MESSAGE);
headerAccessor.setSessionId(sessionId);
headerAccessor.setLeaveMutable(true);
return headerAccessor.getMessageHeaders();
}
然后这样调用 convertAndSendToUser
:
messagingTemplate.convertAndSendToUser(purchaseReport.getSessionId(),
"/queue/greetings",
payload,
createHeaders(sessionId));
谢谢。