WebSocket之外,SSE协议为何被大厂悄悄采用?

文章首发于公众号:BiggerBoy

原文链接:WebSocket之外,SSE协议为何被大厂悄悄采用?)

SSE(Server-Sent Events,服务器发送事件)是一种基于 HTTP 的协议,允许服务器向客户端(如浏览器)主动推送实时数据。它是 HTML5 规范的一部分,旨在简化单向实时通信的实现。


核心特性

  1. 单向通信
    SSE 仅支持服务器到客户端的单向数据推送,客户端通过普通 HTTP 请求建立连接后,服务器可随时发送数据。
  2. 基于 HTTP
    使用标准的 HTTP 协议,无需额外的协议(如 WebSocket),兼容现有基础设施(如身份验证、代理)。
  3. 长连接(Long Polling)
    客户端通过一个持久的 HTTP 连接接收数据流,服务器通过该连接持续发送更新。
  4. 自动重连
    客户端内置断线重连机制,若连接中断会自动尝试重新连接。
  5. 轻量数据格式
    数据以纯文本流格式(text/event-stream)传输,每条消息可包含以下字段:
    • data: 消息内容(必填,支持多行)。
    • event: 自定义事件类型(可选,用于客户端区分不同事件)。
    • id: 消息的唯一标识(可选,用于断线后恢复)。
    • retry: 重连时间间隔(毫秒,可选)。

工作原理

  1. 客户端
    使用 JavaScript 的 EventSource API 发起请求:

    const eventSource = new EventSource('/sse-endpoint');
    eventSource.onmessage = (event) => {
      console.log('收到数据:', event.data);
    };
    eventSource.addEventListener('customEvent', (event) => {
      console.log('自定义事件:', event.data);
    });
    
  2. 服务器
    响应需设置 HTTP 头:

    通过流(Stream)持续发送数据,格式示例:

    event: customEvent
    data: {"status": "update", "value": 42}
    id: 123
    retry: 3000
    
    data: 这是一条普通消息\n多行内容
    
    • Content-Type: text/event-stream
    • Cache-Control: no-cache
    • Connection: keep-alive

与 WebSocket 的对比

特性SSEWebSocket
方向单向(服务器→客户端)双向全双工
协议HTTP独立的 ws://wss:// 协议
复杂度简单,无需额外库需处理握手、帧协议等
断线恢复自动重连,支持id恢复需手动实现
适用场景实时通知、股票行情、日志流聊天、游戏等双向交互

使用场景

  • 实时数据推送(如新闻、股价、天气)。
  • 进度更新(如文件上传/处理进度)。
  • 日志流监控。
  • 无需双向交互的轻量级实时应用(生成式AI,比如DeepSeek回复的内容)。

优点

  • 简单易用:基于 HTTP,无需复杂协议实现。
  • 兼容性:现代浏览器广泛支持(IE 除外,可通过 Polyfill 兼容)。
  • 自动重连:内置断线恢复机制。
  • 低开销:文本格式数据轻量,适合高频小数据量场景。

缺点

  • 单向通信:无法从客户端向服务器发送数据(需配合其他 HTTP 请求)。
  • 文本格式限制:二进制数据传输需编码(如 Base64)。
  • 连接数限制:浏览器对同一域的 SSE 连接数有限制(通常 6 个)。

示例代码

客户端(浏览器)

const eventSource = new EventSource('/updates');
eventSource.onmessage = (e) => {
  console.log('新消息:', e.data);
};
eventSource.onerror = () => {
  console.error('连接错误');
};

服务器(Node.js)

const http = require('http');
http.createServer((req, res) => {
  if (req.url === '/updates') {
    res.writeHead(200, {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive'
    });
    let id = 0;
    setInterval(() => {
      res.write(`data: ${JSON.stringify({ time: Date.now() })}\n\n`);
      id++;
    }, 1000);
  }
}).listen(3000);

注意事项

  • 确保服务器不支持压缩(如 gzip),否则可能中断流传输。
  • 避免在消息中使用单行结束符(\n),需使用双换行符(\n\n)分隔消息。
  • 对于敏感数据,需使用 HTTPS 防止中间人攻击。

SSE 是替代传统轮询(Polling)和长轮询(Long Polling)的高效方案,适用于需要服务器主动推送的实时场景。

关注【BiggerBoy】公众号,获取更多技术干货!

在这里插入图片描述

<think>我们已经知道微信小程序对WebSocket有原生支持,但对SSE(Server-SentEvents)没有直接支持。根据引用[3],小程序目前没有直接支持SSE,但可以通过request的分块传输来模拟,但这种方式处理数据比较困难。因此,建议使用WebSocket实现实时通信。现在用户询问微信小程序对SSE协议的支持情况以及与WebSocket的比较。我们需要从以下几个方面回答:1.**微信小程序对SSE的支持情况**:-根据引用[3]:小程序没有直接支持SSE,虽然可以通过request分块传输来接收类似SSE的数据流,但数据解析困难(因为分块传输的数据可能是不完整的,比如一条json被截断),因此不推荐使用。2.**SSEWebSocket的主要区别**:-SSE是HTTP协议基础上的单向通信(服务器到客户端),而WebSocket是独立的双向通信协议。-SSE支持自动重连、事件ID等特性,而WebSocket需要手动实现。-WebSocket可以双向实时通信,而SSE只能服务器向客户端推送。3.**在微信小程序中的选择建议**:-由于小程序没有原生支持SSE,且模拟实现困难,因此推荐使用WebSocket(引用[2][3])来实现实时通信。-微信小程序原生支持WebSocket,有完整的API(wx.connectSocket,wx.onSocketMessage等),开发相对简单。4.**性能与资源考虑**:-引用[1]提到:WebSocket需要更高的资源管理(因为要保持长连接),而SSE基于HTTP,资源消耗相对较低,但在小程序中无法直接使用SSE。-在微信小程序环境下,尽管WebSocket需要更多资源,但它是官方推荐的实时通信方案。5.**具体实现差异**:-使用WebSocket:需要在小程序端使用wx.connectSocket创建连接,通过事件监听消息(onOpen,onMessage,onClose,onError)。-使用SSE模拟:由于不支持EventSource,需要通过wx.request请求一个分块传输的接口,但需要自行处理数据流的拼接和解析,代码复杂且容易出错。因此,结论是:在微信小程序中,应该优先使用WebSocket来实现实时通信功能,避免尝试使用SSE。下面我们按照用户的要求,结构清晰地回答,并插入引用标识。同时,在最后生成相关问题。</think> ### 微信小程序 SSEWebSocket 支持对比分析 #### 1. SSE 协议在微信小程序中的支持情况 - **不支持原生 SSE**:微信小程序官方未提供 Server-Sent Events (SSE) 的原生 API 支持[^3] - **替代方案可行性**: - 可通过 `wx.request` 实现分块传输,但存在以下技术限制: - 数据包完整性:单次请求可能只获取部分 JSON 数据,导致解析困难 - 无事件驱动:需自行实现消息分片处理逻辑 - 无自动重连:连接中断需手动恢复 ``` // 分块传输示例(不推荐) wx.request({ enableChunked: true, success(res) { // 需处理半截数据:'{"name":"Jo' + 'hn","age":30}' } }) ``` - **结论**:小程序场景下不推荐使用 SSE 协议实现实时通信[^3] #### 2. WebSocket 协议支持 - **完整原生支持**: ```javascript // 标准实现示例 const socket = wx.connectSocket({ url: 'wss://your-domain.com/ws' }) // 消息监听 socket.onMessage(res => { console.log('收到消息:', res.data) }) // 错误处理 socket.onError(error => { console.error('连接异常:', error) }) ``` - **技术优势**: - ✅ 双向实时通信:客户端/服务端均可主动发送消息 - ✅ 协议成熟:标准 WebSocket 协议支持(RFC 6455) - ✅ 心跳保活:内置连接维护机制 #### 3. 核心区别对比表 | **特性** | **SSE** | **WebSocket** | |-------------------------|----------------------------------|-------------------------------| | 通信方向 | 单向(服务端→客户端) | 双向 | | 协议基础 | HTTP 长连接 | 独立 TCP 协议 | | 小程序支持度 | 不可用[^3] | 原生支持[^2] | | 数据格式 | 文本(含事件流格式) | 二进制/文本 | | 自动重连 | 内置机制 | 需手动实现 | | 应用场景 | 服务端推送(新闻、价格更新) | 双向交互(聊天、协作、游戏) | | 资源消耗 | 较低 | 较高(需保持连接)[^1] | #### 4. 技术选型建议 1. **实时双向通信需求**: 必须使用 WebSocket(如聊天室、实时协作等场景)[^2] 2. **服务端单向推送**: - 简单场景:采用轮询(`setInterval + wx.request`) - 复杂场景:WebSocket 模拟 SSE(服务端只发送,客户端只接收) 3. **性能敏感场景**: WebSocket 优于轮询方案,虽然资源消耗高于 SSE,但在小程序中 SSE 不可用 > **特别提示**:需注意微信对 WebSocket 连接的并发限制: > - 同一域名最多同时维持 5 个 WebSocket 连接 > - 每个小程序最多同时维持 50 个 WebSocket 连接 > $$ \text{MaxConnections} = \min(5_{\text{per-domain}}, 50_{\text{per-app}}) $$ #### 5. 实现建议 1. **WebSocket 最佳实践**: ```javascript // 推荐封装为管理类 class SocketManager { constructor(url) { this.socket = wx.connectSocket({ url }) this.initEvents() } initEvents() { this.socket.onOpen(() => this.heartbeat = setInterval(/*...*/, 30000)) this.socket.onClose(() => clearInterval(this.heartbeat)) } send(data) { if(this.socket.readyState === 1) { // OPEN this.socket.send({ data: JSON.stringify(data) }) } } } ``` 2. **消息传输优化**: - 使用 Protobuf 压缩二进制数据: $$ \text{传输效率} \propto \frac{1}{\text{数据包大小}} $$ - 消息合并发送(减少帧数) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员beige

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值