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

时间:2014-05-15 00:11:27

标签: node.js https timeout

如果超过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();

这是我在3s之后得到的:

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 个答案:

答案 0 :(得分:1)

您需要在连接上设置超时:

req.connection.setTimeout(3000);

此超时会将套接字状态从ESTABLISHED更改为FIN_WAIT1和FIN_WAIT2。

在Ubuntu中,FIN_WAIT套接字状态的默认超时为60秒,因此如果没有收到任何流量,则套接字关闭的总时间为63秒。如果套接字接收流量,则超时将重新开始。

如果你需要在3秒内关闭套接字,我猜你必须将连接超时设置为3000ms并降低内核tcp fin等待超时。