SseEmitter

哈喽,大家好,我是了不起。

最近看到一个知名开源项目官宣停更,还是挺震惊的。

SseEmitter介绍

SseEmitter 是 Spring Framework 中用于服务器发送事件(Server-Sent Events, SSE)的类。SSE 是一种允许服务器推送更新到客户端的技术,通常用于实时更新的场景,如股票价格、实时消息、游戏状态等。

功能和用途

  1. 服务器推送事件:与 WebSocket 不同,SSE 是单向通信,从服务器到客户端。客户端通过 HTTP 请求订阅事件,服务器在事件发生时推送数据。
  2. 基于 HTTP 协议:SSE 使用 HTTP 协议,客户端通过标准的 HTTP 请求订阅,服务器通过 HTTP 响应推送事件。
  3. 自动重连:大多数浏览器内置对 SSE 的支持,并且会在连接断开时自动尝试重新连接。
  4. 简单性:SSE 相对于 WebSocket 更加简单和轻量,适用于只需要服务器向客户端推送数据的应用场景。

基本用法

  1. 创建 SseEmitter 实例:在控制器中创建一个 SseEmitter 实例,并将其返回给客户端。
  2. 发送事件:通过 SseEmitter 实例的 send 方法向客户端发送事件。
  3. 处理连接关闭:通过 SseEmitteronCompletiononTimeout 方法处理连接关闭或超时的情况。

示例代码

1. 创建一个控制器类:

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.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 nonBlockingService = Executors.newCachedThreadPool();
    
    @GetMapping("/sse")
    public SseEmitter handleSse() {
        SseEmitter emitter = new SseEmitter();
        nonBlockingService.execute(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    SseEmitter.SseEventBuilder event = SseEmitter.event()
                            .data("SSE event - " + i)
                            .id(String.valueOf(i))
                            .name("sse event")
                            .reconnectTime(10_000L);
                    emitter.send(event);
                    Thread.sleep(1000); // 模拟延迟
                }
                emitter.complete(); // 完成发送
            } catch (IOException | InterruptedException e) {
                emitter.completeWithError(e);
            }
        });
        return emitter;
    }
}

2. 客户端代码(Js):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>SSE Example</title>
</head>
<body>
    <h1>Server-Sent Events Example</h1>
    <ul id="eventList"></ul>
    <script>
        const eventSource = new EventSource('/sse');
        eventSource.onmessage = function(event) {
            const newElement = document.createElement("li");
            newElement.textContent = event.data;
            document.getElementById("eventList").appendChild(newElement);
        };
    </script>
</body>
</html>

通过上述代码,您可以实现服务器向客户端的实时数据推送,提升用户体验。

Java Geek Tech wechat
欢迎订阅 Java 技术指北,这里分享关于 Java 的一切。