SSE 与 WebSocket 核心区别全景解析

SSE(Server-Sent Events)和 WebSocket 都用于实现实时通信,但设计目标和技术实现有本质区别。以下是深度对比:

一、核心机制对比

特性 WebSocket SSE (Server-Sent Events)
通信方向 全双工(双向实时通信) 单工(仅服务器→客户端)
协议基础 独立协议(HTTP升级后脱离HTTP) 纯HTTP协议(长连接)
数据格式 二进制帧或文本帧 纯文本(UTF-8)
连接管理 需手动处理重连 自动重连(Retry机制)
浏览器API WebSocket 对象 EventSource 对象
首次连接 HTTP 101切换协议 标准HTTP GET请求

二、工作流程详解

WebSocket 工作流程(双向通信)

SSE 工作流程(单向推送)

三、数据格式差异

WebSocket 帧结构(二进制灵活)

 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 
+-+-+-+-+-------+-+-------------+
|F|R|R|R| opcode|M| Payload len |
|I|S|S|S| (4)   |A|     (7)     |
|N|V|V|V|       |S|             |
| |1|2|3|       |K|             |
+-+-+-+-+-------+-+-------------+
| Extended payload length...    
+-------------------------------+
| Masking-key (if MASK set)     
+-------------------------------+
| Payload Data                  
+--------------------------------

SSE 事件流格式(文本协议)

event: stockUpdate
id: 42
data: {"symbol":"AAPL","price":175.32}
retry: 5000
​
data: 系统将在5分钟后维护
​
: 注释行(客户端忽略)
  • 字段说明

    • event:事件类型(客户端监听特定事件)

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

    • id:事件ID(断线重连时用Last-Event-ID发送)

    • retry:重连时间(毫秒)

四、性能与能力对比

维度 WebSocket SSE
传输效率 ⭐⭐⭐⭐⭐ (帧头2字节) ⭐⭐ (HTTP头重复传输)
延迟 ⭐⭐⭐⭐⭐ (毫秒级) ⭐⭐⭐ (依赖HTTP层)
服务端推送 ✅ 支持 ✅ 支持
客户端发送 ✅ 支持 ❌ 需额外AJAX请求
二进制支持 ✅ 原生支持 ❌ 仅文本
自动重连 ❌ 需手动实现 ✅ 内置机制
压缩支持 ✅ PerMessage-Deflate ✅ HTTP压缩(gzip)
最大并发连接数 不受限制(单连接复用) 浏览器限制(Chrome 6-8个)

五、代码实现对比

WebSocket 实现

// 客户端
const socket = new WebSocket('wss://api.example.com/ws');
socket.onmessage = (event) => {
  console.log('Received:', event.data);
};
document.getElementById('send').addEventListener('click', () => {
  socket.send(JSON.stringify({action: 'buy', stock: 'AAPL'}));
});
​
// 服务端(Node.js)
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => {
  ws.on('message', (data) => {
    console.log('Client says:', data);
  });
  setInterval(() => {
    ws.send(JSON.stringify({price: Math.random()*100}));
  }, 1000);
});

SSE 实现

// 客户端
const source = new EventSource('/events');
source.addEventListener('stockUpdate', (e) => {
  console.log('Stock update:', e.data);
});
source.addEventListener('alert', (e) => {
  alert(e.data);
});
​
// 服务端(Node.js/Express)
app.get('/events', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  
  // 发送事件
  setInterval(() => {
    res.write(`event: stockUpdate\n`);
    res.write(`data: ${JSON.stringify({symbol: "AAPL", price: getPrice()})}\n\n`);
  }, 1000);
  
  // 断线处理
  req.on('close', () => {
    clearInterval(interval);
  });
});

六、选型决策指南

推荐场景:

技术 最佳适用场景
WebSocket 在线游戏、实时协作工具、聊天应用、金融交易平台
SSE 实时监控仪表盘、新闻推送、股票行情更新、社交媒体通知

七、关键注意事项

  1. SSE的兼容性问题

    • 不支持IE(包括IE11)

    • 部分浏览器限制并发SSE连接数(可通过域名分片解决)

  2. WebSocket的复杂性

    • 需实现心跳保活机制

    • 需处理二进制数据编解码

    • 代理服务器可能导致连接问题(需WSS加密)

  3. SSE的协议限制

    • 无法通过标准SSE发送Cookie(需URL参数传递认证信息)

    • 最大连接时间限制(可搭配retry字段自动恢复)

总结:核心区别精华

维度 WebSocket SSE
设计目标 全功能双向实时通道 轻量级服务器推送
协议开销 极低(自定义帧结构) 较高(HTTP头冗余)
开发复杂度 较高(需处理协议细节) 较低(标准HTTP)
数据能力 二进制+文本 仅文本
断线恢复 手动实现 自动重连+消息追踪
适用场景 强交互应用 单向数据广播

📌 终极建议需要双向交互 → WebSocket 只需服务器推送+简单实现 → SSE 兼容旧系统 → SSE + Polyfill

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐