SSE(Server-Sent Events)是一种基于 HTTP 协议的技术,用于建立一个服务器从服务端向客户端单向推送数据的通道。与 WebSocket 不同,SSE 只支持单向数据传输,适用于实时通知、监控进度、更新日志等场景。由于只需要处理单向通信,SSE 的实现既简单又高效,并且可以充分利用现有的 HTTP 连接。
首先,通过 Spring Initializr 或其他方式创建一个 Spring Boot 项目。确保项目中引入了 Spring Web 依赖。示例如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
在项目中创建一个控制器类,通过返回 SseEmitter 对象来建立 SSE 的长连接。通过 SseEmitter.send() 方法可以向客户端发送消息,SseEmitter.complete() 用于在数据传输结束后关闭连接。下面是一个示例代码:
// 导入相关包
import org.springframework.http.MediaType;
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;
@RestController
public class SseController {
private final ExecutorService executor = Executors.newSingleThreadExecutor();
@GetMapping(value = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter streamSseMvc() {
SseEmitter emitter = new SseEmitter();
executor.execute(() -> {
try {
// 发送10条消息,每条间隔1秒
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
emitter.send("消息 " + i);
}
emitter.complete();
} catch (IOException | InterruptedException e) {
emitter.completeWithError(e);
}
});
return emitter;
}
}
在前端页面中可以使用 JavaScript 的 EventSource API 建立与 SSE 端点的连接,并通过 onmessage 事件接收数据。示例如下:
<!DOCTYPE html>
<html>
<head>
<title>SSE 示例</title>
</head>
<body>
<h1>Server-Sent Events 示例</h1>
<div id="content"></div>
<script>
var eventSource = new EventSource('/sse');
eventSource.onmessage = function(event) {
document.getElementById('content').innerHTML += event.data + '<br>';
};
eventSource.onerror = function(error) {
console.error("SSE 连接出错:", error);
};
</script>
</body>
</html>
对于高并发场景,可借助 CompletableFuture 或 @Async 注解进行异步数据推送。同时,通过注册 SseEmitter 的 onCompletion、onTimeout 和 onError 回调函数,可以更好地管理连接状态并处理潜在错误。
SseEmitter emitter = new SseEmitter(60L * 1000L); // 设置60秒的超时时间
emitter.onCompletion(() -> System.out.println("连接已完成"));
emitter.onTimeout(() -> System.out.println("连接超时"));
emitter.onError((ex) -> System.out.println("连接错误:" + ex.getMessage()));
下面的表格总结了使用 SSE 开发的主要步骤与关键点,帮助您直观了解各阶段实现的重点:
实现步骤 | 关键技术/方法 | 主要优势 |
---|---|---|
项目搭建 | Spring Boot, Spring Web | 快速开发,无需额外依赖 |
创建控制器 | SseEmitter, @RestController | 支持长连接,实时数据推送 |
数据发送 | emitter.send(), 异步处理 | 低延迟、稳定数据传输 |
客户端接收 | EventSource API, onmessage回调 | 简单易用,浏览器原生支持 |
错误与超时管理 | onError, onTimeout, onCompletion | 优化连接资源管理 |
下面的雷达图展示了在开发 SSE 过程中考虑的几个关键维度,例如实时性、稳定性、资源管理、易用性和扩展性。该图基于开发者的实践经验与整体评价。
下方的思维导图以简明的方式展示了在 Spring Boot 中实现 SSE 的整体开发逻辑,从项目搭建、控制器编写、数据发送到前端接收,帮助开发者快速理解整个流程。