Skip to content

HTML5 服务器发送事件(Server-Sent Events,SSE)是一种在服务器与客户端之间建立单向连接的技术,使服务器能够实时推送更新到客户端。相比于轮询和 WebSocket,SSE 提供了一种更简单、资源消耗更少的实时数据传输方式,特别适合消息广播、实时通知等场景。

基本概念

  1. SSE:服务器向客户端单向推送消息的机制。
  2. EventSource:在客户端用于接收 SSE 的接口。
  3. 数据流:SSE 通过持续的 HTTP 连接发送文本数据流。

服务器端实现

服务器需要发送特定格式的数据流,通常使用 HTTP 头部 Content-Type: text/event-stream。下面是一些示例:

使用 Node.js

javascript
const http = require('http');

http.createServer((req, res) => {
    if (req.headers.accept && req.headers.accept === 'text/event-stream') {
        // 设置头部
        res.writeHead(200, {
            'Content-Type': 'text/event-stream',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive'
        });

        // 定义发送消息的函数
        const sendEvent = (data) => {
            res.write(`data: ${JSON.stringify(data)}\n\n`);
        };

        // 发送初始消息
        sendEvent({ message: 'Connected to SSE' });

        // 定时发送消息
        const intervalId = setInterval(() => {
            sendEvent({ message: 'Hello from server', time: new Date().toISOString() });
        }, 5000);

        // 清除定时器
        req.on('close', () => {
            clearInterval(intervalId);
        });
    } else {
        // 非 SSE 请求
        res.writeHead(404);
        res.end();
    }
}).listen(8080, () => {
    console.log('SSE server running at http://localhost:8080');
});

客户端实现

客户端使用 EventSource 接口来接收服务器发送的事件。

html
<!DOCTYPE html>
<html>
<head>
    <title>Server-Sent Events Example</title>
</head>
<body>
    <h1>Server-Sent Events</h1>
    <div id="output"></div>

    <script>
        if (typeof(EventSource) !== "undefined") {
            var source = new EventSource("http://localhost:8080");

            source.onmessage = function(event) {
                var data = JSON.parse(event.data);
                document.getElementById("output").innerHTML += "Message: " + data.message + " at " + data.time + "<br>";
            };

            source.onerror = function(error) {
                console.error("EventSource failed: ", error);
            };
        } else {
            document.getElementById("output").innerHTML = "Sorry, your browser does not support server-sent events...";
        }
    </script>
</body>
</html>

数据格式

SSE 数据流由多个字段组成,每个字段以换行符 \n 结尾:

  • data: 后面跟随事件的数据。
  • event: 自定义事件类型。
  • id: 事件 ID,用于客户端重新连接时标识。
  • retry: 指定客户端在断开连接后重新连接的时间间隔(毫秒)。

示例:

plaintext
data: Hello World
event: customEvent
id: 12345
retry: 3000

特点与注意事项

  1. 自动重连:客户端会在连接断开时自动尝试重新连接,除非服务器明确关闭连接。
  2. 简单实现:与 WebSocket 相比,SSE 更易于实现和维护。
  3. 浏览器支持:大多数现代浏览器都支持 SSE,但需要注意部分旧版浏览器的兼容性。
  4. 单向通信:SSE 只支持服务器向客户端的单向通信。如果需要双向通信,可以考虑使用 WebSocket。

结论

HTML5 服务器发送事件(SSE)是一种高效、轻量级的实时数据推送技术,适用于许多需要实时更新的 web 应用场景。通过简单的 API 和数据格式,SSE 提供了一种易于实现的解决方案,在现代 web 开发中具有广泛的应用前景。