前端 Node + WebSocket 通讯,这才是更优解(附完整 Demo)
·
前端 Node + WebSocket 通讯,这才是更优解(附完整 Demo)
别再用轮询了,WebSocket 才是正道(踩过坑的人都懂)
一、为什么我一开始会被“实时通讯”折磨?
说个真实经历。
之前做一个实时地图(WebGIS那种),要显示设备位置变化。一开始我用的是轮询接口:每隔 3 秒请求一次。
结果呢?
- 数据延迟:3 秒起步(用户:你这地图是“回忆版”?)
- 请求压力大:设备一多,后端直接“喘不过气”
- 前端还要自己控制节流、防抖……写着写着就开始怀疑人生
后来我换成了 WebSocket。
一句话总结:早用早轻松,晚用多踩坑。
二、WebSocket 到底解决了什么问题?
先说核心:
👉 WebSocket 是一个全双工通信协议
也就是说:
- 客户端可以主动发
- 服务端也可以主动推
- 不用每次都 HTTP 请求
对比一下:
| 方案 | 问题 |
|---|---|
| 轮询 | 浪费资源 + 延迟 |
| 长轮询 | 勉强能用,但复杂 |
| WebSocket | 真·实时 |
三、原理讲清楚(不讲你迟早踩坑)
WebSocket 本质流程:
- 通过 HTTP 发起请求(握手)
- 升级协议(Upgrade: websocket)
- 建立长连接
- 双方随时通信
重点在这里:
👉 连接一旦建立,就不会断(除非你断)
所以你可以理解为:
HTTP 是“一次性聊天”,WebSocket 是“开了个微信群”
四、Node.js 实现 WebSocket 服务端(超简单)
我们用最常见的库:
👉 ws
1、安装依赖
npm install ws
2、服务端代码(完整可跑)
// server.js
const WebSocket = require('ws');
// 创建 WebSocket 服务
const wss = new WebSocket.Server({ port: 3000 });
console.log('WebSocket 服务已启动 ws://localhost:3000');
wss.on('connection', (ws) => {
console.log('客户端已连接');
// 发送欢迎消息
ws.send(JSON.stringify({
type: 'welcome',
message: '连接成功'
}));
// 接收消息
ws.on('message', (message) => {
console.log('收到消息:', message.toString());
// 广播给所有客户端
wss.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(message.toString());
}
});
});
// 断开连接
ws.on('close', () => {
console.log('客户端断开连接');
});
});
五、前端 WebSocket 使用(浏览器原生)
不用任何库,浏览器自带。
1、连接服务
const ws = new WebSocket('ws://localhost:3000');
ws.onopen = () => {
console.log('连接成功');
ws.send(JSON.stringify({
type: 'hello',
message: '前端来了'
}));
};
2、接收消息
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('收到服务端消息:', data);
};
3、断开连接
ws.onclose = () => {
console.log('连接关闭');
};
六、实战:WebGIS 实时点位更新(OpenLayers)
来点实际的,不然容易“看懂了但不会用”。
场景
- 后端推送设备坐标
- 前端实时更新地图点位
1、模拟服务端推送数据
setInterval(() => {
const data = {
type: 'location',
lng: 116.39 + Math.random() * 0.01,
lat: 39.9 + Math.random() * 0.01
};
wss.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(data));
}
});
}, 2000);
2、前端更新地图(OpenLayers)
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'location') {
const coord = ol.proj.fromLonLat([data.lng, data.lat]);
feature.setGeometry(new ol.geom.Point(coord));
}
};
效果:
👉 地图上的点会“自己动”,不用刷新
这就是 WebSocket 的爽点。
七、我踩过的坑(你可以直接避开)
1、连接断了你都不知道
浏览器不会帮你自动重连!
👉 解决:
function connect() {
const ws = new WebSocket('ws://localhost:3000');
ws.onclose = () => {
console.log('重连中...');
setTimeout(connect, 2000);
};
}
connect();
2、心跳机制(非常重要)
有些服务器(或代理)会断掉“空闲连接”。
👉 解决:
setInterval(() => {
ws.send(JSON.stringify({ type: 'ping' }));
}, 30000);
3、数据格式混乱
刚开始我直接传字符串,后来全乱套。
👉 建议:
统一格式:
{
"type": "xxx",
"data": {}
}
4、客户端太多,服务器扛不住
WebSocket 是“长连接”,不是免费的。
👉 建议:
- 做连接限制
- 用 Redis 做消息分发
- 或直接上 Socket.IO + 集群
八、什么时候你该用 WebSocket?
直接给你一个判断标准:
👉 满足以下任意一个,就该用:
- 实时地图(GIS)
- 聊天系统
- 实时监控
- 股票/行情
- 在线协同
否则:
👉 别滥用(普通 CRUD 真没必要)
九、总结(说点人话)
- WebSocket 不是“更高级”,而是更合适
- 核心价值:服务端主动推送
- 最大坑点:断线、心跳、扩展性
我当时从轮询切到 WebSocket 的时候,有种感觉:
“原来不是我不会写代码,是我选错了工具…”
最后一句(有点重要):
👉 理解通信模型,比背 API 有用一百倍
如果这篇文章对你有帮助,欢迎点赞 👍 收藏 ⭐ 关注 👀
完结,撒花✿✿ヽ(°▽°)ノ✿
更多推荐




所有评论(0)