← 返回目录

第 18 卷

第 18 / 21 卷日期:

  1. 客户端检测心跳响应:客户端发送心跳包后,启动超时计时器;若在超时阈值内收到服务端

的“pong”响应,则重置超时计时器;若未收到响应,则判定连接失效,主动关闭连接并触发重连;

  1. 连接关闭时清理计时器:在WebSocket的 close 或 error 事件中,清除心跳计时器和超时计时

器,避免内存泄漏。

  1. 前端代码示例(心跳实现)

Code block

1let ws;

2let heartbeatTimer = null; //心跳发送计时器
3let heartbeatTimeoutTimer = null; //心跳超时计时器
4const HEARTBEAT_INTERVAL = 30000; //心跳周期:30秒
5const HEARTBEAT_TIMEOUT = 10000; //心跳超时阈值:10秒

6 7function initWebSocket() {

8ws = new WebSocket("wss://example.com/chat");

9 10// 连接成功:启动心跳

11ws.addEventListener("open", () => {
12console.log("连接成功,启动心跳");
13startHeartbeat();
14});

15 16// 接收消息:检测心跳响应

17ws.addEventListener("message", (event) => {
18const data = JSON.parse(event.data);
19if (data.type === "pong") {
20//收到pong,重置超时计时器
21clearTimeout(heartbeatTimeoutTimer);
22console.log("心跳响应正常");
23} else {
24//处理业务消息
25handleBusinessData(data);
26}
27});

28 29// 连接关闭/错误:停止心跳

30ws.addEventListener("close", stopHeartbeat);

31ws.addEventListener("error", stopHeartbeat);

38 39// 周期性发送ping

40heartbeatTimer = setInterval(() => {
41if (ws.readyState === 1) { //确保连接处于打开状态
42ws.send(JSON.stringify({ type: "ping" }));
43console.log("发送心跳包");
44//启动超时检测
45heartbeatTimeoutTimer = setTimeout(() => {
46console.error("心跳超时,连接失效");
47ws.close(1006, "心跳超时"); // 1006:异常关闭码
48}, HEARTBEAT_TIMEOUT);
49}
50}, HEARTBEAT_INTERVAL);
51}

52 53// 停止心跳

54function stopHeartbeat() { 55clearInterval(heartbeatTimer);

56clearTimeout(heartbeatTimeoutTimer);
57heartbeatTimer = null;
58heartbeatTimeoutTimer = null;
59}

60 61initWebSocket();

二、断线重连机制:异常后自动恢复连接

断线重连的核心逻辑是“连接关闭后,延迟一定时间重试连接,限制最大重试次数,避免无限重试占用资源”,通常在心跳检测到连接失效、网络波动导致连接关闭时触发。

  1. 实现核心要素
  • 重连延迟:设置合理的重试间隔(如3秒),避免频繁重试加剧服务端压力;
  • 最大重试次数:限制重试上限(如10次),超过则停止重试,提示用户手动干预;

• 重连时机:仅在“异常关闭”时触发(如网络中断、心跳超时),正常关闭(如用户主动退出)不

触发;

  • 重连成功后恢复状态:重连成功后,需重新执行初始化操作(如用户登录认证、同步历史消息)。
  1. 完整实现流程
  1. 延迟重试连接:通过 setTimeout 实现延迟重连,每次重试后递增计数器;
  2. 重连成功/失败处理:重连成功则重置计数器,恢复心跳和业务状态;达到最大重试次数则停止重

试,提示用户。

  1. 前端代码示例(断线重连+心跳整合)

Code block

1let ws;

2let heartbeatTimer = null;

3let heartbeatTimeoutTimer = null;

4let reconnectTimer = null; // 重连定时器 5let reconnectCount = 0; // 重连次数

6 7// 配置参数

8const CONFIG = { 9wsUrl: "wss://example.com/chat",

10heartbeatInterval: 30000, 11heartbeatTimeout: 10000,

12reconnectDelay: 3000, 13maxReconnectCount: 10

14};

15 16// 初始化WebSocket

17function initWebSocket() { 18ws = new WebSocket(CONFIG.wsUrl);

19

20ws.addEventListener("open", () => {
21console.log("连接成功");
22reconnectCount = 0; //重置重连计数器
23startHeartbeat();
24//重连成功后恢复状态(如登录认证)
25loginAfterReconnect();
26});

27

28ws.addEventListener("message", (event) => {
29const data = JSON.parse(event.data);
30if (data.type === "pong") {
31clearTimeout(heartbeatTimeoutTimer);
32} else {
33handleBusinessData(data);
全站分卷索引 · 21 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷
  13. 13第 13 卷
  14. 14第 14 卷
  15. 15第 15 卷
  16. 16第 16 卷
  17. 17第 17 卷
  18. 18第 18 卷
  19. 19第 19 卷
  20. 20第 20 卷
  21. 21第 21 卷