Spring WebSockets:消息未发布

5

我使用Spring WebSockets、STOMP和SockJS来处理前端的相关内容。虽然它工作得不错,但我还遇到了一些困难。

这是后端代码:

 @MessageMapping("/showAccountlist")
 @SendTo("/topic/accounts")
 public Account createPublishAccount(String name) throws Exception {

     return new Account(name);
 }

这是前端代码,完全正常运行,所有消息都会发布到所有客户端。

 stompClient.send("/app/showAccountlist", {}, name);

但是当我从Java后端调用我的后端方法时,方法名称为:from
createPublishAccount("Carlos");

似乎消息没有被发布。有什么解决方法吗?或者这不是它的工作方式,只有在通过SockJS触发时才起作用?

这是我的webconfig:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer  {

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
    config.enableSimpleBroker("/topic");
    config.setApplicationDestinationPrefixes("/app");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/showAccountlist").withSockJS();
}

}


Spring是否实例化了具有createPublishAccount方法的类? - Jakub Bibro
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Jakub Bibro
当然。请参阅http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-stomp-handle-send - Jakub Bibro
@Jakub Bibro 谢谢,SimpMessagingTemplate起作用了。如果你能以描述方式并提供代码示例更新你的答案,我会接受它。 - Spring
1个回答

6
似乎无法通过调用@SendTo注释方法来发送消息。
Spring推荐的发送消息方式是使用SimpMessagingTemplate。例如在convertAndSendToUser方法中,可以将目标作为参数(在您的情况下为/topic/accounts)(http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/messaging/simp/SimpMessagingTemplate.html)。
请参阅Spring文档摘录(http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-stomp-handle-send):
“如果您想从应用程序的任何部分向已连接的客户端发送消息怎么办?任何应用程序组件都可以向“brokerChannel”发送消息。最简单的方法是注入SimpMessagingTemplate,并使用它发送消息。通常,按类型注入应该很容易,例如:”
@Controller
public class GreetingController {

    private SimpMessagingTemplate template;

    @Autowired
    public GreetingController(SimpMessagingTemplate template) {
        this.template = template;
    }

    @RequestMapping(path="/greetings", method=POST)
    public void greet(String greeting) {
        String text = "[" + getTimestamp() + "]:" + greeting;
        this.template.convertAndSend("/topic/greetings", text);
    }

}  

谢谢,20小时内将接受赏金。我有一个问题。方法“convertAndSend”还接受参数“user”,以向特定用户发送消息。但是我无法弄清楚如何使用它。这里的用户是什么?如果某个账户收到了钱,我需要在客户端更新余额信息。 - Spring
这适用于Spring Security中的Principal名称。请参见http://docs.spring.io/spring-security/site/docs/current/reference/html/websocket.html#websocket-authentication获取更多详细信息。因此,基于队列名称和Principal名称,Spring将其转换为特定的队列名称,并将消息传递给特定的用户。 - Jakub Bibro
我的应用程序不使用身份验证,这种情况下我还能使用Spring Security吗?也许我需要在客户端每次建立WebSocket连接时静默地生成一个随机用户名? - Spring
1
是的,您可以将Spring安全性添加到您的项目中,因为您需要确保用户只接收自己的消息。请参见http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-stomp-authentication和http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-stomp-user-destination。“Spring的STOMP WebSocket支持期望用户已通过HTTP进行身份验证”。但是,据我所知,有一种方法可以通过WebSocket会话来区分用户。很多取决于您试图解决什么问题。 - Jakub Bibro
但是你可以例如在前端网站上生成一些用户标识,订阅“用户”队列,并在以后使用它来向该用户发送消息。 - Jakub Bibro
1
谢谢,我通过简单地使用/topic/balance/${pageContext.session.id}并将会话ID附加到所有帐户上来解决了这个问题。 - Spring

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