Stomp over WebSocket连接已建立但消息无法送达服务器求助
问题:Spring WebSocket + Stomp客户端消息无法送达服务端
客户端基于WebSocket/SockJS、服务端采用spring-websocket实现聊天功能,连接已成功建立,但发送消息后服务端处理方法无日志输出,消息未送达。以下是相关代码及日志:
客户端代码
import Stomp from 'stompjs'; ... function connect() { var socket = new WebSocket('ws://localhost:8080/chat', "v10.stomp"); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { setConnected(true); console.log('Connected: ' + frame); stompClient.subscribe('/topic/greeting', function(messageOutput) { console.log(messageOutput.body); showMessageOutput(JSON.parse(messageOutput.body)); }); }); } function sendMessage() { let message = JSON.stringify({"from":"User1", "messageBody":"Connected", "to":""}); console.log(message); stompClient.send("app/greeting", {}, message); // 尝试改成topic/greeting也无效果 } ...
客户端package.json依赖
"devDependencies": { "css-loader": "^6.7.2", "postcss-loader": "^7.0.2", "sass": "^1.56.1", "sass-loader": "^13.2.0", "style-loader": "^3.3.1", "webpack": "^5.75.0", "webpack-cli": "^5.0.1", "webpack-dev-server": "^4.11.1" }, "main": "webpack.config.js", "description": "", "dependencies": { "bootstrap": "^5.2.3", "html-webpack-plugin": "^5.5.0", "jquery": "^3.6.1", "net": "^1.0.2", "sockjs-client": "^1.6.1", "stomp-websocket": "^2.3.4-next", "stompjs": "^2.3.3", "websocket": "^1.0.34" }
服务端代码
WebSocketController
@RequiredArgsConstructor @Controller @Slf4j class WebSocketController { private static final Map<String, String> userToSessionMap = new ConcurrentHashMap<>(); SimpMessagingTemplate simpMessagingTemplate; @MessageMapping("/greeting") public void addUserAndNotifyOthers(@Header("simpSessionId") String sessionId, @Payload Message initialMessage) { userToSessionMap.put(initialMessage.getFrom(), sessionId); log.warn(initialMessage.toString()); // 从未输出此日志 simpMessagingTemplate.convertAndSend("topic/greeting", initialMessage); } ... }
Message实体类
@Data @AllArgsConstructor public class Message { String to; String from; String messageBody; }
WebSocket配置类
@Configuration @EnableWebSocketMessageBroker public class WebsocketConfiguration implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/chat").setAllowedOrigins("http://localhost:5000"); registry.addEndpoint("/chat").setAllowedOrigins("http://localhost:5000").withSockJS(); } @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/topic", "/queue"); registry.setApplicationDestinationPrefixes("/app"); } }
客户端日志
Web Socket Opened... stomp.js:134:104 >>> CONNECT accept-version:1.1,1.0 heart-beat:10000,10000 � stomp.js:134:104 <<< CONNECTED version:1.1 heart-beat:0,0 � stomp.js:134:104 connected to server undefined stomp.js:134:104 Connected: CONNECTED heart-beat:0,0 version:1.1 index.js:32:17 >>> SUBSCRIBE id:sub-0 destination:/topic/greeting � stomp.js:134:104 SENDING: {"from":"User1","messageBody":"Connected","to":""} index.js:54:13 >>> SEND destination:topic/greeting content-length:50 {"from":"User1","messageBody":"Connected","to":""}� // 日志结束:从未收到服务端接收日志
问题分析与修复方案
核心问题
- 发送路径错误:服务端配置了
setApplicationDestinationPrefixes("/app"),意味着客户端发送到控制器方法的路径必须是/app/greeting,但日志显示实际发送的是topic/greeting——这个路径会直接被消息代理处理,不会走到你的控制器方法。 - 代码与日志不符:代码中写的是
app/greeting,但日志里是topic/greeting,说明要么代码未更新生效,要么有其他逻辑覆盖了发送目标;同时代码中的路径缺少开头的斜杠,Stomp客户端会将相对路径错误拼接。 - 依赖冲突:客户端同时引入
stompjs和stomp-websocket,两个库功能重叠,可能导致异常行为。
修复步骤
- 修正发送路径:确保使用完整的带前缀路径,添加开头的斜杠:
stompClient.send("/app/greeting", {}, message);
- 清理依赖冲突:删除
stomp-websocket依赖,仅保留stompjs:
// package.json dependencies中移除以下行 "stomp-websocket": "^2.3.4-next",
确保代码生效:重新编译打包客户端代码,避免旧代码缓存导致的路径错误。
可选:完善消息实体:给
Message类添加无参构造器,避免Spring反序列化空字符串to字段时失败:
@Data @AllArgsConstructor @NoArgsConstructor public class Message { String to; String from; String messageBody; }
验证
修复后,客户端发送日志应显示:
>>> SEND destination:/app/greeting content-length:50 {"from":"User1","messageBody":"Connected","to":""}
此时服务端log.warn(initialMessage.toString())会正常输出日志,消息成功送达。
内容的提问来源于stack exchange,提问作者BJagger
相关产品推荐
相关产品推荐

