【问题标题】:Why NodeJS KeepAlive does not seem to work as expected?为什么 NodeJS KeepAlive 似乎没有按预期工作?
【发布时间】:2023-04-04 15:31:01
【问题描述】:

引用自TCP keepalive HowTo

为了了解 TCP keepalive(我们将称之为 keepalive) 确实如此,您只需要读取名称:keep TCP 活。这意味着您将能够检查连接的套接字 (也称为 TCP 套接字),并判断连接是否 仍在运行或如果已损坏

那么为什么当互联网连接中断时,下面的代码没有抛出任何东西

var tls = require('tls');

var socket = tls.connect(443, "google.com", function connected() {
  console.log('connected');
});

socket.setNoDelay(true);
socket.setKeepAlive(true, 0);
socket.setTimeout(0, function(){
  console.log('timeout');
});
socket.on('data', function(data) {
  console.log(data);
});
socket.on('close', function() {
  console.error("close");
});
socket.on('error', function(err) {
  console.error("error", err);
});

在 MacOS/Debian 上测试,使用 NodeJS v0.10.17

【问题讨论】:

    标签: node.js sockets tcp


    【解决方案1】:

    引用man 7 tcp:

    tcp_keepalive_time(整数;默认值:7200;从 Linux 2.2 开始)

    在 TCP 开始发送保持活动探测之前连接需要空闲的秒数。仅当启用 SO_KEEPALIVE 套接字选项时才发送保持活动状态。默认值为 7200 秒(2 小时)。启用 keep-alive 后,空闲连接会在大约 另外 11 分钟(9 次探测间隔 75 秒)后终止。

    所以大约 10 分钟后(在 MacOS 10.8 上)节点发出错误:

    error { [Error: read ETIMEDOUT] code: 'ETIMEDOUT', errno: 'ETIMEDOUT', syscall: 'read' }
    

    【讨论】:

      【解决方案2】:

      https://www.npmjs.com/package/net-keepalive

      这是一个模块,可让您根据每个套接字配置 TCP_KEEPINTVL 和 TCP_KEEPCNT。

      提供对 TCP_KEEPIDLE 等套接字选项的高级访问, TCP_KEEPINTVL, TCP_KEEPCNT

      var Net = require('net')
        , NetKeepAlive = require('net-keepalive')
      ;
      
      // Create a TCP Server
      var srv = Net.createServer(function(s){>
        console.log('Connected %j', s.address())
        // Doesn't matter what it does
        s.pipe(s)
      });
      
      // Start on some port
      srv.listen(1337, function(){
        console.log('Listening on %j', srv.address())
      });
      
      // Connect to that server
      var s = Net.createConnection({port:1337}, function(){
        console.log('Connected to %j', s.address())
      
        //IMPORTANT: KeepAlive must be enabled for this to work
        s.setKeepAlive(true, 1000)
      
        // Set TCP_KEEPINTVL for this specific socket
        NetKeepAlive.setKeepAliveInterval(s, 1000)
      
        // and TCP_KEEPCNT
        NetKeepAlive.setKeepAliveProbes(s, 1)
      });
      

      【讨论】:

        猜你喜欢
        • 2011-11-20
        • 2020-09-15
        • 2016-01-24
        • 1970-01-01
        • 2022-12-17
        • 2021-06-07
        • 2013-02-10
        • 2019-04-24
        • 1970-01-01
        相关资源
        最近更新 更多