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 add SessionId header 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 what I'm doing wrong or I really need to always instantiate a HeaderAccessor and add any native headers to work?
Thanks in advance.
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.