我的node.js应用程序使用http.request到REST API http://army.gov/launch-nukes,我需要区分三种可能的情况:
>成功 – 服务器回应肯定.我知道我的敌人被毁坏了.
>失败 – 我收到服务器的错误,或无法连接到服务器.我还有敌人
>未知 – 建立与服务器的连接后,我发送了请求 – 但不知道发生了什么.这可能意味着请求从来没有提供给服务器,或者服务器对我的响应从未做过.我可能也可能不会开始一场世界大战.
正如你所看到的,对于我来说,区分失败和未知的情况非常重要,因为它们具有非常不同的后果和我需要采取的不同行动.
我也很喜欢使用http Keep-Alive – 我可以说,我是一个战争者,并计划在爆发中提出大量请求(然后长时间没有)
–
问题的核心是如何将连接错误/超时(这是一个失败)与请求放在线路(这是一个未知的)之后发生的错误/超时分隔开来.
在伪代码逻辑中,我想要这样:
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) { if (('' + req.statusCode).match(/^2\d\d$/)) { // Request handled,happy } else if (('' + req.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
(等等…)