Header 在 Spring WebSocket 中使用 convertAndSendToUser 方法的问题

Header problems with use of convertAndSendToUser method in Spring WebSocket

我正在尝试使用 SimpMessageSendingOperationsSimpMessagingTemplate 直接向用户发送消息,但两者都不起作用。

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));

谢谢。