在现代Web应用开发中,实时数据推送与双向通信已成为刚需。从轮询(Polling)到长轮询(Long Polling),再到Server-Sent Events(SSE)与WebSocket,技术不断演进。本文将从协议原理、前端API、适用场景及选型角度,对SSE与WebSocket进行简要而深入的对比分析。

一、Server-Sent Events(SSE)

1.1 原理与规范

SSE基于HTTP协议,允许服务器通过一个长连接向客户端持续推送数据。其核心规范定义于HTML Living Standard,客户端使用EventSource接口。
服务器需设置响应头Content-Type: text/event-stream,并按照特定格式发送消息:

data: 消息内容\n\n

支持自定义事件类型、消息ID(用于断线重连后恢复)及自动重连机制。

1.2 前端API示例

const source = new EventSource('/api/stream');

// 监听默认消息
source.onmessage = (event) => {
  console.log('收到数据:', event.data);
};

// 监听自定义事件
source.addEventListener('ping', (event) => {
  console.log('ping事件:', event.data);
});

source.onerror = (err) => {
  console.error('连接异常', err);
};

1.3 服务端简单示意(Node.js + Express)

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

  let id = 0;
  const timer = setInterval(() => {
    res.write(`id: ${id}\n`);
    res.write(`data: ${JSON.stringify({ time: Date.now() })}\n\n`);
    id++;
  }, 1000);

  req.on('close', () => clearInterval(timer));
});

1.4 优缺点

  • 优点:基于HTTP,部署简单;自动重连与事件ID恢复;轻量,无需额外协议。
  • 缺点:仅支持服务器→客户端单向通信;文本传输(二进制需编码);浏览器连接数限制(HTTP/1.1下同源最多6个,HTTP/2可多路复用)。

二、WebSocket

2.1 原理与规范

WebSocket(RFC 6455)是一个独立的全双工通信协议,通过HTTP Upgrade机制将连接升级为wswss(加密)协议。一旦建立,客户端与服务器可以任意时刻互相发送帧(Frame),开销远低于HTTP请求。

2.2 前端API示例

const ws = new WebSocket('wss://example.com/ws');

ws.onopen = () => {
  ws.send('客户端上线');
};

ws.onmessage = (event) => {
  console.log('收到消息:', event.data);
};

ws.onclose = () => {
  console.log('连接关闭,尝试重连...');
  // 需自行实现重连逻辑
};

2.3 服务端简单示意(Node.js + ws库)

import { WebSocketServer } from 'ws';

const wss = new WebSocketServer({ port: 8080 });

wss.on('connection', (ws) => {
  ws.on('message', (data) => {
    ws.send(`回声: ${data}`);
  });
});

2.4 优缺点

  • 优点:双向实时、低延迟;支持二进制传输;适合高交互场景。
  • 缺点:协议较复杂,需专用服务端支持;连接管理(重连、心跳)需自行实现;负载均衡需处理长连接亲和性。

三、技术对比与选型建议

维度SSEWebSocket
通信方向单向(服务器 → 客户端)双向全双工
协议HTTP / HTTPSws / wss(独立协议)
自动重连内置支持,带Last-Event-ID需手动实现
数据格式UTF-8文本(可自定义事件)文本或二进制帧
浏览器支持除IE外全部支持现代浏览器广泛支持
实现复杂度低(EventSource)中高(需处理心跳、重连等)
典型场景实时通知、股票行情、日志流、AI流式响应在线游戏、聊天室、协同编辑、高频交易

选型原则

  • 仅需服务器推送:优先选择SSE,开发成本低,且可利用HTTP基础设施(CDN、缓存控制)。
  • 双向高频交互:WebSocket是唯一合理选择。
  • 混合架构:可使用WebSocket传输核心双向数据,SSE推送辅助通知;或客户端主动请求用普通HTTP,推送用SSE。

四、总结

SSE与WebSocket并非替代关系,而是面向不同通信模型的互补技术。SSE以极简的API和HTTP生态优势,在单向流式场景(如AI对话流、实时仪表盘)中愈发流行;WebSocket则凭借全双工低延迟特性,在复杂交互应用中占据主导。开发者应基于通信方向性、数据量级、运维成本综合权衡,避免过度设计。

正如RFC 6455所言:“WebSocket旨在解决HTTP难以胜任的实时双向通信问题。”而SSE则完美填补了“单向推送但不想引入复杂协议”的空缺。

参考文献:HTML Living Standard — Server-sent events;RFC 6455 — The WebSocket Protocol