新手求助:如何在JS中发送WebSocket心跳Ping消息?
实现WebSocket保活与服务器在线检测
现在这个需求完全可以实现,现代浏览器的WebSocket API原生支持Ping/Pong机制,再加上你用的axum WebSocket会自动响应Ping,正好能满足你的需求。下面是具体实现步骤:
1. 核心思路
反向代理5分钟无消息会断开连接,所以我们需要每隔小于5分钟的时间(比如30秒)发送标准的Ping帧,既保持连接存活,又能通过服务器回复的Pong帧判断服务器是否在线。
2. 完整代码实现
基于你现有的代码,添加定时Ping和状态检测逻辑:
const loc = window.location; const protocol = loc.protocol === "https:" ? "wss:" : "ws:"; const ws = new WebSocket(protocol + "//" + loc.host + loc.pathname + "/../ws"); // 配置参数:每隔X秒发一次Ping,建议设为5分钟的一半以内,比如30秒 const PING_INTERVAL = 30 * 1000; // 超时时间:如果超过这个时间没收到Pong,判定服务器离线 const PONG_TIMEOUT = 10 * 1000; let pingTimer = null; let pongTimeoutTimer = null; // 发送Ping的函数 function sendPing() { // 只有连接处于OPEN状态时才发送Ping if (ws.readyState === WebSocket.OPEN) { ws.ping(); // 发送标准Ping帧,不是用send()发文本 // 设置Pong超时检测 pongTimeoutTimer = setTimeout(() => { console.log("服务器无响应,判定离线"); // 这里可以添加离线后的处理逻辑,比如提示用户、尝试重连等 ws.close(); }, PONG_TIMEOUT); } } // 监听Pong响应 ws.onpong = () => { console.log("收到服务器Pong响应,连接正常"); // 收到Pong后清除超时计时器 clearTimeout(pongTimeoutTimer); }; // 连接成功后启动定时Ping ws.onopen = () => { console.log("WebSocket连接成功"); pingTimer = setInterval(sendPing, PING_INTERVAL); }; // 连接关闭时清除所有定时器 ws.onclose = () => { console.log("WebSocket连接关闭"); clearInterval(pingTimer); clearTimeout(pongTimeoutTimer); }; // 连接出错时同样清除定时器 ws.onerror = (error) => { console.error("WebSocket出错:", error); clearInterval(pingTimer); clearTimeout(pongTimeoutTimer); }; // 你原有的发送消息代码保持不变 // ws.send(JSON.stringify(jsonMessage));
3. 关键细节说明
- 用
ws.ping()而非send():ping()发送的是WebSocket标准控制帧,axum会自动回复Pong帧;如果用send()发字符串"ping",属于业务消息,需要服务器额外处理,没必要。 - 定时器清理:必须在连接关闭、出错时清除定时器,否则会导致无效的Ping发送,甚至内存泄漏。
- 超时时间设置:
PONG_TIMEOUT要小于PING_INTERVAL,比如Ping每30秒发一次,超时设为10秒,确保下一次Ping发送前能检测到是否收到Pong。
内容的提问来源于stack exchange,提问作者DJDuque
相关产品推荐
相关产品推荐

