NodeJS http获取超时

时间:2014-10-22 17:40:32

标签: node.js rest express

我有以下代码创建问题:

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请求,而不是套接字,为什么请求不会在我的超时函数中中止?

2 个答案:

答案 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软件包要好得多。它支持开箱即用的超时等等。