常见的实时通信技术(轮询、sse、websocket、webhooks)

1. HTTP轮询:最老实的办法

刚开始做实时功能时,我第一个想到的就是轮询。特别简单直白,就像你每隔5分钟就刷新一次朋友圈看看有没有新消息一样。

短轮询:勤快但费劲

短轮询就是客户端隔三差五地问服务器:"有新消息没?"不管有没有,服务器都会立即回答:"没有"或者"有,给你"。

专业一点的说法:

  1. 客户端定期向服务器发送HTTP请求
  2. 服务器立即响应,无论是否有新数据
  3. 客户端处理响应后,等待固定间隔再次请求
javascript 复制代码
// 前端代码示例
setInterval(() => {
fetch('/api/check-updates')
.then(res => res.json())
.then(data => {
// 处理数据
});
}, 5000); // 每5秒问一次

​优点​​:

  • 实现简单,是个后端都会写
  • 兼容性无敌,连IE6都支持

​缺点​​:

  • 太费流量了,就像你每隔5分钟就给朋友发微信"在吗?"
  • 延迟感人,如果消息刚好在你两次询问之间来了,就得等下次轮询

长轮询:聪明一点的做法

后来我发现长轮询更聪明些。客户端问完"有新消息吗?",服务器会一直等着,直到真的有消息了才回复。

长轮询是对短轮询的改进:

  1. 客户端发送请求到服务器
  2. 服务器保持连接打开,直到有新数据或超时
  3. 一旦有数据或超时,服务器响应
  4. 客户端收到响应后立即发起新请求
javascript 复制代码
function longPoll() {
fetch('/api/long-poll')
.then(res => res.json())
.then(data => {
// 处理数据
longPoll(); // 立即发起下一次请求
});
}

​体验提升​​:

  • 消息来得更快了,基本实时
  • 请求次数少了,省流量

​新问题​​:

  • 服务器得一直挂着这些连接,人一多就撑不住了
  • 还是得不停地建立新连接

2. SSE:服务器主动找你聊天

后来我发现SSE(Server-Sent Events)这个好东西。它就像你朋友主动给你发微信,不用你老问了。

  1. 客户端通过EventSource API建立到服务器的连接
  2. 连接保持打开状态,服务器可随时推送数据
  3. 数据以特定格式(text/event-stream)传输
  4. 自动处理连接中断和重连
javascript 复制代码
// 前端
const eventSource = new EventSource('/sse-endpoint');

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

​爽点​​:

  • 消息实时推送,延迟超低
  • 自动重连,断网也不怕
  • 用起来特别简单

​不爽的地方​​:

  • 只能服务器推给你,你不能推给服务器(单向)
  • 有些老浏览器不支持
  • 只能传文本,想传文件没门

​适合场景​​:

  • 股票行情推送
  • 新闻实时更新
  • 像ChatGPT那种一个字一个字往外蹦的效果

3. WebSocket:真正的双向通话

想要真正的实时双向通信?那就得上WebSocket了。这就像微信通话,两边都能随时说话。

  1. 独立协议(ws://或加密wss://)
  2. 通过HTTP升级握手建立连接
  3. 之后保持持久连接双向通信
javascript 复制代码
// 前端
const socket = new WebSocket('wss://example.com/ws');

socket.onopen = () => {
socket.send('你好!');
};

socket.onmessage = (e) => {
console.log('收到:', e.data);
};

​为什么香​​:

  • 真正的实时,延迟极低
  • 双向通信,想发就发
  • 一个连接管所有,省资源

​坑也不少​​:

  • 兼容性还是有点问题(不过现在大部分浏览器都OK了)
  • 得自己处理断线重连
  • 安全性要特别注意

​最适合​​:

  • 在线游戏(比如王者荣耀)
  • 实时聊天(微信、QQ这种)
  • 协同编辑(像腾讯文档)

4. Webhooks:让服务器主动找你

Webhooks比较特别,它让服务器主动调用你的接口。比如你女朋友说"有事给我打电话",这就是Webhooks。

​工作流程​​:

  1. 你告诉服务器你的回调地址
  2. 服务器有事就直接call你

专业一点的说法

  1. 客户端(实际是接收服务器)提供回调URL
  2. 服务端在事件发生时向该URL发送HTTP请求
  3. 接收方处理事件并返回响应
复制代码
javascript 复制代码
// 你的服务器接口
app.post('/webhook', (req, res) => {
console.log('收到通知:', req.body);
res.status(200).end();
});

​好处​​:

  • 实时性很好
  • 不用轮询,省事

​要注意​​:

  • 你的接口必须随时待命
  • 得做好安全验证
  • 高并发时可能会挂

​常用在​​:

  • 支付结果通知(比如支付宝回调)
  • GitHub代码提交触发CI/CD
  • 各种第三方服务集成

5、全面对比表

技术指标 HTTP短轮询 HTTP长轮询 SSE (Server-Sent Events) WebSocket Webhooks
​通信方向​ 客户端→服务器 客户端→服务器 服务器→客户端 双向全双工 服务器→客户端
​协议基础​ HTTP HTTP HTTP 独立协议(ws/wss) HTTP
​连接方式​ 短连接 长连接 持久连接 持久连接 反向HTTP调用
​实时性​ 低(依赖轮询间隔) 中(减少轮询间隔) 极高
​数据格式​ 任意 任意 文本(Event Stream) 文本/二进制 任意
​实现复杂度​ ★★☆☆☆ ★★★☆☆ ★★★★☆ ★★★★★ ★★★☆☆
​兼容性​ 全平台 全平台 现代浏览器 现代浏览器 全平台
​服务器压力​ 高(频繁请求) 中(保持连接) 中(维护连接) 取决于回调频率
​客户端压力​ 中(需管理连接) 需部署服务端
​流量消耗​ 高(大量请求头) 低(复用连接) 极低
​自动重连​ 需手动实现 需手动实现 内置支持 需手动实现 需手动实现
​数据安全性​ 标准HTTPS 标准HTTPS 标准HTTPS WSS加密 需额外验证
​适用场景​ 简单通知,低频更新 中等实时性要求 实时通知推送 高频双向交互 服务器触发的外部通知
​典型应用​ 简单消息提醒 基础聊天功能 股票行情、新闻推送 在线游戏、IM应用 支付回调、CI/CD触发
​实现示例​ 定时AJAX请求 挂起HTTP请求 EventSource API WebSocket API 提供回调URL端点

6、补充说明

​渐进增强策略​​:

  • 优先考虑:WebSocket > SSE > 长轮询 > 短轮询
  • 回退方案:可考虑功能检测后自动降级

​混合使用场景​​:

  • WebSocket + Webhooks:用于不同业务场景
  • SSE + 短轮询:兼容性方案

​性能考量​​:

  • 万级连接:WebSocket ≈ SSE > 长轮询 ≫ 短轮询
  • 带宽消耗:短轮询 > 长轮询 > Webhooks > SSE > WebSocket

​移动端特别提示​​:

  • 注意移动网络下的连接稳定性
  • 考虑省电模式对长连接的影响

​安全建议​​:

  • 所有技术都应使用加密版本(wss/https)
  • Webhooks必须实现签名验证
  • 限制连接频率防止DDoS
相关推荐
编程猪猪侠9 分钟前
Tailwind CSS 自定义工具类与主题配置指南
前端·css
qhd吴飞13 分钟前
mybatis 差异更新法
java·前端·mybatis
YGY Webgis糕手之路35 分钟前
OpenLayers 快速入门(九)Extent 介绍
前端·经验分享·笔记·vue·web
患得患失94937 分钟前
【前端】【vueDevTools】使用 vueDevTools 插件并修改默认打开编辑器
前端·编辑器
ReturnTrue86838 分钟前
Vue路由状态持久化方案,优雅实现记住表单历史搜索记录!
前端·vue.js
未来之窗软件服务39 分钟前
跨平台 WebSocket 服务器的设计与实现 —— 基于.NET 8 的跨操作系统解决方案linux,macos,windows——开发工具
linux·服务器·websocket·仙盟创梦ide·东方仙盟
UncleKyrie43 分钟前
一个浏览器插件帮你查看Figma设计稿代码图片和转码
前端
遂心_1 小时前
深入解析前后端分离中的 /api 设计:从路由到代理的完整指南
前端·javascript·api
你听得到111 小时前
Flutter - 手搓一个日历组件,集成单日选择、日期范围选择、国际化、农历和节气显示
前端·flutter·架构
风清云淡_A1 小时前
【REACT18.x】CRA+TS+ANTD5.X封装自定义的hooks复用业务功能
前端·react.js