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

Spring Websocket(Sockjs+STOMPjs)升级后10秒内会话异常关闭问题

排查Spring WebSocket + SockJS + STOMPJS会话10秒内自动关闭的问题

我来帮你分析下这个问题——既然已经拿到了HTTP 101的协议升级响应,说明基础的握手流程是通的,但10秒内会话就关闭,大概率和心跳配置、客户端连接逻辑、服务器超时设置或者网络层面的拦截有关,给你几个具体的排查方向:


1. 优先检查SockJS的心跳配置

这应该是最常见的原因,SockJS默认的心跳超时正好是10秒,和你遇到的时间窗口完全吻合:

  • 服务器端:在你的WebSocket配置类里,调整SockJS的心跳和断开延迟参数,确保和客户端匹配:
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/websocket")
                .withSockJS()
                .setHeartbeatTime(30000) // 把心跳间隔改成30秒,避免频繁检测
                .setDisconnectDelay(5000); // 断开前的延迟时间,给客户端缓冲
    }
    
  • 客户端:STOMP.js必须显式配置心跳,不然服务器端收不到客户端的心跳信号,就会在10秒后主动关闭会话:
    const socket = new SockJS('/websocket');
    const stompClient = Stomp.over(socket);
    // 配置心跳,outgoing是客户端发心跳的间隔,incoming是服务器端的,和服务器保持一致
    stompClient.heartbeat.outgoing = 30000;
    stompClient.heartbeat.incoming = 30000;
    

2. 确认客户端是否正确订阅了STOMP目的地

有时候服务器会因为会话"空闲"(没有订阅任何主题/队列)而主动关闭连接。一定要确保客户端在连接成功后立即执行订阅操作:

stompClient.connect({}, function(frame) {
    console.log('Connected: ' + frame);
    // 必须订阅至少一个目的地,比如你的业务主题
    stompClient.subscribe('/topic/your-topic', function(message){
        console.log('Received message: ' + message.body);
    });
});

3. 检查服务器端的WebSocket消息代理配置

除了SockJS的配置,Spring的消息代理也有自己的心跳设置,你可以显式配置来覆盖默认值:

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
    config.enableSimpleBroker("/topic")
            .setHeartbeatValue(new long[]{30000, 30000}) // 代理的心跳间隔,和SockJS保持一致
            .setTaskScheduler(taskScheduler()); // 自定义调度器,确保心跳任务正常执行
    config.setApplicationDestinationPrefixes("/app");
}

@Bean
public TaskScheduler taskScheduler() {
    ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
    scheduler.setPoolSize(1);
    scheduler.setThreadNamePrefix("websocket-heartbeat-");
    scheduler.initialize();
    return scheduler;
}

4. 排查网络层面的超时拦截

如果你的应用前面有反向代理(比如Nginx)或者负载均衡,这些设备可能会主动断开空闲的WebSocket连接:

  • Nginx配置示例:在对应的location块里添加WebSocket支持和超时设置:
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 3600s; // 把超时时间调长,比如1小时
    proxy_send_timeout 3600s;
    
  • 另外也要检查防火墙是否有针对WebSocket连接的短超时限制,这部分可能需要运维协助确认。

5. 查看完整的会话关闭日志

你提供的日志被截断了,完整的CloseStatus代码和描述能直接定位问题。可以把日志级别调到TRACE,获取更详细的信息:

logging.level.org.springframework.web.socket=TRACE
logging.level.org.springframework.messaging=TRACE

常见的关闭原因比如HEARTBEAT_TIMEOUT(心跳超时)、GOING_AWAY(服务器主动断开),能帮你快速锁定问题。


先从心跳配置和客户端订阅这两个方向入手,这是最容易触发10秒会话关闭的点。

内容的提问来源于stack exchange,提问作者Black Glix

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 10:04:38