SpringBoot SSE重复连接超时求助:net::ERR_INCOMPLETE_CHUNKED_ENCODING
SpringBoot SSE重复连接与
net::ERR_INCOMPLETE_CHUNKED_ENCODING问题排查 针对你遇到的首次连接正常但立刻触发二次连接、最终超时报错的问题,从代码和配置层面排查以下几个常见原因:
1. SseEmitter被意外关闭
- 检查后端代码是否在首次连接完成后,误调用了
emitter.complete()或emitter.completeWithError()方法。这两个方法会主动关闭SSE连接,浏览器检测到连接关闭后会自动发起重连。 - 排查业务逻辑中是否存在未捕获的异常,Spring在捕获到Emitter关联线程的异常时,会自动关闭Emitter,触发浏览器重连。
2. 响应头配置不规范
SSE对响应头有严格要求,缺失或错误的头会导致浏览器无法识别长连接,进而触发重连:
// 确保在创建Emitter前设置这些响应头 HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); assert response != null; response.setHeader("Content-Type", "text/event-stream"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Connection", "keep-alive"); response.setCharacterEncoding("UTF-8");
如果未设置text/event-stream,浏览器会将响应视为普通HTTP请求,连接完成后立刻结束并尝试重连。
3. 超时配置未真正生效
- 确认SseEmitter的超时参数是否正确设置:
// 明确指定5分钟超时 SseEmitter emitter = new SseEmitter(5 * 60 * 1000L); - 检查服务器(如Tomcat)的全局连接超时配置,若Tomcat的
connectionTimeout设置小于5分钟,会提前断开连接,导致ERR_INCOMPLETE_CHUNKED_ENCODING错误。可以在application.properties中调整:server.tomcat.connection-timeout=300000 # 5分钟,与Emitter超时一致
4. 前端重连逻辑误触发
检查前端EventSource的错误处理逻辑,是否在未区分错误类型的情况下直接发起重连:
const source = new EventSource('/sse/connect'); // 错误示例:任何错误都触发重连 source.onerror = function(error) { source.close(); // 立刻重连导致二次连接请求 setTimeout(() => new EventSource('/sse/connect'), 0); };
应该在错误处理中判断是否为正常关闭,避免不必要的重连:
source.onerror = function(error) { if (source.readyState === EventSource.CLOSED) { // 仅在意外关闭时考虑重连,而非立刻触发 console.log('连接意外关闭,稍后尝试重连'); setTimeout(() => new EventSource('/sse/connect'), 5000); } };
5. SSE消息格式错误
后端推送消息时未遵循SSE格式规范,会导致浏览器无法解析,进而中断连接:
- 正确的推送方式应使用Spring提供的
SseEmitter.event()构造消息:emitter.send(SseEmitter.event().data("推送内容").id("1").name("message")); - 手动构造消息时必须以
data:开头,以\n\n结尾,比如:
格式错误会导致浏览器认为连接异常,触发重连和编码错误。emitter.send("data: 推送内容\n\n");
排查步骤建议
- 先检查后端响应头是否符合SSE要求,可通过浏览器开发者工具的Network面板查看请求头。
- 确认SseEmitter未被主动关闭,添加日志监控
emitter.onCompletion()和emitter.onError()事件,查看连接关闭的原因:emitter.onCompletion(() -> log.info("SSE连接正常关闭")); emitter.onError((e) -> log.error("SSE连接异常关闭", e)); - 验证服务器全局超时配置与Emitter超时是否一致。
- 检查前端重连逻辑是否存在误触发。
内容的提问来源于stack exchange,提问作者benym
相关产品推荐
相关产品推荐

