Nodejs HTTPS客户端超时未关闭TCP连接

3
我需要在连接时间超过3秒时关闭http连接,这是我的代码:
var options = {
  host: 'google.com',
  port: '81',
  path: ''
};

callback = function(response) {
  var str = '';

  response.on('data', function (chunk) {
    str += chunk;
  });

  response.on('end', function () {
    console.log(str);
  });

  response.on('error', function () {
    console.log('ERROR!');
  });
}

var req = https.request(options, callback);

req.on('socket', function(socket) {
  socket.setTimeout(3000);
  socket.on('timeout', function() {
    console.log('Call timed out!');
    req.abort();
    //req.end();
    //req.destroy();
  });
});

req.on('error', function(err) {
  console.log('REQUEST ERROR');
  console.dir(err);
    req.abort();
    //req.end();
});

req.end();

这是我在3秒后得到的结果:
Call timed out!
REQUEST ERROR
{ [Error: socket hang up] code: 'ECONNRESET' }

通过使用 lsof | grep TCP | wc -l 命令,我可以看到TCP连接仍然保持打开状态,即使在收到“超时”事件后。最终,我会得到以下结果并关闭连接:

REQUEST ERROR
{ [Error: connect ETIMEDOUT] code: 'ETIMEDOUT', errno: 'ETIMEDOUT', syscall: 'connect' }

有人知道这是为什么吗?为什么调用req.abort()req.end()req.destory()不能关闭连接?这是因为我在套接字上设置了超时,而不是在实际的HTTP调用上吗?如果是,我该如何关闭连接?

1个回答

1

你需要在连接上设置超时时间:

req.connection.setTimeout(3000);

这个超时时间会将套接字状态从“已建立”更改为“等待结束1”和“等待结束2”。
在Ubuntu中,“等待结束”套接字状态的默认超时时间为60秒,因此如果它没有收到任何流量,则套接字关闭的总时间为63秒。如果套接字接收到流量,超时时间将重新开始。
如果您需要在3秒内关闭套接字,则必须将连接超时设置为3000毫秒,并降低内核TCP结束等待超时时间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接