SseEmitter
是 Spring Framework 中用于服务器发送事件(Server-Sent Events, SSE)的类。SSE 是一种允许服务器推送更新到客户端的技术,通常用于实时更新的场景,如股票价格、实时消息、游戏状态等,又或者想要实现像ChatGPT那样的流式问答的效果。
以下是 SseEmitter
的一些关键点和使用方法:
关键点
- 服务器推送事件:与 WebSocket 不同,SSE 是单向通信,从服务器到客户端。客户端通过 HTTP 请求订阅事件,服务器在事件发生时推送数据。
- 基于 HTTP 协议:SSE 使用 HTTP 协议,客户端通过标准的 HTTP 请求订阅,服务器通过 HTTP 响应推送事件。
- 自动重连:大多数浏览器内置对 SSE 的支持,并且会在连接断开时自动尝试重新连接。
- 简单性:SSE 相对于 WebSocket 更加简单和轻量,适用于只需要服务器向客户端推送数据的应用场景。
使用方法
1. 添加依赖
确保你的项目中包含 Spring Web 依赖。
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2. 创建控制器
创建一个 REST 控制器来处理 SSE 请求。
java
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.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@RestController
public class SseController {
@GetMapping("/sse")
public SseEmitter handleSse() {
SseEmitter emitter = new SseEmitter();
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(() -> {
try {
emitter.send("Hello at " + System.currentTimeMillis());
} catch (IOException e) {
emitter.completeWithError(e);
}
}, 0, 1, TimeUnit.SECONDS);
emitter.onCompletion(executor::shutdown);
return emitter;
}
}
3. 客户端订阅
客户端可以使用 JavaScript 原生的 EventSource
对象来订阅事件。
html
<!DOCTYPE html>
<html>
<head>
<title>SSE Example</title>
</head>
<body>
<h1>SSE Example</h1>
<div id="events"></div>
<script>
const eventSource = new EventSource('/sse');
eventSource.onmessage = function(event) {
const newElement = document.createElement("div");
newElement.textContent = event.data;
document.getElementById("events").appendChild(newElement);
};
</script>
</body>
</html>
解释
- 创建
SseEmitter
实例 :在服务器端控制器中,通过调用new SseEmitter()
创建一个SseEmitter
实例。 - 定期发送消息 :使用调度任务定期向客户端发送消息。
SseEmitter
的send
方法用于发送事件。 - 处理异常 :在发送消息时处理可能的
IOException
,并通过completeWithError
方法通知客户端连接终止。 - 客户端接收消息 :客户端通过
EventSource
对象订阅服务器推送的事件,并通过onmessage
处理接收到的消息。
注意事项
- 连接管理 :需要合理管理
SseEmitter
的生命周期,确保在连接完成、错误或超时时正确关闭。 - 浏览器支持:SSE 是大多数现代浏览器支持的技术,但在一些老旧浏览器中可能不受支持。
- 数据格式:SSE 传输的数据格式是文本,通常使用 JSON 格式传输结构化数据。
SseEmitter
提供了一种简洁高效的方法来实现服务器到客户端的实时数据推送,适合于许多实时应用场景。