Springboot SseEmitter前端显示timeout:null问题求助
问题
尝试执行以下Spring Boot SSE后端代码:
@Controller public class DataActivityController { @CrossOrigin @RequestMapping(value="/sse/mvc/emitter") public ResponseEntity<SseEmitter> handleRequest () { final SseEmitter emitter = new SseEmitter(); ExecutorService service = Executors.newSingleThreadExecutor(); service.execute(() -> { for (int i = 0; i < 1000; i++) { try { emitter.send(i + " - ", MediaType.TEXT_PLAIN); Thread.sleep(10); } catch (Exception e) { e.printStackTrace(); emitter.completeWithError(e); return; } } emitter.complete(); }); return new ResponseEntity(emitter, HttpStatus.OK); } }
随后通过浏览器使用以下代码连接:
<script> function sendRequest(){ if(typeof(EventSource) !== "undefined") { var source = new EventSource("http://localhost:8080/sse/mvc/emitter"); source.onmessage = function(event) { document.getElementById("sseDiv").innerHTML += event.data + " - "; }; } else { document.getElementById("sseDiv").innerHTML = "Your browser does not support server-sent events."; } } </script>
浏览器页面重复显示{"timeout":null} - ,但Spring Boot应用无任何错误输出,该如何解决?
解决方案
问题根源
- 直接调用
emitter.send(Object, MediaType)时,Spring默认会通过消息转换器将对象序列化为JSON。这里传入的字符串被当作普通Object处理,最终被Jackson序列化后返回了SseEmitter内部的结构(如{"timeout":null}),而非预期的纯文本内容。 - 浏览器的
EventSource组件要求SSE消息必须符合规范:每条消息以data:开头,以\n\n结尾,否则无法正确解析出event.data的有效内容。
修复步骤
方式一:用SseEmitter.SseEventBuilder构建规范消息
修改后端发送消息的代码,通过SseEmitter.event()构建符合SSE标准的消息,Spring会自动处理格式封装:
emitter.send(SseEmitter.event() .data(i + " - ", MediaType.TEXT_PLAIN));
方式二:手动拼接SSE格式字符串
如果不想使用SseEventBuilder,可以直接发送符合SSE规范的字符串:
emitter.send("data: " + i + " - \n\n", MediaType.TEXT_PLAIN);
必须包含data:前缀和\n\n结尾,确保浏览器能识别为完整的SSE消息。
额外优化建议
- 关闭线程池:避免资源泄漏,在
emitter.complete()和异常分支中添加service.shutdown()。 - 明确响应类型:修改
@RequestMapping,指定produces为SSE专用的text/event-stream,让浏览器更清晰识别响应格式:
@RequestMapping(value="/sse/mvc/emitter", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
内容的提问来源于stack exchange,提问作者jugurtha
相关产品推荐
相关产品推荐

