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

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应用无任何错误输出,该如何解决?


解决方案

问题根源

  1. 直接调用emitter.send(Object, MediaType)时,Spring默认会通过消息转换器将对象序列化为JSON。这里传入的字符串被当作普通Object处理,最终被Jackson序列化后返回了SseEmitter内部的结构(如{"timeout":null}),而非预期的纯文本内容。
  2. 浏览器的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 07:50:25