在Node.js中发送多个HTTP请求:未收到任何响应或超时

时间:2015-06-06 16:29:06

标签: node.js http mediawiki keep-alive wikipedia-api

我正在尝试处理维基百科文章,并希望收到所有维基百科文章的列表。为了做到这一点,我经常向Wikipedia API发送http请求,这允许您一次接收500个标题,并返回 apcontinue 字符串,当在以下请求中使用时,返回标题从那个字符串开始。

为了做到这一点,我使用 agentkeepalive 模块:

var http = require('http');
var Agent = require('agentkeepalive');

var keepaliveAgent = new Agent({
  keepAlive: true,
  maxSockets: 5,
  timeout: 5000,
  keepAliveTimeout: 3000
});

要向Wikipedia发送http请求,我使用以下代码:

function wikipediaApiCall(params, callback) {
  var options = {
    host: 'en.wikipedia.org',
    path: '/w/api.php?' + createParamString(params),
    method: 'GET',
    agent: keepaliveAgent
  };

  var callbackFunc = function(response) {
    var err;
    var str = '';

    if (('' + response.statusCode).match(/^5\d\d$/)) {
      err = new Error('Server error');
    }

    //another chunk of data has been recieved, so append it to `str`
    response.on('data', function (chunk) {
      str += chunk;
    });

    response.on('error', function (e) {
      err = new Error('Request error');
    });

    response.on('timeout', function () {
      err = new Error('Timeout');
      response.abort();
      callback(err);
    });

    response.on('end', function () {
      var obj = JSON.parse(str);

      if (obj.warnings) {
        err = new Error('Request error');
      }

      callback(err, obj);
    });
  }

  var req = http.request(options, callbackFunc);
  req.setTimeout(5000);

  req.on('error', function(err) {
    callback(err, null);
    return;
  });

  req.on('timeout', function () {
    err = new Error('Timeout');
    response.abort();
    callback(err);
  });

  req.on('finish', function(){
    console.log('ended');
  });

  req.end();
}

但是,在发送16到20个请求之后,我没有收到任何回复,但我的请求也没有超时。

为什么会发生这种情况?

更新

我发送给维基百科的请求包含以下参数:

  var params = {
    list: 'allpages',
    aplimit: limit,
    apfrom: from,
    continue: cont,
    // apfilterredir: 'nonredirects'
  };

有趣的是,在省略nonredirects设置后,我能够发送和接收最多330个请求,但不超过这个。

更新2

我能够注册finished事件。对于失败的请求似乎也被解雇了。我相应地修改了代码。

1 个答案:

答案 0 :(得分:0)

也许你需要一个bot标志来获得更高的API限制。也许并行请求太多; WMF的建议是在发生如此大的任务时连续提出请求。此外,根据WMF API礼仪,您应该使用低值的maxlag参数。