什么是 SSE (Server-Sent Events) ?

509 阅读2分钟

Server-Sent Events(SSE) 协议是一个基于 HTTP 协议的技术,允许服务器端向客户端单向推送实时更新。

SSE 是 HTML5 标准的一部分,主要用于在客户端和服务端保持一个长期的连接,服务器可以通过该连接向客户端推送事件和数据。

SSE 的特点:

  1. 单向通信:SSE 是单向通信,服务器可以推送数据给客户端,但是客户端不能通过同一个连接向服务器发送数据。
  2. 简单易用:相较于 WebSocket, SSE 的实现更为简单,使用标准的 HTTP 协议,无需额外的协议支持。
  3. 自动重连:如果连接中断,SSE 客户端会自动尝试重新连接到服务器。
  4. 基于文本: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-Typetext/event-stream

一般响应格式如下:

HTTP/1.1 200 
Content-Type: text/event-stream;charset=UTF-8
Transfer-Encoding: chunked

SSE 与 websocket 对比:

特性SSEWebSocket
协议基于 HTTP独立的 Websocket 协议
通信方向单向通信:客户端与服务器端建立连接之后,仅允许服务端向客户端推送数据双向通信
浏览器支持大部分现代浏览器支持大部分现代浏览器支持
复杂度简单:基于 HTTP复杂:需要专门的协议和配置
重连机制原生支持自动重连需要手动实现重连机制
数据格式基于文本的事件流可以传输文本和二进制数据