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

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:

  1. 定义结果实体类:
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; }
}
  1. 修改控制器返回值:
@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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 16:56:06