Spring Stomp @SubscribeMapping适用于用户目标

4

我想在用户使用@SubscribeMapping注释订阅stomp用户目标时得到通知。我的想法是在其加入时发送一些初始化数据。

尽管我无法使其正常工作:

Javascript:

stompClient.subscribe('/user/monitor', function(msg) {
            console.log(msg);    
        });

Java方面:

@SubscribeMapping("/monitor-user{clientId}")
public void init(@DestinationVariable("clientId") String clientId) {
    messagingTemplate.convertAndSend("/user/" + clientId + "/monitor", getOps());
}

我尝试了很多映射组合,比如 "/user/monitor-{clientId}", "/user/monitor" (移除clientId),但都没有成功。

请问预期的映射值是什么,这样才能被调用呢?

谢谢!


1
你能否重新表达一下你的问题?你想要实现什么用例呢? 用例1:当用户Alice订阅目标“/foobar”时,你希望发送一条消息到“/monitor”主题,这是一个专门用于监控目的的特殊主题,每当用户订阅“/foobar”时都会接收到一条消息。 用例2:当Alice订阅“/foobar”时,你想立即向她发送初始化数据。 - Brian Clozel
1个回答

14

由于客户端订阅了"/user/monitor"队列,因此服务器的@SubscribeMapping注释必须是针对"/user/monitor"而不是"/user/monitor{something}"。

服务器可以根据您的身份验证方案来理解客户端。如果您使用sockjs websocket,则可以使用HTTP身份验证,并且利用Spring Security,在函数中添加一个"Principal"参数,它将保存用户信息:

@SubscribeMapping("/monitor")
public void init(Principal p) {
    String user = p.getName();
    messagingTemplate.convertAndSendToUser(user, "/monitor", getOps());
}

如果您不使用HTTP身份验证,您可以发送用户信息给服务器,例如添加一个自定义的STOMP头,可通过SimpMessageHeaderAccessor从服务器访问:

@SubscribeMapping("/monitor")
public void init(SimpMessageHeaderAccessor accessor) {
    String user = accessor.getFirstNativeHeader("userid");
    messagingTemplate.convertAndSendToUser(user, "/monitor", getOps());
}

另一种方法可能是订阅包含用户信息的不同队列名称(也许这是您的建议)。客户端必须使用类似于以下代码:

另一种方法可以是订阅包含用户信息的不同队列名称(也许这是你的建议)。客户端必须使用类似于以下代码:
stompClient.subscribe('/topic/byUser/'+userId, function(msg) {
    console.log(msg);    
});

这样服务器就可以通过这种方式访问它:

@SubscribeMapping("/byUser/{userId}")
public void init(@DestinationVariable String userId) {
    messagingTemplate.convertAndSendToUser(userId, "/monitor", getOps());
}

但是请记住,在这种情况下,队列是公共的,因此其他客户端如果知道其他客户端的名称,就可以访问其消息。


1
在您的第二个代码示例中,convertAndSendToUser() 方法将转换对 /user/{userId}/monitor 的调用。Spring 知道如何从 Principal 名称找到连接,但它如何从一个它从未知道的自定义标头中找到连接呢? - Joffrey
仅供参考,一些外部代理(如RabbitMQ)不支持在/topic/*后面添加斜杠。例如,/topic/custom/subcustom是无效的,我必须将它们更改为/topic/custom.subcustom - Tobia

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