2014-05-15 2 views
3

мне нужно, чтобы закрыть соединение HTTP, если они занимают больше времени, чем 3 секунды, так что это мой код:Nodejs HTTPS клиент тайм-аут не закрывает соединение TCP

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-соединение остается открытым даже после получения события «timeout». После вечности, я получаю это и соединение закрыто:

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

Кто-нибудь знает, почему это происходит? Почему звонки req.abort() или req.end() или req.destory() не закрывают соединение? Это потому, что я устанавливаю таймаут в сокете вместо фактического HTTP-вызова? Если да, как мне закрыть соединение?

ответ

1

вам необходимо установить тайм-аут на связи:

req.connection.setTimeout(3000); 

Этот таймаут изменит состояние сокета от ESTABLISHED до FIN_WAIT1 и FIN_WAIT2.

В Ubuntu установлен статус таймера FIN_WAIT по умолчанию 60 секунд, поэтому общее время закрытия сокета составляет 63 секунды, если он не получает никакого трафика. Если сокеты получают трафик, тайм-ауты начнутся.

Если вам нужно закрыть сокет в течение 3 секунд, я думаю, вы должны установить время ожидания соединения до 3000 мс и снизить тайм-аут ожидания tcp ядра.

Смежные вопросы