最近面试一家公司,问到了websocket的心跳监测,太久没用很多都不记得了;特来复盘一下;

首先,什么是websocket心跳监测?

心跳监测是一种用于保持Websocket连接活跃的机制,它的主要目的是监测连接是否仍然有效,并在连接断开时及时采取措施(如重连),心跳监测通常通过定期发送和接收小型数据包(称为心跳包或Ping或Pong帧)来实现;

为什么需要心跳监测?

Websocket是一种全双工通信协议,客户端和服务器之间建立持久连接后,可以随时发送和接收数据,然而在实际应用中,可能会遇到以下问题:

1.连接断开:因为网络不稳定或服务器故障导致连接断开,或者是因为客户端或服务端长时间没有数据传输时,中间设备(如防火墙,代理服务器)可能会主动关闭连接;2.资源浪费:如果连接已经断开,但是服务端和客户端没有及时监测到,可能会导致资源浪费;

所以心跳监测的作用是:

  • 检测连接状态:通过定期发送心跳包,确认连接是否仍然连接;
  • 保持连接活跃:防止中间设备因长时间无数据传输而关闭连接;
  • 及时重连:在连接断开时,客户端可以快速尝试重新连接;

WebSocket心跳监测的实现方式

  1. 使用Ping/Pong帧

WebSocket协议提供了Ping和Pong帧,用于心跳检测,

PIng帧:由一端(客户端或服务器)发送,用于检测连接是否仍然有效;

Pong帧:另一端收到Ping帧后,必须回复Pong帧;

特点是:Ping/Pong帧是WebSocket协议的一部分,不需要额外实现;Ping/Pong帧是轻量级的,不会对性能造成显著影响;

     

// 服务器发送 Ping 帧
setInterval(() => {
  if (websocket.readyState === WebSocket.OPEN) {
    websocket.ping();
  }
}, 30000); // 每 30 秒发送一次 Ping 帧

// 客户端监听 Pong 帧
websocket.on("pong", () => {
  console.log("Received Pong frame");
});

2.自定义心跳包

自定义心跳包的话就需要包括:

  • 客户端和服务端约定一个特定的消息格式(如:{“type” : "heartbeat"});
  • 定期发送心跳包,并等待对方的响应;

特点 :需要手动处理心跳包发送和接收逻辑,灵活性高,可以根据需求自定义心跳包的内容和频率;

// 客户端发送心跳包
setInterval(() => {
  if (websocket.readyState === WebSocket.OPEN) {
    websocket.send(JSON.stringify({ type: "heartbeat" }));
  }
}, 30000); // 每 30 秒发送一次心跳包

// 服务器响应心跳包
websocket.on("message", (data) => {
  const message = JSON.parse(data);
  if (message.type === "heartbeat") {
    websocket.send(JSON.stringify({ type: "heartbeat", status: "ok" }));
  }
});

心跳检测的特点

心跳间隔:心跳间隔不宜过短,否则会增加网络负担;也不宜过长,否则无法及时检测连接断开;通常设置为30-60秒;

超时检测:如果一定时间内没有收到心跳响应,则认为连接断开;超时时间通常为心跳间隔的2-3倍;

重连机制:在检测到连接断开后,客户端尝试重新连接;重连时可以使用指数退避策略,避免频繁重连; 

心跳检测的应用场景:

实时聊天应用;

在线游戏;

实时数据推送(天气预报,股票数据);

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐