1️⃣ SseEmitter 是什么?

SseEmitterSpring MVC 提供的一个用于 支持 SSE(Server-Sent Events) 的类,位于包:

org.springframework.web.servlet.mvc.method.annotation.SseEmitter

它的作用是:
在 HTTP 协议中,服务器可以主动通过一个持续的连接向客户端推送数据,而不是客户端一直轮询服务器,这种方式就是 SSE(服务器发送事件)。

SseEmitter 类帮你 在 Spring Controller 中方便地实现 SSE 推送,专门用于服务端持续向前端推送事件数据。


2️⃣ SSE 原理简单说

传统模型

  • HTTP 是一个请求一个响应,响应结束连接就关闭。
  • 要获得实时数据,客户端通常轮询(定时发请求)。

SSE 模型

  • 客户端发一次请求(fetchEventSource API)
  • 服务器保持连接不关闭,按需不断推送事件数据(MIME 类型 text/event-stream
  • 客户端在收到数据后自动触发回调处理

SSE 是一种单向推送(服务器到浏览器),它基于 HTTP 协议,和 WebSocket 相比更简单轻量。


3️⃣ SseEmitter 的作用

在 Spring MVC 中:

  • SseEmitter 是一个返回值对象,Controller 方法返回它之后,Spring MVC 会处理对应的响应头和流输出。
  • 你可以调用 SseEmitter.send() 发多条消息给浏览器。
  • Spring 会帮你设置响应头为:
    Content-Type: text/event-stream
    Cache-Control: no-cache
    Connection: keep-alive
    
  • 这就建立了一个长连接,直到你调用 complete() 或超时。

4️⃣ 使用示例

服务端代码(Spring Boot Controller)

@RestController
public class SseController {

    @GetMapping("/sse")
    public SseEmitter sse() {
        // 默认超时是 30秒,这里设为 0 表示不超时
        SseEmitter emitter = new SseEmitter(0L);

        // 可以在新线程中异步推送数据
        new Thread(() -> {
            try {
                for (int i = 1; i <= 5; i++) {
                    emitter.send(SseEmitter.event()
                        .name("message") // 事件名
                        .data("推送数据: " + i) // 数据
                        .id(String.valueOf(i))); // 事件ID(可选)
                    Thread.sleep(2000); // 每 2 秒推送一次
                }
                emitter.complete(); // 结束连接
            } catch (Exception e) {
                emitter.completeWithError(e);
            }
        }).start();

        return emitter;
    }
}

客户端代码(浏览器端)

<script>
    const evtSource = new EventSource("http://localhost:8080/sse");

    evtSource.onmessage = function(e) {
        console.log("默认事件收到:", e.data);
    };

    evtSource.addEventListener("message", function(e) {
        console.log("多事件监听:", e.data);
    });

    evtSource.onerror = function(e) {
        console.error("连接错误", e);
    };
</script>

运行后你会看到服务器每 2 秒推来一条数据,浏览器自动接收并执行回调,无需重新请求。


5️⃣ 为什么要用 SseEmitter

优点:

  1. 实时推送:比轮询更快更省资源
  2. 简单:基于 HTTP,不需要特殊协议
  3. 浏览器原生支持EventSource API 无需额外库(除 IE)
  4. 单向推送比 WebSocket容易实现和调试(但不能客户端推送给服务端)

场景:

  • 实时日志展示
  • 长时间批处理任务进度推送
  • 消息通知
  • 系统状态监控

6️⃣ 生命周期 & 注意点

  • 默认超时时间SseEmitter 构造方法可以设置。设为 0 表示无限长。
  • 结束连接:调用 emitter.complete()
  • 异常处理:调用 completeWithError(Throwable)
  • 多线程安全SseEmitter.send() 可以在多线程推送,但要注意同步。

总结
SseEmitter 是 Spring MVC 帮你实现 HTTP 长连接 的 SSE 推送的工具类。
前端只要用浏览器的 EventSource 建立连接,就可以持续接收服务器推送的数据。
它适合:

  • 实时数据流
  • 进度通知
  • 无需 WebSocket 的轻量推送场景
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐