跳转到内容

HTML Server Sent Events

来自代码酷

HTML Server-Sent Events

Server-Sent Events (SSE) 是一种基于 HTTP 的服务器推送技术,允许服务器向客户端(通常是网页浏览器)单向发送实时数据更新。与 WebSocket 不同,SSE 仅支持服务器到客户端的单向通信,但实现更简单,适用于需要实时数据流但无需双向交互的场景,如新闻推送、股票行情或日志监控。

概述[编辑 | 编辑源代码]

SSE 使用标准的 HTTP 协议,通过长连接(long-lived connection)实现数据推送。客户端通过 `EventSource` API 订阅服务器事件流,服务器则以 `text/event-stream` 格式持续发送数据。

核心特点[编辑 | 编辑源代码]

  • **单向通信**:仅服务器→客户端。
  • **自动重连**:客户端在连接断开时会尝试重新连接。
  • **轻量级**:基于 HTTP,无需额外协议。
  • **事件驱动**:支持自定义事件类型(如 `message`、`error`)。

基本用法[编辑 | 编辑源代码]

客户端代码[编辑 | 编辑源代码]

客户端通过 JavaScript 的 `EventSource` 对象监听服务器事件:

  
// 创建 EventSource 对象,指向服务器端点  
const eventSource = new EventSource('/sse-endpoint');  

// 监听默认事件(未指定事件类型时触发)  
eventSource.onmessage = (event) => {  
    console.log('新数据:', event.data);  
};  

// 监听自定义事件(如 'update')  
eventSource.addEventListener('update', (event) => {  
    console.log('自定义事件数据:', event.data);  
});  

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

服务器代码(Node.js 示例)[编辑 | 编辑源代码]

服务器需设置响应头 `Content-Type: text/event-stream` 并持续发送数据流:

  
const http = require('http');  

http.createServer((req, res) => {  
    if (req.url === '/sse-endpoint') {  
        res.writeHead(200, {  
            'Content-Type': 'text/event-stream',  
            'Cache-Control': 'no-cache',  
            'Connection': 'keep-alive'  
        });  

        // 每秒发送一次数据  
        setInterval(() => {  
            res.write(`data: ${new Date().toISOString()}\n\n`); // 注意格式要求  
        }, 1000);  
    }  
}).listen(3000);
    • 输出示例**:

客户端控制台每秒接收一条时间戳数据:

  
新数据: 2023-10-01T12:00:00.000Z  
新数据: 2023-10-01T12:00:01.000Z  

数据格式规范[编辑 | 编辑源代码]

SSE 数据流必须遵循以下格式:

  • 每行以字段名开头(如 `data:`、`event:`、`id:`)。
  • 数据以双换行符 `\n\n` 结束。
  • 注释行以 `:` 开头(可选)。
    • 示例**:
  
event: update  
data: {"price": 150}  
id: 12345  

data: 这是一条多行  
data: 消息\n\n  

实际应用案例[编辑 | 编辑源代码]

实时股票价格推送[编辑 | 编辑源代码]

服务器持续发送股票价格更新,客户端动态更新页面:

  
eventSource.onmessage = (event) => {  
    const stockData = JSON.parse(event.data);  
    document.getElementById('stock-price').textContent = stockData.price;  
};

服务器日志监控[编辑 | 编辑源代码]

开发者后台实时显示服务器日志:

sequenceDiagram participant Client participant Server Client->>Server: 订阅 /logs loop 每秒推送 Server->>Client: data: [ERROR] 文件未找到\n\n end

高级配置[编辑 | 编辑源代码]

自定义重连时间[编辑 | 编辑源代码]

服务器可通过 `retry:` 字段指定重连延迟(毫秒):

  
retry: 5000  
data: 重连时间设置为5秒\n\n  

事件 ID 追踪[编辑 | 编辑源代码]

服务器发送 `id:` 字段,客户端在重连时通过 `Last-Event-ID` 请求头恢复:

  
id: 42  
data: 恢复此事件后的数据\n\n  

限制与替代方案[编辑 | 编辑源代码]

  • **局限性**:
 * 不支持双向通信(需使用 WebSocket)。  
 * 部分浏览器限制最大并发连接数(如 Chrome 为 6)。  
  • **替代技术**:
 * **WebSocket**:全双工通信,适合聊天应用。  
 * **长轮询(Long Polling)**:兼容性更好但效率较低。  

数学表示(可选)[编辑 | 编辑源代码]

事件流的吞吐量可建模为: R=nt 其中 R 为速率(事件/秒),n 为事件数,t 为时间。

总结[编辑 | 编辑源代码]

SSE 是构建实时单向数据流的轻量级解决方案,适合无需客户端响应的场景。通过 `EventSource` API 和标准化数据格式,开发者可以快速实现服务器推送功能。