从Node.js向API发送许多请求会导致错误

时间:2017-07-04 14:37:05

标签: javascript node.js facebook api node-request

我的数据库中有超过2000个用户,当我尝试向所有用户广播消息时,它几乎不发送大约200个请求然后我的服务器停止并且我收到如下错误:

{ Error: connect ETIMEDOUT 31.13.88.4:443
at Object.exports._errnoException (util.js:1026:11)
at exports._exceptionWithHostPort (util.js:1049:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1090:14)
code: 'ETIMEDOUT',
errno: 'ETIMEDOUT',
syscall: 'connect,
address: '31.13.88.4',
port: 443 }

有时我收到另一个错误:

Error!: Error: socket hang up 

这是我的要求:

function callSendAPI(messageData) {
  request({
    uri: 'https://graph.facebook.com/v2.6/me/messages',
    qs: { access_token: '#####' },
    method: 'POST',
    json: messageData

  }, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      var recipientId = body.recipient_id;
      var messageId = body.message_id;

      if (messageId) {
        console.log("Successfully sent message with id %s to recipient %s", 
          messageId, recipientId);
      } else {
      console.log("Successfully called Send API for recipient %s", 
        recipientId);
      }
    } else {
      console.error("Failed calling Send API");
      console.log(error)
    }
  });  
}

我试过

setTimeout让API调用等待一段时间:

 setTimeout(function(){callSendAPI(data)},200);

如果他/她遇到类似错误,有人可以提供帮助吗?

EDITED

我使用Messenger平台支持对发送API的高速率调用,并且不限制200次调用。

2 个答案:

答案 0 :(得分:1)

您可能正在达到Facebook API限制。要限制请求,您应该在前一个请求之后发送每个请求。你没有包含你在所有用户上迭代的地方,但我怀疑你可能在一个循环中进行,如果你使用setTimeout延迟每个延迟200毫秒的请求那么你有所有请求就像你之前做的那样 - 仅仅200分钟后完成。

你能做的是:

  1. 您可以使用setTimeout并为每个请求添加可变延迟(不推荐)
  2. 您可以使用异步模块seriesparallelLimit(使用回调)
  3. 您可以使用Bluebird的Promise.mapSeriesPromise.map concurrency限制(使用承诺)
  4. 不建议使用1,因为它仍然会发生故障(除非你增加了更多的复杂性)并且你仍有可能因为你只控制请求何时启动,所以你有太多的并发和超限。不是有多少未完成的请求。

    2和3大致相同,但使用回调或承诺不同。在您的示例中,您使用的是回调,但是callSendAPI没有采取自己的回调,如果您希望选项2可以使用它,或者,如果您想要选项,它应该返回一个承诺3工作。

    有关详细信息,请参阅文档:

    当然有更多方法可以做到,但那些方法最直接。

    理想情况下,如果您想充分利用每小时200个请求限制,那么您应该自己对请求进行排队,并以与该限制相对应的特定间隔发出请求。有时候,如果你在一小时内没有做很多请求,那么有时你就不会有延迟。你应该在这里真正做的是集中排队所有请求,并按照与已经用完的部分相对应的间隔清空队列到你应该自己跟踪的限制 - 但这可能很棘手。

答案 1 :(得分:-1)

听起来你正在达到速率限制。

来自Facebook documentation

  

您的应用可以合计每位用户每小时拨打200个电话。

您可以查看dashboard,看看您是否在这些情况下达到了限速率。