我正在使用带有RabbitMQ代理的集群tomcat环境中使用Spring Websockets构建应用程序。我有一个API模块需要注册端点来监听。我按照正常的例子提出了这个配置:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer
{
@Override
public void configureMessageBroker(final MessageBrokerRegistry config)
{
config.enableStompBrokerRelay("/topic/")
.setRelayHost("localhost")
.setRelayPort(61613)
.setClientLogin("guest")
.setClientPasscode("guest");
}
@Override
public void registerStompEndpoints(final StompEndpointRegistry registry)
{
registry.addEndpoint("/updates")
.setAllowedOrigins("*")
.withSockJS();
}
}
虽然这有效,但它并没有解决我的问题,因为看起来WebSocket和中继配置都捆绑在API模块中,因此其他层无法重用代理。我需要在服务层进行stomp消息代理中继配置,以便我们应用程序的其他模块可以将消息推送到RabbitMQ中的主题,然后转向并通知API模块更新所有打开的websockets。
下面是我们的应用程序中相关层的示例图以及我要完成的任务。我需要允许模块" Cron Message Sender"通过我们的其他API模块将消息推送给订阅消息主题的每个人。
答案 0 :(得分:1)
所以第二种方法确实有效。我将websockets配置为独立运行(没有中继),然后我在服务层建立了一个单独的AMQP消息代理连接,以允许服务之间的通信。在API模块中,我只是听取了AMQP消息代理,然后手动将这些消息转发到通知websocket订阅者的 SimpMessagingTemplate 。我不确定这在技术上是否是“正确”的方式,但它似乎工作得很好,我还没有看到任何实施问题。事实上,我实际上认为我可能更喜欢这种方法,因为我现在只是让我的所有服务能够使用比我最初需要的websockets更多类型的消息来互相交流。
以下是新配置:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer
{
@Override
public void configureMessageBroker(final MessageBrokerRegistry config)
{
config.enableSimpleBroker("/topic");
}
@Override
public void registerStompEndpoints(final StompEndpointRegistry registry)
{
registry.addEndpoint("/updates")
.setAllowedOrigins("*")
.withSockJS();
}
}
这里是我收听消息代理并将消息转发给websocket订阅者的地方:
@Component
public class SendWebSocketUpdates
{
private static final Logger logger = LoggerFactory.getLogger(SendWebSocketUpdates.class);
private final Gson gson;
@Autowired
private SimpMessagingTemplate messagingTemplate;
@Autowired
private MessageBrokerConsumer<String> messageBrokerConsumer;
public SendWebSocketUpdates()
{
this.gson = new Gson();
}
@PostConstruct
public void init()
{
//listen for incoming AMQP messages from the rabbitmq server and forward them to the websocket subscribers
messageBrokerConsumer.addListener((message, topicName) -> {
final String destination = "/topic/" + topicName;
final String messageJson = gson.toJson(message.getBody());
//check to see if trace logging is enabled
if (logger.isTraceEnabled())
{
logger.trace("Sending Message to \"{}\": {}", destination, messageJson);
}
//broadcast the via a STOMP message to subscribers of this topic
messagingTemplate.convertAndSend(destination, messageJson);
});
}
}
答案 1 :(得分:-1)
解决此问题很容易。我浪费了一整天的时间来寻找解决方案。 Here 's my answer for the same problem。
密钥为setUserDestinationBroadcast
和setUserRegistryBroadcast
:
registry.enableStompBrokerRelay("/topic/", "/queue/", "/exchange/")
.setUserDestinationBroadcast("/topic/log-unresolved-user")
.setUserRegistryBroadcast("/topic/log-user-registry")