教育人就是要培养他对自己有更严格的要求。——苏霍姆林斯基

SseEmitter 是 Spring Framework 提供的一个类,用于处理服务器向客户端推送事件(Server-Sent Events, SSE)的功能。与 WebSocket 不同,SSE 是单向的,服务器可以推送数据到客户端,但客户端不能推送数据到服务器。SSE 适用于场景包括实时消息通知、进度更新、数据流推送等。Spring Boot 中通过 SseEmitter 实现 SSE 通信简单且高效。

Spring Boot 中的 SseEmitter 提供了一种轻量级的方式来向前端推送实时数据,它通过标准的 HTTP 协议工作,兼容性广泛且易于使用。

SseEmitter 的主要特点:

  • 轻量级:基于 HTTP 协议,兼容性好,不需要复杂的配置。
  • 单向推送:服务器向客户端推送数据,适合需要实时更新的场景。
  • 长连接:通过持续连接,避免频繁的轮询操作。
  1. 官方文档、GitHub地址

官方文档提供了 SseEmitter 的详细使用方法,而 GitHub 仓库中有关于 Spring Boot 及其 SSE 实现的代码示例。

  1. 引入依赖

使用 Spring Boot 时,SseEmitter 是框架自带的类,通常不需要额外的依赖。但如果需要增强对 SSE 的支持,建议引入 spring-boot-starter-web

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
  1. 例子

下面是一个使用 SseEmitter 实现服务器推送的简单示例,演示如何向客户端推送实时更新消息。

示例:实时消息推送

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@RestController
public class SseController {

// 使用线程池处理异步任务
private final ExecutorService executor = Executors.newCachedThreadPool();

@GetMapping("/sse")
public SseEmitter handleSse() {
SseEmitter emitter = new SseEmitter(60_000L); // 设置超时时间为60秒

executor.submit(() -> {
try {
for (int i = 0; i < 5; i++) {
TimeUnit.SECONDS.sleep(1); // 模拟延迟
emitter.send("实时消息更新 " + i); // 发送消息
}
emitter.complete(); // 完成推送
} catch (IOException | InterruptedException e) {
emitter.completeWithError(e); // 处理异常
}
});

return emitter;
}
}

代码解析:

  1. 创建 SseEmitter:在 /sse 路由下创建一个 SseEmitter 对象,设置超时时间为 60 秒,表示连接将在 60 秒内保持活跃。
  2. 异步推送消息:通过线程池异步推送消息,避免阻塞主线程。使用 emitter.send() 方法将消息发送到客户端。
  3. 处理完成或异常:在消息推送完成后调用 emitter.complete() 关闭连接。如果推送过程中发生异常,可以通过 emitter.completeWithError() 进行错误处理。

客户端可以使用以下 JavaScript 代码接收推送的实时消息:

1
2
3
4
5
6
7
8
9
const eventSource = new EventSource("/sse");

eventSource.onmessage = function(event) {
console.log("收到消息: ", event.data);
};

eventSource.onerror = function() {
console.error("连接出错或已关闭");
};

应用场景:

  1. 实时通知:用于实时推送消息或通知,比如社交媒体的新消息提醒或电子邮件更新。
  2. 进度条更新:在处理长时间运行的任务时,服务器可以通过 SSE 向前端实时推送任务的进度更新。
  3. 数据流推送:用于持续推送实时数据流,如金融数据、天气更新等。

总结

SseEmitter 提供了一种轻量、直观的方式实现服务器推送操作,尤其适用于需要向客户端发送实时数据的场景。它的实现基于标准的 HTTP 协议,简单易用,同时可以通过长连接减少服务器与客户端之间的轮询压力。

在使用 SseEmitter 时,开发者可以通过异步处理机制提升应用的响应速度,确保高效的实时推送体验。如果你的项目中有实时推送需求,SseEmitter 是一个非常合适的解决方案。