我有以下代码创建问题:
var timeout_wrapper = function (req) {
return function () {
log.error('rest', 'Unable to contact service. Timed out.');
if (res.req) {
res.status(HttpStatus.INTERNAL_SERVER_ERROR).send('Timed out contacting service.');
}
req.abort();
};
};
var timeout;
var req = https.get(options, function (response) {
log.info('rest', 'Got response from service.');
clearTimeout(timeout);
if (response.statusCode === HttpStatus.NOT_FOUND) {
callback(false);
return;
}
if (response.statusCode === HttpStatus.NO_CONTENT) {
callback(true);
return;
}
log.error('rest', 'Service returned an undocumented status code: %s', response.statusCode);
res.status(HttpStatus.INTERNAL_SERVER_ERROR).send('Unable to contact service.');
}).on('error', function (e) {
clearTimeout(timeout);
log.error('rest', 'Unable to contact service. Got error: %s', e);
/*if (res.req) {
res.status(HttpStatus.INTERNAL_SERVER_ERROR).send('Unable to contact service.');
}*/
});
timeout = setTimeout(timeout_wrapper(req), 10000);
我正在联系的服务经常超时(但我无法控制)。所以我创建了一个超时函数,它起作用(客户端确实接收res.status(HttpStatus.INTERNAL_SERVER_ERROR).send('Timed out contacting service.');
),但请求没有中止。使用以下stacktrace后会调用.on('error', ...)
:
ERR! rest Error: socket hang up
ERR! rest at createHangUpError (http.js:1472:15)
ERR! rest at CleartextStream.socketCloseListener (http.js:1522:23)
ERR! rest at CleartextStream.EventEmitter.emit (events.js:117:20)
ERR! rest at tls.js:696:10
ERR! rest at process._tickCallback (node.js:415:13)
ERR! rest Unable to contact service. Got error: %s { [Error: socket hang up] code: 'ECONNRESET' }
我认为这是一个简单的HTTPS GET请求,而不是套接字,为什么请求不会在我的超时函数中中止?
答案 0 :(得分:2)
我认为你不需要为这种情况设置一个timeout_wrapper。一个简单的解决方案是将http.get
置于函数内,并将回调作为参数。这个可能不是您的解决方案灵活,但看起来更简单,应该在这种情况下工作。
function testGet(options, callback) {
var req = http.get(options, function(response) {
if (response.statusCode === HttpStatus.NOT_FOUND)
callback(false);
if (response.statusCode === HttpStatus.NO_CONTENT)
callback(true);
if (response.statusCode == ERROR)
callback(false);
}).on('error', function(e){
callback(false);
});
req.setTimeout(TIMEOUT, function(){
callback(false);
req.abort();
}
}
答案 1 :(得分:0)
我无法回答上面的问题,但是我使用request软件包解决了我的问题,在我看来,这比Node自己的HTTP软件包要好得多。它支持开箱即用的超时等等。