Spring websockets:消息未发布

Posted

技术标签:

【中文标题】Spring websockets:消息未发布【英文标题】:Spring websockets: message not published 【发布时间】:2016-05-20 11:36:20 【问题描述】:

我将 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后端,方法名称

createPublishAccount("Carlos");

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

这是我的网络配置:

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

【问题讨论】:

具有 createPublishAccount 方法的类是否被 Spring 实例化? 似乎不可能通过调用@SendTo注解的方法来发送消息。使用SimpMessagingTemplate 可以吗? 当然。见docs.spring.io/spring/docs/current/spring-framework-reference/… @Jakub Bibro 感谢 SimpMessagingTemplate 的作品。如果您可以以描述性方式和代码示例更新您的答案。我会接受的 【参考方案1】:

调用@SendTo 注解的方法似乎无法发送消息。

Spring推荐的消息发送方式是使用SimpMessagingTemplate。例如在convertAndSendToUser 方法(http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/messaging/simp/SimpMessagingTemplate.html)中,可以将目标作为参数(在您的情况下为/topic/accounts)。

请参阅 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 security 的 Principal 名称。有关详细信息,请参阅docs.spring.io/spring-security/site/docs/current/reference/html/…。所以spring根据队列名称和主体名称,将其转换为特定的队列名称,消息将传递给特定的用户。 我的应用不使用身份验证,在这种情况下我还能使用 Spring Security 吗?也许每次建立 websocket 连接时,我都需要在客户端默默地生成一个随机用户名? 是的,你可以在你的项目中添加spring security,因为你需要确保用户只接收自己的消息。请参阅 docs.spring.io/spring/docs/current/spring-framework-reference/… 和 docs.spring.io/spring/docs/current/spring-framework-reference/…。 “Spring 的 STOMP WebSocket 支持期望用户已经通过 HTTP 进行了身份验证”。但公平地说,有一个选项可以通过 websocket 会话以某种方式区分用户。很大程度上取决于您要解决的问题。 谢谢我通过简单的 /topic/balance/$pageContext.session.id 解决了这个问题,并将会话 ID 附加到所有帐户

以上是关于Spring websockets:消息未发布的主要内容,如果未能解决你的问题,请参考以下文章

Spring(Grails)WebSocket 立即记录错误:SubProtocolWebSocketHandler - *** ms 后未收到消息

从 Tomcat 9 到客户端的 Websocket 二进制消息拆分为 2 个或更多 tcp 数据包

RabbitMQ WebSocket 404 未找到

Websocket客户端未收到任何消息

Spring:向 websocket 客户端发送消息

Spring 4 - websocket 消息传递 stomp 处理程序