【问题标题】:NodeJS http get timeoutNodeJS http获取超时
【发布时间】:2017-02-21 22:17:48
【问题描述】:

我有以下代码会产生问题:

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.'); ),但请求没有中止。 .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 请求,而不是套接字,为什么我的超时函数中没有中止请求?

【问题讨论】:

    标签: node.js rest express


    【解决方案1】:

    我认为你不需要为这种情况创建一个 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();
        }
    }
    

    【讨论】:

    • 在给出答案时,最好给出some explanation as to WHY your answer
    • 哦,对不起。这是我的第一个答案。
    • 改进答案还为时不晚。在左侧您的帖子下方是一个编辑按钮。如果您可以更好地解释该帖子,请对其进行编辑,以便为以后可能出现的其他人提供更好的答案。
    • 干得好!现在这是一个更好的答案。不要犹豫,进行编辑以改进网站。干杯。
    【解决方案2】:

    我无法回答上面的问题,但是我通过使用 request 包解决了我的问题,在我看来,它比 Node 自己的 HTTP 包要好得多。除其他外,它还支持开箱即用的超时。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-19
      • 2016-02-08
      • 1970-01-01
      • 2019-06-06
      • 2014-08-16
      • 1970-01-01
      • 1970-01-01
      • 2015-02-22
      相关资源
      最近更新 更多