Spring WebSockets ActiveMQ convertAndSendToUser

时间:2018-04-22 09:54:43

标签: spring spring-boot websocket activemq stomp

我有一个Spring Boot应用程序(Jhipster),它使用STOMP over WebSockets将信息从服务器传递给用户。

我最近添加了一个ActiveMQ服务器来处理水平扩展应用程序,使用亚马逊自动扩展组/负载均衡器。

我使用convertAndSendToUser()方法,该方法适用于应用的单个实例,以便找到经过身份验证的用户' "个人队列"所以只有他们收到消息。

但是,当我在负载均衡器后面启动应用程序时,我发现如果在服务器上生成了他们的websocket-proxy连接的事件,那么消息只发送给用户 经纪人)成立于?

如何确保消息通过ActiveMQ传递给用户实际连接的应用程序的任何实例"以及#34;无论哪个实例接收,比如执行convertAndSendToUser()事件的HTTP请求?

这里的参考是我的StompBrokerRelayMessageHandler:

@Bean
public AbstractBrokerMessageHandler stompBrokerRelayMessageHandler() {
    StompBrokerRelayMessageHandler handler = (StompBrokerRelayMessageHandler) super.stompBrokerRelayMessageHandler();
    handler.setTcpClient(new Reactor2TcpClient<>(
        new StompTcpFactory(orgProperties.getAws().getAmazonMq().getStompRelayHost(),
            orgProperties.getAws().getAmazonMq().getStompRelayPort(), orgProperties.getAws().getAmazonMq
            ().getSsl())
    ));

    return handler;
}

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
    config.enableStompBrokerRelay("/queue", "/topic")
        .setSystemLogin(orgProperties.getAws().getAmazonMq().getStompRelayHostUser())
        .setSystemPasscode(orgProperties.getAws().getAmazonMq().getStompRelayHostPass())
        .setClientLogin(orgProperties.getAws().getAmazonMq().getStompRelayHostUser())
        .setClientPasscode(orgProperties.getAws().getAmazonMq().getStompRelayHostPass());

    config.setApplicationDestinationPrefixes("/app");
}

我找到了与ActiveMQ上生成的队列对应的名称,方法是检查用户订阅用户队列时在监听器中生成的SessionSubscribeEvent中的标头,为{{1} }。

simpSessionId

相应的队列&#39;可在ActiveMQ中找到,格式为:@Override @EventListener({SessionSubscribeEvent.class}) public void onSessionSubscribeEvent(SessionSubscribeEvent event) { log.debug("Session Subscribe Event:" + "{}", event.getMessage().getHeaders().toString()); }

我可以将sessionId保存在键值对中,只是将消息推送到该主题频道吗?

我还在CONNECT / SUBSCRIBE框架中找到了一些possibilities设置ActiveMQ特定STOMP属性来创建持久订阅者如果我将这些属性设置为Spring而不是理解路由?

{simpDestination}-user{simpSessionId}&amp; client-id

1 个答案:

答案 0 :(得分:1)

修改MessageBrokerReigstry config解决了问题:

config.enableStompBrokerRelay("/queue", "/topic")
            .setUserDestinationBroadcast("/topic/registry.broadcast")

基于documentation section 4.4.13中的这一段:

  

在多应用程序服务器方案中,可以保留用户目标   未解决,因为用户已连接到其他服务器。在   在这种情况下,您可以将目标配置为未解析的广播   消息,以便其他服务器有机会尝试。这可以   通过userDestinationBroadcast属性完成   Java配置中的MessageBrokerRegistry和   message-broker元素的user-destination-broadcast属性   XML

我没有看到关于“为什么”/topic/registry.broadcast是正确的“主题”目的地的任何文档,但我发现了它的各种迭代:

  1. websocket sessions sample doesn't cluster.. spring-session-1.2.2
  2. What is MultiServerUserRegistry in spring websocket?
  3. Spring websocket - sendToUser from a cluster does not work from backup server