WebSocket 与实时功能实现指南:聊天、通知与实时更新
实时功能已经成为现代网站的常见需求——在线客服、实时通知、协作文档编辑。实现这些功能的核心技术是 WebSocket。
WebSocket vs SSE vs 轮询
| 特性 | 轮询 | SSE | WebSocket |
|---|---|---|---|
| 通信方向 | 客户端→服务端 | 服务端→客户端 | 双向 |
| 实时性 | 取决于轮询间隔 | 即时 | 即时 |
| 连接开销 | 每次请求都有 | 保持长连接 | 保持长连接 |
| 浏览器支持 | 所有 | 除 IE 外 | 除 IE 外 |
| 适用场景 | 简单定时刷新 | 推送通知 | 双向交互 |
WebSocket 服务端(Node.js + ws)
npm install ws
// server.js
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });
const clients = new Set();
server.on('connection', (ws) => {
clients.add(ws);
console.log('Client connected. Total:', clients.size);
// 接收消息
ws.on('message', (message) => {
const data = JSON.parse(message);
// 广播给所有客户端
clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify({
type: 'message',
user: data.user,
content: data.content,
time: new Date().toISOString()
}));
}
});
});
// 断开连接
ws.on('close', () => {
clients.delete(ws);
console.log('Client disconnected. Total:', clients.size);
});
});
console.log('WebSocket server running on port 8080');
WebSocket 客户端
// 连接到 WebSocket 服务
const ws = new WebSocket('wss://example.com/ws');
// 连接打开
ws.addEventListener('open', () => {
console.log('Connected');
// 发送消息
ws.send(JSON.stringify({
user: 'Alice',
content: 'Hello everyone!'
}));
});
// 接收消息
ws.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
displayMessage(data.user, data.content);
});
// 连接关闭
ws.addEventListener('close', () => {
console.log('Disconnected');
// 自动重连(简单实现)
setTimeout(() => {
window.location.reload();
}, 3000);
});
// 错误处理
ws.addEventListener('error', (error) => {
console.error('WebSocket error:', error);
});
SSE(Server-Sent Events)方案
如果只需要服务端推送(不需要客户端发送),SSE 是更简单的选择:
// 服务端(Node.js)
app.get('/events', (req, res) => {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
});
// 每秒推送当前时间
setInterval(() => {
res.write(`data: ${JSON.stringify({ time: new Date().toISOString() })}\n\n`);
}, 1000);
});
// 客户端
const eventSource = new EventSource('/events');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Server time:', data.time);
};
部署注意事项
- Nginx 代理 WebSocket — 需要配置 Upgrade header
- 自动重连机制 — WebSocket 连接可能意外断开
- 连接管理 — 记录在线用户数,限制连接数
- 扩展性 — 多服务器环境需使用 Redis Pub/Sub 转发消息
16IDC 观察
如果你只需要服务端推送通知(如新评论、订单状态更新),SSE 比 WebSocket 更简单、兼容性更好。如果需要双向交互(如在线客服、协作编辑),WebSocket 是唯一选择。