Skip to main content

SEE协议

Server-Sent Events(SEE)是一种基于HTTP协议的轻量级服务器推送技术,其底层实现原理可以概括为以下几个核心要点:

1. 基于HTTP长连接的单向通信

SEE使用标准的HTTP协议实现服务器到客户端的单向数据推送。与传统HTTP请求不同的是,SEE通过保持HTTP连接打开(长连接),允许服务器在有新数据时随时向客户端发送。

工作流程

  1. 客户端发起请求
    客户端通过创建EventSource对象向服务器发送HTTP请求,请求头中包含:

    Accept: text/event-stream
    Cache-Control: no-cache

    表明客户端期望接收事件流格式的数据。

  2. 服务器响应并保持连接
    服务器返回状态码200 OK,并设置响应头:

    Content-Type: text/event-stream
    Cache-Control: no-cache
    Connection: keep-alive

    然后不关闭连接,而是持续向客户端发送数据。

  3. 数据推送
    服务器以特定格式(见下文)向客户端发送数据,客户端通过监听事件接收这些数据。

2. 数据格式:Event Stream

服务器发送的数据必须遵循text/event-stream格式,每行以field: value形式存在,空行表示消息结束。常见字段包括:

  • data: 实际数据内容(必选)。
  • event: 事件类型(可选,默认为message)。
  • id: 事件ID(可选,用于重连时恢复状态)。
  • retry: 重连超时时间(毫秒,可选)。

示例

data: This is a simple message\n\n
event: notification\n
data: {"title": "New Message", "body": "You have 3 new messages"}\n\n
id: 12345\n
data: Update #12345\n\n

3. 自动重连机制

SEE的一大优势是浏览器会自动处理重连,当连接意外断开时(如网络波动),浏览器会在一段时间后自动尝试重新连接服务器。服务器可通过retry字段指定重连间隔:

retry: 5000\n
data: Server will be back soon\n\n

4. 客户端实现(JavaScript)

浏览器通过EventSource接口提供SEE支持:

const eventSource = new EventSource('/api/events');

// 监听默认事件(未指定event字段时)
eventSource.onmessage = (event) => {
console.log('Received:', event.data);
};

// 监听自定义事件
eventSource.addEventListener('notification', (event) => {
const data = JSON.parse(event.data);
console.log('Notification:', data.title);
});

// 错误处理
eventSource.onerror = (error) => {
console.error('EventSource failed:', error);
};

5. 服务器实现示例

以下是Node.js + Express实现SEE服务器的简化示例:

const express = require('express');
const app = express();

app.get('/api/events', (req, res) => {
// 设置响应头
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
});

// 发送初始数据
res.write('data: Connected!\n\n');

// 定时推送数据(例如每5秒)
const intervalId = setInterval(() => {
const message = `data: Server time is ${new Date().toISOString()}\n\n`;
res.write(message);
}, 5000);

// 客户端断开连接时清理资源
req.on('close', () => {
clearInterval(intervalId);
res.end();
});
});

app.listen(3000, () => console.log('Server running on port 3000'));

6. 与WebSocket的核心差异

特性Server-Sent EventsWebSocket
协议HTTP独立的WebSocket协议
连接管理由浏览器自动重连需要手动实现重连逻辑
数据方向单向(服务器→客户端)双向
二进制支持仅文本支持文本和二进制
复杂度简单(基于HTTP)较高(需要处理握手、帧等)

7. 局限性与适用场景

局限性

  • 单向通信:无法实现客户端主动向服务器发送数据。
  • 浏览器兼容性:IE不支持,需使用Polyfill。
  • 性能:长连接会占用服务器资源,高并发场景需优化。

适用场景

  • 实时通知(如邮件提醒、社交媒体更新)。
  • 股票行情、体育赛事比分等实时数据推送。
  • 新闻更新、博客订阅等内容推送。

总结

SEE通过保持HTTP长连接和特定的数据格式,实现了服务器到客户端的轻量级单向通信,其核心优势在于简单易用、自动重连,适合不需要双向通信的实时推送场景。