Server-Sent Events (SSE) 技术详解

一、SSE 基本概念

Server-Sent Events (SSE) 是一种允许服务器向客户端(通常是浏览器)推送实时更新的Web技术。它基于HTTP协议,提供了一种简单高效的服务器到客户端的单向通信机制。

主要特点:

  • 单向通信:仅服务器→客户端方向

  • 基于HTTP:无需特殊协议

  • 文本数据:支持UTF-8文本格式

  • 自动重连:内置连接恢复机制

  • 轻量级:比WebSocket更简单

二、SSE 工作原理

1. 建立连接

客户端通过EventSource API发起连接:

const eventSource = new EventSource('/sse-endpoint');

2. 服务器响应

服务器返回特定格式的流响应:

HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

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

3. 数据传输格式

SSE使用简单文本协议,每条消息由字段组成,以\n\n结束:

event: notification
id: 123
data: {"time": "2023-01-01", "message": "Hello"}
retry: 5000\n\n

三、SSE 与 WebSocket 对比

特性SSEWebSocket
方向单向(服务器→客户端)双向
协议HTTP独立协议(ws://)
数据格式文本文本/二进制
自动重连支持需手动实现
浏览器支持除IE外主流浏览器所有现代浏览器
复杂度中高
适用场景实时通知、日志流聊天、游戏等交互应用

四、SSE 实现示例

客户端实现

// 创建SSE连接
const eventSource = new EventSource('/sse');

// 监听消息
eventSource.onmessage = (e) => {
  console.log('收到消息:', e.data);
};

// 监听自定义事件
eventSource.addEventListener('status', (e) => {
  console.log('状态更新:', JSON.parse(e.data));
});

// 错误处理
eventSource.onerror = () => {
  console.error('连接错误');
  // 自动重连
};

服务器实现(Node.js)

const http = require('http');

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

    // 发送初始消息
    res.write('data: 连接已建立\n\n');

    // 定时推送
    let counter = 0;
    const timer = setInterval(() => {
      counter++;
      res.write(`data: 这是第${counter}条消息\n\n`);
      
      // 发送自定义事件
      if (counter % 5 === 0) {
        res.write('event: alert\ndata: 重要通知!\n\n');
      }
    }, 1000);

    // 连接关闭时清理
    req.on('close', () => {
      clearInterval(timer);
    });
  } else {
    res.writeHead(404);
    res.end();
  }
}).listen(3000);

五、SSE 高级特性

1. 消息字段

  • data:消息内容(可多行)

  • id:事件ID(用于重连时Last-Event-ID头部)

  • event:自定义事件类型

  • retry:重连时间(毫秒)

2. 多行数据

data: 第一行\n
data: 第二行\n
data: 第三行\n\n

客户端接收:"第一行\n第二行\n第三行"

3. 自定义事件

event: userupdate\n
data: {"id": 123, "name": "张三"}\n\n

客户端监听:eventSource.addEventListener('userupdate', handler)

六、SSE 使用场景

  1. 实时通知:社交网络更新、新邮件提醒

  2. 实时数据监控:股票价格、IoT设备状态

  3. 日志流:实时显示服务器日志

  4. 新闻/体育赛事:实时比分更新

  5. 进度报告:长时间操作进度更新

七、SSE 最佳实践

  1. 连接管理

    // 安全关闭连接
    function closeSSE() {
      eventSource.close();
    }
  2. 错误处理增强

    eventSource.onerror = (e) => {
      if (e.eventPhase === EventSource.CLOSED) {
        console.log('连接被服务器关闭');
      } else {
        console.log('连接出错:', e);
      }
    };
  3. 性能优化

    • 合并多条消息减少HTTP开销

    • 适当设置retry时间(默认3秒)

  4. 安全考虑

    // 携带认证信息
    const eventSource = new EventSource('/sse', {
      withCredentials: true
    });

SSE提供了一种简单高效的服务器推送解决方案,特别适合需要服务器主动推送但不需要双向通信的场景。相比轮询和长轮询,SSE更加高效且易于实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值