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

发布于:2025-05-18 ⋅ 阅读:(20) ⋅ 点赞:(0)

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

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

短轮询:勤快但费劲

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

专业一点的说法:

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

​优点​​:

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

​缺点​​:

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

长轮询:聪明一点的做法

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

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

  1. 客户端发送请求到服务器
  2. 服务器保持连接打开,直到有新数据或超时
  3. 一旦有数据或超时,服务器响应
  4. 客户端收到响应后立即发起新请求


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. 自动处理连接中断和重连

// 前端
const eventSource = new EventSource('/sse-endpoint');

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

​爽点​​:

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

​不爽的地方​​:

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

​适合场景​​:

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

3. WebSocket:真正的双向通话

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

  1. 独立协议(ws://或加密wss://)
  2. 通过HTTP升级握手建立连接
  3. 之后保持持久连接双向通信

// 前端
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. 接收方处理事件并返回响应

// 你的服务器接口
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、补充说明

  1. ​渐进增强策略​​:

    • 优先考虑:WebSocket > SSE > 长轮询 > 短轮询
    • 回退方案:可考虑功能检测后自动降级
  2. ​混合使用场景​​:

    • WebSocket + Webhooks:用于不同业务场景
    • SSE + 短轮询:兼容性方案
  3. ​性能考量​​:

    • 万级连接:WebSocket ≈ SSE > 长轮询 ≫ 短轮询
    • 带宽消耗:短轮询 > 长轮询 > Webhooks > SSE > WebSocket
  4. ​移动端特别提示​​:

    • 注意移动网络下的连接稳定性
    • 考虑省电模式对长连接的影响
  5. ​安全建议​​:

    • 所有技术都应使用加密版本(wss/https)
    • Webhooks必须实现签名验证
    • 限制连接频率防止DDoS

    网站公告

    今日签到

    点亮在社区的每一天
    去签到