温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

WebSocket如何保持连接

发布时间:2026-07-25 15:14:20 来源:亿速云 阅读:85 作者:小樊 栏目:软件技术

WebSocket 保持连接的核心目标是防止连接被意外断开(如超时、网络波动、代理/NAT 等),同时保证连接健康可用。下面从原理、常见做法、代码示例、注意事项几个方面说明。


一、WebSocket 连接为什么会断?

即使 WebSocket 是“长连接”,也可能因为以下原因断开:

  1. 网络层断开

    • 客户端/服务器网络切换
    • Wi‑Fi / 4G 切换
    • 代理、NAT、防火墙超时(常见 60s / 300s)
  2. 无数据发送被中间设备断开

    • 很多网关会断开“长时间无数据”的 TCP 连接
  3. 服务器或客户端主动关闭

    • 服务重启
    • 代码调用 close()
  4. 异常错误

    • 协议错误
    • 心跳失败

二、保持 WebSocket 连接的核心方法 ✅

✅ 1. 使用 心跳(Ping / Pong)

这是最重要、最常见的方式。

原理

  • 客户端或服务器定期发送 Ping 帧
  • 对方返回 Pong 帧
  • 如果多次未收到 Pong → 认为连接已断 → 重连

特点

  • Ping / Pong 是 WebSocket 协议层帧
  • 不会污染业务数据
  • 大多数 WebSocket 库都支持

✅ 2. 客户端自动重连(Reconnect)

连接断开后:

  • 监听 onclose / onerror
  • 使用 指数退避 重连

✅ 3. 合理的超时与清理机制

  • 设置心跳间隔(如 30s)
  • 设置最大失败次数(如 3 次)
  • 超过阈值再重连

三、前端示例(浏览器)

基础 WebSocket + 心跳 + 重连

let 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();

四、后端示例(Node.js + ws)

服务端心跳

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 保持连接 = 心跳 + 重连 + 超时控制

如果你有具体场景,比如:

  • 小程序 / UniApp
  • React Native
  • Spring Boot / Netty
  • 高并发 IM / 推送系统

可以告诉我,我可以给你更贴近实战的方案

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI