Spring Boot WebSocket订阅/topic/resources超时问题求助
问题原因及解决方案
核心原因
你的测试代码中使用MappingJackson2MessageConverter作为Stomp客户端的消息转换器,但服务器控制器返回的是纯字符串(如"CalculatorMResource sum"),并非标准JSON格式内容。Jackson转换器无法将纯字符串解析为有效JSON,导致StringStompFrameHandler的handleFrame方法无法被触发,CompletableFuture一直处于未完成状态,最终触发30秒超时。
另外,控制器参数Optional<Map<String, Object>> params与测试中发送的ObjectNode类型存在匹配风险,虽Spring会尝试自动转换,但也可能干扰消息处理流程。
解决方案
方案1:客户端改用字符串消息转换器
既然服务器返回纯字符串,直接替换为StringMessageConverter即可:
WebSocketStompClient stompClient = new WebSocketStompClient(new SockJsClient(createTransportClient())); // 替换为字符串转换器 stompClient.setMessageConverter(new StringMessageConverter());
方案2:服务器返回标准JSON格式内容
若需保留Jackson转换器,可让控制器返回POJO对象或格式化后的JSON:
- 定义结果实体类:
public class FunctionCallResult { private String content; public FunctionCallResult(String content) { this.content = content; } // 生成getter和setter方法 public String getContent() { return content; } public void setContent(String content) { this.content = content; } }
- 修改控制器返回值:
@MessageMapping("/{classType}/{functionName}") @SendTo("/topic/resources") public FunctionCallResult callFunction( @DestinationVariable String classType, @DestinationVariable String functionName, Optional<Map<String, Object>> params ) { return new FunctionCallResult(classType + " " + functionName); }
额外优化:参数类型匹配
测试中发送ObjectNode,控制器接收Optional<Map<String, Object>>,建议直接在客户端发送Map对象,避免类型转换风险:
Map<String, Object> params = new HashMap<>(); List<Object> numbers = Arrays.asList(1, null, 2); params.put("numbers", numbers); params.put("operator", Operator.ADD.name()); stompSession.send("/call/CalculatorMResource/sum", params);
内容的提问来源于stack exchange,提问作者Adam Barča
相关产品推荐
相关产品推荐

