在现代 Web 应用中,即时通讯 是不可或缺的功能之一,例如:在线客服、社交聊天、实时监控、协同编辑等场景都依赖它。
前端实现即时通讯的常见技术包括:
⏱ 短轮询(Short Polling)
⏳ 长轮询(Long Polling)
SSE(Server-Sent Events)
WebSocket
接下来我们逐一介绍这几种方式的原理、代码示例、优缺点以及应用场景。
客户端周期性发送请求,询问服务器是否有新消息。流程如下:
客户端每隔几秒用 setInterval()
发一次请求;
服务器立即响应当前是否有新数据;
客户端处理返回结果;
循环上述过程。
setInterval(() => {
fetch('/api/messages')
.then(res => res.json())
.then(data => {
if (data.newMessages) {
updateUI(data.messages);
}
});
}, 3000); // 每3秒轮询
实现简单;
兼容性强。
请求频繁,消耗资源;
延迟较高,不够实时。
客户端发出请求;
若服务器没有数据,保持连接不返回;
一旦有数据或超时,立即响应;
客户端收到数据后立即再次发请求。
app.get('/long-poll', (req, res) => {
waitForMessageOrTimeout().then(message => {
res.json({ message });
});
});
function poll() {
fetch('/long-poll')
.then(res => res.json())
.then(data => {
handleMessage(data.message);
poll(); // 继续请求
});
}
poll();
接近实时;
比短轮询更省资源。
服务端需处理连接挂起;
不支持双向通信。
服务端通过一个持续的 HTTP 连接推送事件流给客户端。
app.get('/events', (req, res) => {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Connection', 'keep-alive');
setInterval(() => {
res.write(`data: ${JSON.stringify({ time: Date.now() })}\n\n`);
}, 2000);
});
const eventSource = new EventSource('/events');
eventSource.onmessage = function(event) {
console.log('新事件:', event.data);
};
实现简单;
自动断线重连;
适合实时推送(如通知系统)。
单向通信;
不支持 IE;
仅支持文本格式。
WebSocket 是在 HTTP 握手基础上建立的 TCP 持久连接,支持全双工通信。
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });
server.on('connection', socket => {
socket.on('message', msg => {
console.log('客户端消息:', msg);
socket.send('收到啦');
});
});
const socket = new WebSocket('ws://localhost:8080');
socket.onmessage = event => console.log('服务器消息:', event.data);
socket.send('你好,服务器');
真·实时双向通信;
支持二进制/文本;
网络开销小、性能高。
状态维护复杂;
部分代理网络可能阻断;
安全性需要额外关注(如身份认证、攻击防范)。
特性 | WebSocket | SSE(Server-Sent Events) |
---|---|---|
通信方向 | 双向 | 单向(服务器 -> 客户端) |
协议 | TCP + 自定义协议 | 基于 HTTP/1.1 |
数据类型 | 文本 + 二进制 | 仅支持文本 |
自动重连 | ❌ 手动实现 | ✅ 默认支持 |
浏览器支持 | ✅ 全面支持 | 部分旧浏览器不支持 |
实现复杂度 | 较高 | 简单 |
应用场景 | 聊天、游戏、协同编辑 | 推送通知、状态更新、日志流等 |
需求 | 推荐方案 |
---|---|
高实时双向通信 | ✅ WebSocket |
单向实时推送(轻量级) | ✅ SSE |
实现简单,无需后端支持 | ✅ 短轮询 |
有实时需求,轻负载方案 | ✅ 长轮询 |
不同的即时通讯技术适用于不同的业务场景:
若你的应用是聊天室、游戏、实时协同编辑,推荐使用 WebSocket;
若是系统通知、股票行情、直播弹幕,可以优先考虑 SSE;
若项目初期不方便配置服务端支持,可用 长轮询/短轮询 简单实现。
MDN WebSocket
MDN EventSource (SSE)
Node.js ws 库文档
HTML Living Standard - Server-sent events