Spring WebSockets ActiveMQ convertAndSendToUser
Spring WebSockets ActiveMQ convertAndSendToUser
我有一个 Spring 启动应用程序 (Jhipster),它使用 STOMP over WebSockets 将信息从服务器传递给用户。
我最近添加了一个 ActiveMQ 服务器来处理水平缩放应用程序,使用 Amazon auto-scaling 组/load-balancer。
我使用 convertAndSendToUser()
方法,该方法适用于应用程序的单个实例来定位经过身份验证的用户的 "individual queue",因此只有他们会收到消息。
但是,当我在负载均衡器后面启动应用程序时,我发现如果事件是在他们的websocket-proxy 连接(到代理)建立于?
我如何确保消息通过 ActiveMQ 到达用户实际 "connected too" 的任何应用程序实例,而不管哪个实例收到,比如执行 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");
}
我通过检查 SessionSubscribeEvent
中的 headers 找到了在 ActiveMQ 上生成的 queue 对应的名称,该名称是在用户订阅时在侦听器中生成的一个 user-queue,作为 simpSessionId
.
@Override
@EventListener({SessionSubscribeEvent.class})
public void onSessionSubscribeEvent(SessionSubscribeEvent event) {
log.debug("Session Subscribe Event:" +
"{}", event.getMessage().getHeaders().toString());
}
对应的queue可以在ActiveMQ中找到,格式为:{simpDestination}-user{simpSessionId}
我可以将 sessionId 保存在 key-value 对中,然后将消息推送到该主题频道吗?
我还发现一些 possibilities 在 CONNECT/SUBSCRIBE 框架中设置 ActiveMQ 特定的 STOMP 属性来创建 持久订阅者 如果我设置这些属性将 Spring比懂路由?
client-id
& subcriptionName
修改 MessageBrokerReigstry config
解决了问题:
config.enableStompBrokerRelay("/queue", "/topic")
.setUserDestinationBroadcast("/topic/registry.broadcast")
基于documentation section 4.4.13中的这段:
In a multi-application server scenario a user destination may remain
unresolved because the user is connected to a different server. In
such cases you can configure a destination to broadcast unresolved
messages to so that other servers have a chance to try. This can be
done through the userDestinationBroadcast property of the
MessageBrokerRegistry in Java config and the
user-destination-broadcast attribute of the message-broker element in
XML
我没有看到任何关于 "why" 的文档 /topic/registry.broadcast
是正确的 "topic" 目的地,但我发现了它的各种迭代:
- websocket sessions sample doesn't cluster.. spring-session-1.2.2
- What is MultiServerUserRegistry in spring websocket?
- Spring websocket - sendToUser from a cluster does not work from backup server
我有一个 Spring 启动应用程序 (Jhipster),它使用 STOMP over WebSockets 将信息从服务器传递给用户。
我最近添加了一个 ActiveMQ 服务器来处理水平缩放应用程序,使用 Amazon auto-scaling 组/load-balancer。
我使用 convertAndSendToUser()
方法,该方法适用于应用程序的单个实例来定位经过身份验证的用户的 "individual queue",因此只有他们会收到消息。
但是,当我在负载均衡器后面启动应用程序时,我发现如果事件是在他们的websocket-proxy 连接(到代理)建立于?
我如何确保消息通过 ActiveMQ 到达用户实际 "connected too" 的任何应用程序实例,而不管哪个实例收到,比如执行 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");
}
我通过检查 SessionSubscribeEvent
中的 headers 找到了在 ActiveMQ 上生成的 queue 对应的名称,该名称是在用户订阅时在侦听器中生成的一个 user-queue,作为 simpSessionId
.
@Override
@EventListener({SessionSubscribeEvent.class})
public void onSessionSubscribeEvent(SessionSubscribeEvent event) {
log.debug("Session Subscribe Event:" +
"{}", event.getMessage().getHeaders().toString());
}
对应的queue可以在ActiveMQ中找到,格式为:{simpDestination}-user{simpSessionId}
我可以将 sessionId 保存在 key-value 对中,然后将消息推送到该主题频道吗?
我还发现一些 possibilities 在 CONNECT/SUBSCRIBE 框架中设置 ActiveMQ 特定的 STOMP 属性来创建 持久订阅者 如果我设置这些属性将 Spring比懂路由?
client-id
& subcriptionName
修改 MessageBrokerReigstry config
解决了问题:
config.enableStompBrokerRelay("/queue", "/topic")
.setUserDestinationBroadcast("/topic/registry.broadcast")
基于documentation section 4.4.13中的这段:
In a multi-application server scenario a user destination may remain unresolved because the user is connected to a different server. In such cases you can configure a destination to broadcast unresolved messages to so that other servers have a chance to try. This can be done through the userDestinationBroadcast property of the MessageBrokerRegistry in Java config and the user-destination-broadcast attribute of the message-broker element in XML
我没有看到任何关于 "why" 的文档 /topic/registry.broadcast
是正确的 "topic" 目的地,但我发现了它的各种迭代:
- websocket sessions sample doesn't cluster.. spring-session-1.2.2
- What is MultiServerUserRegistry in spring websocket?
- Spring websocket - sendToUser from a cluster does not work from backup server