WebSocket 保持连接的核心目标是防止连接被意外断开(如超时、网络波动、代理/NAT 等),同时保证连接健康可用。下面从原理、常见做法、代码示例、注意事项几个方面说明。
即使 WebSocket 是“长连接”,也可能因为以下原因断开:
网络层断开
无数据发送被中间设备断开
服务器或客户端主动关闭
close()异常错误
这是最重要、最常见的方式。
连接断开后:
onclose / onerrorlet ws = null;
let heartbeatTimer = null;
let reconnectTimer = null;
function connect() {
ws = new WebSocket("wss://example.com/ws");
ws.onopen = () => {
console.log("connected");
startHeartbeat();
};
ws.onmessage = (event) => {
if (event.data === "pong") {
console.log("heartbeat ok");
} else {
console.log("message:", event.data);
}
};
ws.onclose = () => {
console.log("disconnected");
stopHeartbeat();
reconnect();
};
ws.onerror = (err) => {
console.error("error", err);
};
}
function startHeartbeat() {
heartbeatTimer = setInterval(() => {
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send("ping");
}
}, 30000); // 30 秒
}
function stopHeartbeat() {
clearInterval(heartbeatTimer);
}
function reconnect() {
if (reconnectTimer) return;
reconnectTimer = setTimeout(() => {
reconnectTimer = null;
connect();
}, 3000); // 3 秒后重连
}
connect();
const WebSocket = require("ws");
const wss = new WebSocket.Server({ port: 8080 });
wss.on("connection", (ws) => {
ws.isAlive = true;
ws.on("pong", () => {
ws.isAlive = true;
});
ws.on("message", (msg) => {
if (msg === "ping") {
ws.send("pong");
}
});
});
// 每 30 秒检查一次
setInterval(() => {
wss.clients.forEach((ws) => {
if (!ws.isAlive) {
return ws.terminate();
}
ws.isAlive = false;
ws.ping();
});
}, 30000);
| 项目 | 建议 |
|---|---|
| 心跳间隔 | 20–30 秒 |
| 重连策略 | 指数退避 |
| 最大重连次数 | 可无限,但加上限 |
| 心跳内容 | 简短(ping/pong) |
| 网络切换 | 监听 online/offline |
window.addEventListener("online", () => {
console.log("网络恢复,重连");
connect();
});
❌ 只靠 TCP 长连接
❌ 心跳间隔太长(> 1–2 分钟)
❌ 重连无延迟(瞬间打爆服务器)
❌ 心跳和业务消息混在一起
WebSocket 保持连接 = 心跳 + 重连 + 超时控制
如果你有具体场景,比如:
可以告诉我,我可以给你更贴近实战的方案。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。