node.js在发出http请求时区分错误

标签 node.js http rest timeout

我的 node.js 应用程序使用 http.request 到 REST API http://army.gov/launch-nukes 我需要区分三种可能案例:

  • Success -- 服务器回复是肯定的。我知道我的敌人已经被消灭了。
  • Failure -- 我收到了来自服务器的错误,或者无法连接到服务器。我还有敌人。
  • 未知 -- 与服务器建立连接后,我已经发送了请求 -- 但不确定发生了什么。这可能意味着请求从未发送到服务器,或者服务器对我的响应从未发送过。我可能刚刚开始了一场世界大战,也可能没有。

如您所见,区分 FailureUnknown 情况对我来说非常重要,因为它们有非常不同的后果和我需要采取的不同行动。

我也非常想使用 http Keep-Alive——我能说什么,我是一个好战的人,并计划在突发情况下发出大量请求(然后很长一段时间内什么都没有)时间)

--

问题的核心是如何将连接错误/超时(这是一个Failure)与在请求上线后发生的错误/超时(即是一个未知)。

在伪代码逻辑中我想要这个:

var tcp = openConnectionTo('army.gov') // start a new connection, or get an kept-alive one
tcp.on('error', FAILURE_CASE);
tcp.on('connectionEstablished',  function (connection) {

       var req = connection.httpGetRequest('launch-nukes');
       req.on('timeout', UNKNOWN_CASE);
       req.on('response', /* read server response and decide FAILURE OR SUCCESS */);
   }
)

最佳答案

这是一个例子:

var http = require('http');

var options = {
  hostname: 'localhost',
  port: 7777,
  path: '/',
  method: 'GET'
};

var req = http.request(options, function (res) {
  // check the returned response code
  if (('' + res.statusCode).match(/^2\d\d$/)) {
    // Request handled, happy
  } else if (('' + res.statusCode).match(/^5\d\d$/))
    // Server error, I have no idea what happend in the backend
    // but server at least returned correctly (in a HTTP protocol
    // sense) formatted response
  }
});

req.on('error', function (e) {
  // General error, i.e.
  //  - ECONNRESET - server closed the socket unexpectedly
  //  - ECONNREFUSED - server did not listen
  //  - HPE_INVALID_VERSION
  //  - HPE_INVALID_STATUS
  //  - ... (other HPE_* codes) - server returned garbage
  console.log(e);
});

req.on('timeout', function () {
  // Timeout happend. Server received request, but not handled it
  // (i.e. doesn't send any response or it took to long).
  // You don't know what happend.
  // It will emit 'error' message as well (with ECONNRESET code).

  console.log('timeout');
  req.abort();
});

req.setTimeout(5000);
req.end();

我建议你使用netcat来玩它,即:

$ nc -l 7777
// Just listens and does not send any response (i.e. timeout)

$ echo -e "HTTP/1.1 200 OK\n\n" | nc -l 7777
// HTTP 200 OK

$ echo -e "HTTP/1.1 500 Internal\n\n" | nc -l 7777
// HTTP 500

(等等……)

关于node.js在发出http请求时区分错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19322248/

相关文章:

http - 在哪里以及如何在 vue js 中存储 API 端点?

node.js - 聊天/系统通信应用程序(Nodejs + RabbitMQ)

rest - 纯粹为了使用 HTTP 请求正文而发布

javascript - 如何使用相同的 HTML 通过不同的 url 呈现不同的内容?

c - send() 和 recv() 缓冲区大小应该尽可能大吗?

rest - 可以在 POST 中返回 http 状态 404 吗?

java - 从 Android 的 Jersey Resftul Web 服务传递和接收 JSON 对象

使用 C 连接到 REST 服务

javascript - 使用旧版本的 Node 创建 React App

javascript - Node.js:无法使用请求模块执行 PROFIND