我正在尝试在 Spring 中使用 STOMP 在经过身份验证的用户之间发送消息。在客户端,我使用 STOMP.js。
控制器:
@MessageMapping("/hello")
@SendToUser("/queue/hello")
public HelloMsg hello(HelloMsg message) throws Exception {
System.out.println("Got message " + message.getMsg());
return new HelloMsg("Hello, " + HtmlUtils.htmlEscape(message.getMsg()));
}
WebSocket配置:
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.setApplicationDestinationPrefixes("/app");
config.enableSimpleBroker( "/queue");
config.setUserDestinationPrefix("/user");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/stomp").setAllowedOrigins("*");
}
对于用户,我的
SecurityConfig
中有这个:
@Bean
public UserDetailsService userDetailsService() {
final Properties users = new Properties();
users.put("sample1", passwordEncoder().encode("password")+",ROLE_USER,enabled");
users.put("sample2", passwordEncoder().encode("password")+",ROLE_USER,enabled");
return new InMemoryUserDetailsManager(users);
}
客户:
function handleSubmit(e) {
e.preventDefault()
stompClient.publish({
destination: "/user/"+friend+"/queue/hello",
body: JSON.stringify({"msg" : "hello there!"})
})
}
我希望在从控制器发送消息时看到控制器的打印 客户端,但什么也没有。
如果
@SendToUser("/queue/hello")
更改为 @SendTo("/app/hello")
并且
目的地在客户端中设置为 "/app/hello"
。消息已按预期发送给所有用户。
@SendToUser("/destination")
将为您的 /destination
加上 /user/{username}
前缀,其中 /user
是 userDestinationPrefix。如果消息中未找到 simpUser 标头,则将使用内部会话 ID。假设在您的情况下,消息标头中有用户主体,则在调用处理程序时,消息将被路由到 /user/{username}/queue/hello
。因此您必须在客户端中订阅/user/{username}/queue/hello
才能接收消息/app/hello
发送消息将调用您的消息处理程序。"/user/"+friend+"/queue/hello"
并且您在该路径中没有收到任何消息。如果是这种情况,请尝试将 "/user"
添加到enableSimpleBroker 方法参数中。