【问题标题】:Nodejs Http request has no responseNodejs Http请求没有响应
【发布时间】:2015-03-06 00:38:18
【问题描述】:

当前使用 http GET 到外部 API。单独调用时,响应良好。当放入 for 循环时,某些请求似乎没有响应。

这是http GET函数:

function httpGetChunk(url, callback) {
    http.get(url, function(resp) {
        var body='';
        resp.on('data', function(chunk) {
            body += chunk; //chunk too large from this response
        });
        resp.on('end', function() {
            var data = JSON.parse(body);
            callback(data);
        });
        resp.on("error", function(e) {
            console.log("Got error: " + e.message);
        });
    });
}

当我在 for 循环中为 5 个不同的 url 调用 GET 函数时,我只得到其中一些的响应。运行它几次,响应将来自被调用 url 的不同组合,但不是全部。

有什么见解吗?

编辑 1:为了提供更多信息,我的 for 循环看起来像这样。

for (var i=0;i<5; i++) {
    httpGetChunk(someUrl, function(data) {
        console.log(data);
    });
}

这只会打印出一些响应,而不是全部。

编辑 2: 我已经考虑了关于这个线程的所有建议。我现在正在使用 async 模块并将并发连接数增加到 20:

http.globalAgent.maxSockets = 20;

以下代码是我目前正在测试的代码:

getMatchStats() 返回一个带有统计数据的游戏“比赛”对象(例如,比赛中的击杀数、死亡数等)

matchIds 是包含匹配项的所有 id 键的数组

async.parallel([
    getMatchStats(matchIds[0], function (matchData) {
        console.log('0');
    }),
    getMatchStats(matchIds[1], function (matchData) {
        console.log('1');
    }),
    getMatchStats(matchIds[2], function (matchData) {
        console.log('2');
    }),
    getMatchStats(matchIds[3], function (matchData) {
        console.log('3');
    }),
    getMatchStats(matchIds[4], function (matchData) {
        console.log('4');
    }),
], function(err, result) {
    console.log('done');
    callback(result);
});

和 getMatchStats

function getMatchStats(matchId, callback) {
    var url = getMatchStatsUrl(matchId); //gets url based on id
    httpGetChunk(url, function(data) {
        callback(data);
    });
}

同样,async.parallel 永远不会完成,因为只有一些请求有响应。每次我运行它时,响应都会来自不同的匹配组合。有时,它甚至会完成所有请求。

也许我的操作系统对连接数有限制(我在 localhost 上进行测试)?

【问题讨论】:

  • 节点本身对它允许的同时套接字连接的数量有一个相当小的限制。通过尝试并行执行多个请求,您可能会用完套接字。可以增加节点套接字限制,我认为在最新的 node.js 版本中已经提高了默认值。我不知道这是否是您的具体问题,但可能是)。
  • 使用request。它让您的生活变得如此轻松。
  • @jfriend00 我调查了一下,我目前使用的是 0.10 nodejs,它对套接字连接有限制。我已经增加了限制,问题仍然存在。
  • 那么,我想知道您正在调用的服务器是否存在并发问题(当多个请求同时到达时)。我建议您查看网络嗅探器(例如 WireShark)并准确查看通过网络发送和接收的内容,以了解正在发生的事情。您需要确定这是您本地代码的问题还是您发出请求的服务器的问题。

标签: node.js http get response


【解决方案1】:

每个请求都是异步的。因此,如果您使用常规的for 循环,每个步骤都将同步执行,并且不会等待回调被调用。你需要的是类似于async 模块中的each 方法,比如:

async.each(yourArrayOfUrls, function (url, callback) {
  httpGetChunk(url, function(data) {
    console.log(data);
    callback();
  });
}, function (err) {
  // if some step produce an error, you can get it here...
});

【讨论】:

  • 不应该for循环只是产生一堆异步http请求吗?回调仍然应该被调用,对吗?另外,我尝试了异步,问题仍然存在
  • 是的,你的for 循环产生了一堆异步请求,但是是以同步的方式,所以当循环结束时,并不是所有的请求都返回了。这就是为什么你永远不应该使用同步循环来运行异步调用。在这些情况下,您应该使用 async 模块之类的东西,甚至是 Promise。在您的场景中,您没有看到所有请求的日志的唯一原因是其中一个返回了错误,您可以在 async.each 方法的最后一个函数中捕获它。
猜你喜欢
  • 1970-01-01
  • 2018-08-04
  • 1970-01-01
  • 1970-01-01
  • 2020-08-19
  • 2018-11-13
  • 1970-01-01
  • 1970-01-01
  • 2018-04-03
相关资源
最近更新 更多