Affects: Spring 2.1.10.RELEASE
I'm trying to send a message directly to an user using SimpMessageSendingOperations
or SimpMessagingTemplate
but both doesn't work.
simpMessagingTemplate.convertAndSend("/user/" + userSessionId + "/queue/greetings", "Message One");
messagingTemplate.convertAndSendToUser(userSessionId, "/queue/greetings", "Message Two");
I already inspected the internal classes to understand the problem and seems to be the headers. For example, if I create a StompHeaderAccessor
and specially add any nativeHeaders
and also set the SessionId and send as the last parameter of convertAndSendToUser
it works.
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());
Because inside the SimpMessagingTemplate
class there is a method called processHeadersToSend
and if there is any Native headers it returns the same headers so in AbstractMessageSendingTemplate
class the type of headersToUse
variable changes to a HashMap and the behavior is different.
I also created a method annotated with @SendToUser
to understand the idea and the same behavior happens:
@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";
I'd like to know what I'm doing wrong or if I really need to always instantiate a HeaderAccessor and add any native headers to work?
Thanks in advance.
Comment From: guibernardi
Just to clarify I understand and solve my problem, I didn't pay attention to the JavaDoc description in processHeadersToSend
.
The convertAndSendToUser
accepts a Map<String, Object>
parameter as the headers, but correct is send a MessageHeaders
if I want to keep my own headers.
So I created a method:
private MessageHeaders createHeaders(String sessionId) {
SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor
.create(SimpMessageType.MESSAGE);
headerAccessor.setSessionId(sessionId);
headerAccessor.setLeaveMutable(true);
return headerAccessor.getMessageHeaders();
}
And call convertAndSendToUser
like this:
messagingTemplate.convertAndSendToUser(purchaseReport.getSessionId(),
"/queue/greetings",
payload,
createHeaders(sessionId));
Thanks.
Comment From: sbrannen
Glad you figured it out.
In light of that, I'll close this issue.
Thanks for the feedback.
Comment From: Royal520
thanks god
Comment From: Dilunder
Большое спасибо, это решение мне помогло! thx ❤️
Comment From: argestes
Just to clarify I understand and solve my problem, I didn't pay attention to the JavaDoc description in
processHeadersToSend
. TheconvertAndSendToUser
accepts aMap<String, Object>
parameter as the headers, but correct is send aMessageHeaders
if I want to keep my own headers.So I created a method:
``` private MessageHeaders createHeaders(String sessionId) { SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor .create(SimpMessageType.MESSAGE); headerAccessor.setSessionId(sessionId); headerAccessor.setLeaveMutable(true); return headerAccessor.getMessageHeaders();
} ```
And call
convertAndSendToUser
like this:
messagingTemplate.convertAndSendToUser(purchaseReport.getSessionId(), "/queue/greetings", payload, createHeaders(sessionId));
Thanks.
Thanks for putting this