WebSocket 和 SSE 怎么选?实时通信入门与避坑

前言

做实时功能时,很多团队都会遇到同一个问题:消息推送到底用 WebSocket 还是 SSE?

如果只是"能跑起来",两者都能做;但到了线上,连接数、稳定性、网关兼容、开发复杂度都会影响结果。

这篇文章用工程视角讲清三件事:

  1. 两者的本质区别;
  2. 典型业务场景该怎么选;
  3. 上线前最容易踩的坑有哪些。

一、先给结论:一句话理解两者

  • WebSocket:全双工,客户端和服务端都可以主动发消息,适合高频双向交互。
  • SSE(Server-Sent Events):服务端单向推送到客户端,基于 HTTP,适合"服务端通知客户端"类场景。

如果你现在只记一条:
只需要服务端推送,用 SSE 先赢一半复杂度;双向实时互动,直接 WebSocket。


二、核心差异对比(工程最关心的维度)

维度 WebSocket SSE
通信方向 双向 单向(服务端 -> 客户端)
协议基础 ws:// / wss:// HTTP(text/event-stream
连接维护 需处理心跳、断线重连 浏览器原生支持自动重连(可配)
数据格式 文本/二进制都可 主要是文本流
适用场景 聊天、协同编辑、游戏、交易终端 通知流、日志流、任务进度、AI输出流式展示
实现复杂度 较高 较低

三、典型场景怎么选

场景 1:AI 对话流式输出

用户发请求后,前端只需要不断接收模型输出。

这类是标准"服务端持续推送",SSE 更轻量,接入成本低。

场景 2:IM 聊天室

客户端要发消息、撤回、输入状态同步,服务端也要广播。

这是典型双向高频,WebSocket 更合适

场景 3:运维看板/实时监控

浏览器端只看状态更新,不太需要主动发。

优先 SSE;如果后续要双向控制,再评估迁移 WebSocket。


四、最小代码示例

4.1 SSE:Node.js(Express)服务端

js 复制代码
import express from "express";

const app = express();

app.get("/events", (req, res) => {
  res.setHeader("Content-Type", "text/event-stream");
  res.setHeader("Cache-Control", "no-cache");
  res.setHeader("Connection", "keep-alive");

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

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

app.listen(3000);

4.2 前端订阅 SSE

js 复制代码
const es = new EventSource("/events");
es.onmessage = (e) => {
  const payload = JSON.parse(e.data);
  console.log("收到推送", payload);
};

这套代码就能跑出"服务端持续推送,前端实时显示"的最小闭环。


五、上线最常见的 4 个坑

5.1 反向代理超时

Nginx/网关如果默认超时较短,会导致长连接被频繁断开。

需要针对长连接路由单独配置超时与缓冲策略。

5.2 忘记做重连与幂等消费

不管 WebSocket 还是 SSE,真实网络都会抖动。

客户端要有重连逻辑,服务端要避免消息重复处理。

5.3 心跳机制缺失(WebSocket)

没有心跳时,连接可能"看起来在线,实际上不可用"。

建议服务端和客户端都实现 ping/pong 或应用层心跳。

5.4 把实时链路当普通 HTTP 接口压测

连接数、广播风暴、消息堆积和普通 QPS 不是一套指标。

实时系统要看:在线连接数、消息延迟、断线率、重连成功率。


六、实战建议:从"够用"开始,不要一步到位过度设计

可以按下面顺序决策:

  1. 先判断是否需要双向;不需要就优先 SSE;
  2. 评估连接规模与消息频率,确认网关和实例承载;
  3. 加入可观测性(连接数、延迟、断线率)再扩大流量;
  4. 当业务从"通知"演进为"交互",再升级到 WebSocket。

这比一开始就上复杂通信栈更稳,也更省研发成本。


总结

WebSocket 和 SSE 没有绝对优劣,关键看你是"实时通知"还是"实时交互"。

工程上最实用的原则是:能用 SSE 先用 SSE,必须双向再上 WebSocket

你们现在线上的实时需求主要是通知流,还是双向交互?评论区说下场景,一起交流学习~~~

相关推荐
hj28625113 小时前
Docker 核心知识点整理(网络 + Dockerfile + 原理 + 命令)
网络·docker·容器
so~what13 小时前
NTN全局控制器集中管理的优势
网络·ntn
normanhere13 小时前
华为S5735堆叠配置加华为AC S9700-S主备配置案例
网络
sdghterhd1 天前
WebSocket 快速入门教程(附示例源码)
网络·websocket·网络协议
xy34531 天前
Wireshark捕获过滤器——语法元素详解
网络·测试工具·渗透测试·wireshark
DLYSB_1 天前
生命通道:如何用 HIS 医疗系统直连网络声光终端,打造“零延误”的危急值响应网关?
java·网络·数据库·报警灯
德福危险1 天前
富有想象力的XSS盲打:靶机练习之Tempus_fugit5
服务器·网络·xss
哥是强混1 天前
Means:基于 .NET 10 打造的开源自部署 S3 兼容对象存储服务
网络·数据库·.net
Piko6141 天前
锐捷 VSU 虚拟化堆叠配置
运维·网络·笔记
IpdataCloud1 天前
AI生成的Avalon恶意框架怎么防?用IP离线库识别模块化C2通信
运维·人工智能·网络协议·tcp/ip·ip