Spring WebSocket如何向特定用户发送消息?

9
我正在阅读书籍《Spring实战4》,以便使用WebSocket上的STOMP消息传递。
假设用户目标前缀设置为"/user"如下:
registry.setUserDestinationPrefix("/user");

然后客户端使用以下JavaScript代码订阅目标:

stomp.subscribe("/user/queue/notifications", handleNotifications);

然后在服务器上,客户端订阅的实际目标应该从其会话中推导出来,可能是这样的:

/queue/notifications-user6hr83v6t  --- (1)

然后我使用SimpMessagingTemplate向该用户发送消息:

messaging.convertAndSendToUser( username, "/queue/notifications",
                           new Notification("You just got mentioned!"));

然后,消息将会像这样发送到目的地:
/user/<username>/queue/notifications  ---(2)

好的,这两个目的地 (1)(2) 看起来不同,那么信息怎么才能到达客户端呢?

1个回答

7
路径
/user/<username>/queue/notifications 

看起来这是文档中使用的“逻辑”路径。它最初是使用 convertAndSendToUser 方法创建的。然后,在 UserDestinationMessageHandler 类中的该行代码中将其转换为技术格式。

UserDestinationResult result = this.destinationResolver.resolveDestination(message);

给定订阅:
stompClient.subscribe('/user/queue/reply', function (greeting) { ...

使用以下步骤发送消息:

stompClient.send("/app/personal", ...

拦截并截取它。
@MessageMapping("/personal")
public void personalMessage(SimpMessageHeaderAccessor headerAccessor, PoCRequestMessage message) {

    SimpMessageHeaderAccessor ha = SimpMessageHeaderAccessor
            .create(SimpMessageType.MESSAGE);
    ha.setSessionId(headerAccessor.getSessionId());
    ha.setLeaveMutable(true);
    PoCReplyMessage reply = new PoCReplyMessage("Personal Message" + message.getName());
    simpMessagingTemplate.convertAndSendToUser(headerAccessor.getSessionId(), "/queue/reply", reply, ha.getMessageHeaders());
}

目标地址将按以下方式解析:
source destination: /user/zojdn53y/queue/reply
target destination: /queue/reply-userzojdn53y

这是最终目的地名称如何解析的过程。 目标目的地是创建的队列的实际名称(至少在使用外部消息代理时是这样 - 对于简单的内存代理,我没有检查这一点,但我认为情况应该是相同的)。
需要注意的一件重要事情是:当您想使用未经身份验证的用户(通常在尝试WebSocket时)时,您需要额外将消息头放入convertAndSendToUser方法中 - 这在Spring WebSocket @SendToSession: send message to specific session中有详细说明。

用户目标结果成功创建后,我的订阅者列表在某个时点为空,因此消息无法发送。有任何想法吗?我在这里提出了同样的SO问题-https://stackoverflow.com/questions/49482735/cannot-send-messages-to-unauthenticated-users-using-springstompsockjs - mns
谢谢 - 这终于帮了我 - 在看了很多不同的东西之后...现在只要我能让@SendToUser注释起作用就好了... - Jeef
是的,我做到了(终于)。 - Jeef
那么,当用户(第1人称)向另一个用户(第2人称)发送消息并且另一个用户(第2人称)订阅此端点时,我们如何防止第3方能够订阅此端点呢? - ZootHii

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接