You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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":""}�
// 日志结束:从未收到服务端接收日志

问题分析与修复方案

核心问题

  1. 发送路径错误:服务端配置了setApplicationDestinationPrefixes("/app"),意味着客户端发送到控制器方法的路径必须是/app/greeting,但日志显示实际发送的是topic/greeting——这个路径会直接被消息代理处理,不会走到你的控制器方法。
  2. 代码与日志不符:代码中写的是app/greeting,但日志里是topic/greeting,说明要么代码未更新生效,要么有其他逻辑覆盖了发送目标;同时代码中的路径缺少开头的斜杠,Stomp客户端会将相对路径错误拼接。
  3. 依赖冲突:客户端同时引入stompjs和stomp-websocket,两个库功能重叠,可能导致异常行为。

修复步骤

  1. 修正发送路径:确保使用完整的带前缀路径,添加开头的斜杠:
stompClient.send("/app/greeting", {}, message);
  1. 清理依赖冲突:删除stomp-websocket依赖,仅保留stompjs:
// package.json dependencies中移除以下行
"stomp-websocket": "^2.3.4-next",
  1. 确保代码生效:重新编译打包客户端代码,避免旧代码缓存导致的路径错误。

  2. 可选:完善消息实体:给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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 08:55:24