Server-Sent Events(SSE) 协议是一个基于 HTTP 协议的技术,允许服务器端向客户端单向推送实时更新。
SSE 是 HTML5 标准的一部分,主要用于在客户端和服务端保持一个长期的连接,服务器可以通过该连接向客户端推送事件和数据。
SSE 的特点:
- 单向通信:SSE 是单向通信,服务器可以推送数据给客户端,但是客户端不能通过同一个连接向服务器发送数据。
- 简单易用:相较于 WebSocket, SSE 的实现更为简单,使用标准的 HTTP 协议,无需额外的协议支持。
- 自动重连:如果连接中断,SSE 客户端会自动尝试重新连接到服务器。
- 基于文本:SSE 数据是基于文本格式,通常是 UTF-8 编码的纯文本。
SSE 的基本用法
服务器端实现(示例代码以 java spring boot 为例)
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.IOEeception;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@RestController
public class SseController {
@GetMapping("/sse")
public SseEmitter streamSseMvc() {
SseEmitter emitter = new SseEmitter();
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(() -> {
try {
for (int i = 0; i < 10; i++) {
emitter.send("SSE event - " + i);
TimeUnit.SECONDS.sleep(1);
}
emitter.complete();
} catch (IOException | InterruptedException e) {
emitter.completeWithError(e);
}
});
return emitter;
}
}
客户端实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SSE Example</title>
</head>
<body>
<div id="sse-messages"></div>
<script>
const eventSource = new EventSource('/sse');
eventSource.onmessage = function(event) {
const newElement = document.createElement("div");
newElement.textContent = event.data;
document.getElementById("sse-messages").appendChild(newElement);
};
eventSource.onerror = function() {
console.error("SSE connection error");
};
</script>
</body>
</html>
SSE 消息格式
SSE 消息是基于文本的,通常有以下几种字段:
- data: 数据字段,包含要传输的实际数据;
- id: 事件ID, 用于标识事件;
- event: 事件类型,客户端可以根据事件类型处理不同的事件。
- retry: 重试时间,客户端在连接断开后重试的时间间隔(毫秒)。
示例消息:
data: message 1
id: 1
event: update
retry: 5000
data: message 2
id: 2
event: update
retry: 5000
sse 接口的响应 Header 中的 Content-Type 是 text/event-stream。
一般响应格式如下:
HTTP/1.1 200
Content-Type: text/event-stream;charset=UTF-8
Transfer-Encoding: chunked
SSE 与 websocket 对比:
| 特性 | SSE | WebSocket |
|---|---|---|
| 协议 | 基于 HTTP | 独立的 Websocket 协议 |
| 通信方向 | 单向通信:客户端与服务器端建立连接之后,仅允许服务端向客户端推送数据 | 双向通信 |
| 浏览器支持 | 大部分现代浏览器支持 | 大部分现代浏览器支持 |
| 复杂度 | 简单:基于 HTTP | 复杂:需要专门的协议和配置 |
| 重连机制 | 原生支持自动重连 | 需要手动实现重连机制 |
| 数据格式 | 基于文本的事件流 | 可以传输文本和二进制数据 |