当前位置: 首页 > news >正文

基于TCP Socket 实现心跳机制

在 Node.js 中使用 TCP Socket 实现心跳机制(Heartbeat)的核心目的是检测连接是否存活,避免因网络波动或客户端异常断开导致的"僵尸连接"。以下是详细实现步骤及代码示例:


1. **基本原理

  • 心跳机制:服务端定期向客户端发送探测消息(如 ping),客户端需响应 pong
  • 超时检测:若在指定时间内未收到响应,判定连接失效并主动关闭。
  • 重置计时器:每次正常通信(收到数据或心跳响应)时,重置超时检测。

2. 服务端实现(使用 net 模块)

const net = require('net');

// 创建 TCP 服务器
const server = net.createServer((socket) => {
  console.log('Client connected:', socket.remoteAddress);

  // 初始化心跳配置
  const HEARTBEAT_INTERVAL = 3000; // 3秒发送一次心跳
  const HEARTBEAT_TIMEOUT = 10000; // 10秒未响应则断开
  let heartbeatTimer = null;
  let timeoutTimer = null;

  // 发送心跳包
  const sendHeartbeat = () => {
    if (socket.writable) {
      socket.write('ping'); // 发送心跳标识
      console.log('Sent ping to client');
    }
  };

  // 启动心跳定时器
  const startHeartbeat = () => {
    heartbeatTimer = setInterval(sendHeartbeat, HEARTBEAT_INTERVAL);
    resetTimeout();
  };

  // 重置超时检测
  const resetTimeout = () => {
    if (timeoutTimer) clearTimeout(timeoutTimer);
    timeoutTimer = setTimeout(() => {
      console.log('Client timeout, closing connection');
      socket.destroy(); // 强制关闭连接
    }, HEARTBEAT_TIMEOUT);
  };

  // 监听客户端数据
  socket.on('data', (data) => {
    const message = data.toString();
    if (message === 'pong') {
      console.log('Received pong from client');
      resetTimeout(); // 收到响应,重置超时检测
    } else {
      console.log('Received data:', message);
      // 处理业务逻辑...
    }
  });

  // 启动心跳机制
  startHeartbeat();

  // 监听连接关闭
  socket.on('close', () => {
    console.log('Client disconnected');
    clearInterval(heartbeatTimer);
    clearTimeout(timeoutTimer);
  });

  // 错误处理
  socket.on('error', (err) => {
    console.error('Socket error:', err.message);
  });
});

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

3. 客户端实现(Node.js 客户端示例)

const net = require('net');

// 连接到服务端
const client = net.createConnection({ port: 3000 }, () => {
  console.log('Connected to server');
});

// 监听服务端数据
client.on('data', (data) => {
  const message = data.toString();
  if (message === 'ping') {
    console.log('Received ping from server');
    client.write('pong'); // 响应心跳
  } else {
    console.log('Received data:', message);
    // 处理业务逻辑...
  }
});

// 监听连接关闭
client.on('close', () => {
  console.log('Connection closed');
});

// 错误处理
client.on('error', (err) => {
  console.error('Connection error:', err.message);
});

4. 关键逻辑说明

  1. 心跳发送

    • 服务端每隔 HEARTBEAT_INTERVAL(如 3 秒)发送 ping
    • 客户端需响应 pong,否则服务端会触发超时关闭。
  2. 超时检测

    • 每次发送心跳或收到正常数据时,重置超时计时器。
    • HEARTBEAT_TIMEOUT(如 10 秒)内未收到响应,判定连接失效。
  3. 资源清理

    • 连接关闭时,清除所有定时器(clearIntervalclearTimeout)。

5. 优化建议

  • 协议设计:使用固定格式(如 HEARTBEAT|pong)区分心跳与业务数据。
  • 重连机制:客户端检测到连接关闭后,可自动重连。
  • 动态配置:根据网络状况动态调整心跳间隔和超时时间。
  • TCP Keep-Alive:可结合系统级 Keep-Alive(需手动启用):
    socket.setKeepAlive(true, 60000); // 1分钟无活动发送探测包
    

6. 测试验证

  1. 启动服务端和客户端。
  2. 观察控制台日志,确认心跳正常(pingpong 交替出现)。
  3. 手动断开客户端网络,服务端应在 10 秒后检测到超时并关闭连接。

总结

通过应用层心跳机制,可以有效检测 TCP 连接的存活性,避免因意外断开导致的资源泄漏。实际项目中可根据需求调整心跳间隔和超时阈值,并结合业务逻辑完善错误处理。

相关文章:

  • 【AI提示词】API开发专家
  • Python operator 模块介绍
  • 关于 Java 预先编译(AOT)技术的详细说明,涵盖 GraalVM 的配置、Spring Boot 3.x 的集成、使用示例及优缺点对比
  • (二十)安卓开发中的事件监听(Listener)的使用方法梳理
  • 【全队项目】智能学术海报生成系统PosterGenius--多智能体辩论
  • 高精地图地图匹配定位算法(二)
  • 如何绕过WAF实现SQL注入攻击?​
  • [Windows] 字体渲染 mactype v2025.4.11
  • 2 VS Code 配置指南:C 语言开发环境搭建(含 MinGW-w64 编译器及关键扩展)
  • Web攻防—SSRF服务端请求伪造Gopher伪协议无回显利用
  • CATIA高效工作指南——常规配置篇(一)
  • MyBatis-Plus 核心功能
  • 《2025蓝桥杯C++B组:D:产值调整》
  • 14 - VDMA彩条显示实验
  • 二叉树深度解析:从基础概念到算法实现与应用
  • 04--网络属性设置与多路复用
  • 【HD-RK3576-PI】VNC 远程桌面连接
  • Spark RDD算子详解:从入门到精通
  • Cygwin中链接非标准名动态库
  • 05--MQTT物联网协议
  • 图片做多的网站是哪个/怎么做一个网站平台
  • wordpress建站费用/百度地图推广电话
  • 网站建设公司苏州/网络推广一般怎么收费
  • 长春网站建设公司/网站批量查询工具
  • 网站网站制作服务/数字营销课程
  • 广州网站建设网站/最近重大新闻