跳到主要内容

heartbeatMechanism

2024年10月18日
柏拉文
越努力,越幸运

一、认识


WebSocket 心跳机制 是一种通过定期发送心跳消息来检查连接状态的方法。它确保客户端和服务器之间的连接保持活跃,并能够及时发现断开的连接。WebSocket 心跳机制 可以解决如下问题:

  1. 连接有效性: 确保连接仍然存在,防止因网络问题导致的静默断开。

  2. 资源管理: 及时关闭不再活跃的连接,释放服务器资源。

  3. 提高稳定性: 提高系统的稳定性和用户体验,避免因连接问题导致的消息丢失或延迟。

二、工作


  1. 定时发送心跳: 服务器(或客户端)定期发送心跳消息(如ping)到对方。

  2. 接收和回应: 接收方在收到心跳消息后,返回一个回应(如pong)。

  3. 检测连接状态: 如果在预定时间内未收到回应,发送方可以推测连接已断开并进行相应处理(如重连、关闭连接等)

三、实现


3.1 服务端

const Koa = require("koa");
const HTTP = require("http");
const WebSocket = require("ws");
const KoaRouter = require("koa-router");

const app = new Koa();
const router = new KoaRouter();
const server = HTTP.createServer(app.callback());
const wss = new WebSocket.Server({ server });

const HEARTBEAT_INTERVAL = 30000; // 心跳间隔时间

// 心跳机制,定期检查连接
function setupHeartbeat(webSocket) {
webSocket.isAlive = true; // 初始化心跳状态

const interval = setInterval(() => {
if (webSocket.isAlive === false) {
console.log("Terminating WebSocket due to no heartbeat response.");
return webSocket.terminate(); // 终止连接
}
webSocket.isAlive = false; // 设置为 false,等待响应
webSocket.ping(); // 发送 ping
}, HEARTBEAT_INTERVAL); // 每隔 HEARTBEAT_INTERVAL 秒检查一次

webSocket.on("pong", () => {
console.log("WebSockete pong received.");
webSocket.isAlive = true; // 收到心跳回应
});

webSocket.on("close", () => {
console.log("WebSocket closed 002");
clearInterval(interval); // 清除心跳检查
});
}

// WebSocket 连接处理
wss.on("connection", (ws) => {
setupHeartbeat(ws); // 设置心跳机制

ws.on("message", (message) => {
console.log("Received message:", message);
});

ws.on("close", () => {
console.log("WebSocket closed 001");
});
});

router.get("/", (ctx) => {
ctx.body = "WebSocket Server Running";
});

app.use(router.routes()).use(router.allowedMethods());

server.listen(3000, () => {
console.log("Server started on port 3000");
});

3.2 客户端

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h1>WebSocket Heartbeat Example</h1>
<div id="status">Connecting...</div>

<script>
const socket = new WebSocket("ws://localhost:3000");

socket.addEventListener("open", () => {
document.getElementById("status").textContent = "Connected";
console.log("WebSocket connection established");
});

socket.addEventListener("message", (event) => {
const data = JSON.parse(event.data);
// 不需要处理 heartbeat 相关的消息
});

socket.addEventListener("close", () => {
document.getElementById("status").textContent = "Disconnected";
console.log("WebSocket connection closed");
});

socket.addEventListener("error", (error) => {
console.error("WebSocket error:", error);
});
</script>
</body>
</html>