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

Spring Boot 1.5.13 WebSocket连接30分钟自动关闭问题求助

解决Spring Boot 1.5.x WebSocket因HTTP会话过期被断开的问题

哥们,我维护老项目时也碰到过一模一样的情况——WebSocket消息收发都正常,但过段时间就因为HTTP会话过期被踢掉,错误码1008。结合你的代码和配置,给你几个针对性的解决方案:

1. 解除WebSocket与HTTP会话的绑定

你的错误提示明确指向“已结束的认证HTTP会话”,说明Spring的WebSocket默认和HTTP会话绑定了。哪怕你发了WebSocket心跳,HTTP会话还是会按自身规则过期,进而触发WebSocket连接终止。

解决思路是自定义握手拦截器,在握手阶段移除WebSocket对HTTP会话的依赖:

public class NoHttpSessionBindingInterceptor implements HandshakeInterceptor {
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, 
                                   WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        // 移除HTTP会话属性,让WebSocket连接不再依赖它
        attributes.remove("HTTP_SESSION");
        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, 
                               WebSocketHandler wsHandler, Exception exception) {
        // 无需额外操作
    }
}

然后在WebSocket配置里注册这个拦截器:

@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry.addHandler(
            new CustomExceptionWebSocketHandlerDecorator(socketHandler),
            ENDPOINT
        )
        .addInterceptors(new NoHttpSessionBindingInterceptor()) // 新增这一行
        .setAllowedOrigins("*");
}

这样WebSocket连接就和HTTP会话彻底解绑,HTTP会话过期也不会影响它的存活了。

2. 用WebSocket心跳刷新HTTP会话

如果业务上必须保留WebSocket与HTTP会话的绑定(比如需要从会话里取用户信息),那可以在收到WebSocket消息(包括你的心跳)时手动刷新HTTP会话:

public class HttpSessionRefreshDecorator extends WebSocketHandlerDecorator {
    public HttpSessionRefreshDecorator(WebSocketHandler delegate) {
        super(delegate);
    }

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
        // 获取绑定的HTTP会话并触发刷新
        HttpSession httpSession = (HttpSession) session.getAttributes().get("HTTP_SESSION");
        if (httpSession != null) {
            // 通过设置任意属性触发会话刷新
            httpSession.setAttribute("last_websocket_activity", System.currentTimeMillis());
        }
        // 继续执行原消息处理逻辑
        super.handleTextMessage(session, message);
    }
}

然后用这个装饰器包裹你的handler:

registry.addHandler(
        new HttpSessionRefreshDecorator(new CustomExceptionWebSocketHandlerDecorator(socketHandler)),
        ENDPOINT
    )
    .setAllowedOrigins("*");

这样每次你发送WebSocket心跳时,都会同步刷新HTTP会话,避免它提前过期。

3. 确认session超时配置真的生效

虽然你设置了server.servlet.session.timeout=6h,但Spring Boot 1.5.x在某些场景下(比如Tomcat版本差异)可能不会正确读取这个配置。你可以启动项目后,查看Tomcat启动日志,搜索“session timeout”,确认实际生效的超时时间是不是6小时。如果没生效,试试直接配置Tomcat的参数:

# Tomcat会话超时配置(单位:分钟)
server.tomcat.session-timeout=360

最后小提醒

你的WebSocket心跳是必须的,但最好做成双向的——客户端发心跳后,服务器也响应一条消息,这样既能维持WebSocket连接本身,也能确保HTTP会话的刷新逻辑正常触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:59:31