如何实现客户端订阅多台服务器的Spring WebSocket(SockJS/Stomp)推送?
问题解决步骤
1. 修复客户端变量引用错误
你当前代码存在变量名误用问题:创建stompClient1时错误引用了未定义的socket变量,实际应该使用对应的socket1;同理stompClient2要引用socket2,否则无法建立正确的连接。
2. 修正STOMP订阅路径
STOMP的订阅目的地是相对路径,不需要包含服务器完整URL。每个StompClient已经和对应服务器建立了专属连接,订阅时只需使用服务器配置中enableSimpleBroker声明的前缀路径(比如/topic/publish-updates)即可。
修正后的客户端代码
// 连接第一台服务器实例 var socket1 = new SockJS("http://cml-consumerinstance-ci-0000.com:8080/stomp-endpoint"); stompClient1 = Stomp.over(socket1); stompClient1.connect("", "", function (frame) { stompClient1.subscribe("/topic/publish-updates", function (publishedUpdates) { showMessages(JSON.parse(publishedUpdates.body)); }); }); // 连接第二台服务器实例 var socket2 = new SockJS("http://cml-consumerinstance-ci-1111.com:8080/stomp-endpoint"); stompClient2 = Stomp.over(socket2); stompClient2.connect("", "", function (frame) { stompClient2.subscribe("/topic/publish-updates", function (publishedUpdates) { showMessages(JSON.parse(publishedUpdates.body)); }); });
额外注意事项
如果你的需求是全局消息广播(任意服务器实例发送的消息,所有订阅者都能收到),仅用enableSimpleBroker无法实现——它是内存级代理,只能在单个实例内广播。此时需要配置外部消息代理(如RabbitMQ、Redis)实现多实例消息同步:
示例:配置Redis作为消息代理
- 添加Maven依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
- 修改WebSocket配置类:
@Override public void configureMessageBroker(MessageBrokerRegistry registry) { // 启用Redis中继代理,替换内存代理 registry.enableStompBrokerRelay("/topic", "/queue") .setRelayHost("你的Redis地址") .setRelayPort(6379) .setClientLogin("Redis用户名") .setClientPasscode("Redis密码"); registry.setApplicationDestinationPrefixes("/app"); }
配置完成后,所有服务器实例的消息会通过Redis同步,UI即使只订阅一个实例也能收到全量推送;如果需要分别获取每个实例的专属消息,保持修正后的客户端代码即可。
内容的提问来源于stack exchange,提问作者Om Sao
相关产品推荐
相关产品推荐

