Java环境间WebSocket通信异常:SpringBoot Reactive收不到消息
问题排查与修复方案
我帮你定位到了核心问题,结合你的代码片段来看,导致接收端Step 1/2不执行、关闭时出现1002错误的原因有两个:WebSocket消息payload未释放和客户端关闭时机过早,同时Reactive流的处理逻辑也需要调整。
1. 修复Spring Boot Reactive WebSocket的处理逻辑
Reactive WebSocket的WebSocketMessage基于Netty ByteBuf实现,必须手动释放payload,否则会造成资源泄漏,阻塞后续消息流。同时调整流处理的写法,确保整个链路被正确激活:
@Override public Mono<Void> handle(WebSocketSession webSocketSession) { // 处理 incoming 消息,生成响应 Flux<WebSocketMessage> messageFlux = webSocketSession.receive() .doOnNext(msg -> log.info("Step 0: Received message frame")) .flatMap(message -> { log.info("Step 1: Processing message payload"); String payload = message.getPayloadAsText(); // 必须释放消息的payload,避免资源泄漏和流阻塞 message.release(); return Mono.just(payload); }) .map(payload -> { log.info("Step 2: Generating response"); return webSocketSession.textMessage(this.receiveMessage(payload)); }); // 返回send的Mono,Spring会自动订阅该流,触发整个处理链路 return webSocketSession.send(messageFlux); }
2. 调整客户端的关闭时机
客户端发送消息后立刻调用sendClose,会导致消息还没被服务器接收处理就关闭连接,服务器端的流被中断,从而触发1002错误。需要等待消息发送完成后再关闭:
// 先等待消息发送完成,再执行关闭操作 webSocket.sendText(toJSON(List.of("Lorem", "Ipsum", "dolor", "sit", "amet")), true) .thenCompose(ignore -> webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "ok")) .thenRun(() -> log.info("Sent close frame"));
为什么这样修复?
- payload未释放:如果不调用
message.release(),Netty的ByteBuf会一直占用内存,后续的消息处理流会被阻塞,这就是Step 1和Step 2完全没执行的关键原因。 - 关闭时机过早:
sendText是异步操作,直接调用sendClose会跳过消息发送的等待步骤,服务器还没来得及处理消息就收到关闭请求,内部流处理中断,返回1002错误码。 - 流逻辑优化:用
flatMap替代嵌套map,更贴合Reactive编程的异步处理风格,确保每个步骤的操作都被正确串联。
额外验证点
- 检查
receiveMessage方法是否有未捕获的异常,如果这个方法报错,也会导致服务器内部错误,触发1002状态码。 - 查看服务器端的完整日志,确认是否有未打印的异常信息,能帮你进一步排查潜在问题。
内容的提问来源于stack exchange,提问作者Mauro de Palma
相关产品推荐
相关产品推荐

