在 Spring Boot 中使用 Server-Sent Events (SSE) 实现实时消息推送是一种轻量级的解决方案,适用于需要从服务器向客户端发送更新的应用场景。
步骤 1: 添加依赖
首先,确保你的 pom.xml
或 build.gradle
文件中包含了 Spring Web 的依赖,因为 SSE 是基于 HTTP 的。
对于 Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
对于 Gradle:
implementation 'org.springframework.boot:spring-boot-starter-web'
步骤 2: 创建 SSE 控制器
接下来,创建一个控制器用于处理 SSE 请求。下面是一个示例控制器:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.scheduling.annotation.Scheduled;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.servlet.http.HttpServletResponse;
@RestController
public class SseController {
private final CopyOnWriteArrayList<SseHolder> holders = new CopyOnWriteArrayList<>();
@GetMapping("/subscribe")
public void subscribe(HttpServletResponse response) throws IOException {
response.setContentType("text/event-stream");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Connection", "keep-alive");
SseHolder holder = new SseHolder(response);
holders.add(holder);
// Send initial data immediately after subscription
sendToAll("Welcome to the SSE feed!");
}
@Scheduled(fixedRate = 5000)
public void sendUpdate() {
sendToAll("This is an update from the server.");
}
private void sendToAll(String message) {
for (SseHolder holder : holders) {
try {
holder.send(message);
} catch (IOException e) {
holders.remove(holder);
}
}
}
static class SseHolder {
private final HttpServletResponse response;
private final StringBuilder sb = new StringBuilder();
public SseHolder(HttpServletResponse response) {
this.response = response;
}
public void send(String message) throws IOException {
sb.setLength(0);
sb.append("data: ").append(message).append("\n\n");
response.getWriter().write(sb.toString());
response.getWriter().flush();
}
}
}
步骤 3: 测试 SSE
你可以在前端使用 JavaScript 的 EventSource 对象来接收这些事件:
<script>
var source = new EventSource('/subscribe');
source.onmessage = function(event) {
console.log('Server says: ' + event.data);
};
</script>
这样,每当服务器有新的消息,它就会通过 SSE 推送给所有订阅了 /subscribe
路径的客户端。
注意事项
- SSE 连接是单向的,只能由服务器推送到客户端。
- 当客户端断开连接或浏览器关闭时,SSE 连接会自动关闭,因此你需要在后端代码中处理连接断开的情况(如在
sendToAll
方法中检查和移除无效的连接)。
以上就是使用 Spring Boot 和 SSE 实现实时消息推送的基本流程。可以根据自己的需求进行扩展和优化,例如添加身份验证、错误处理等。