Mon application node.js utilise http.request
à REST API http://army.gov/launch-nukes
et je dois distinguer trois cas possibles:
Success
- Le serveur répond par l'affirmative. Je sais que mes ennemis sont détruits.Failure
- Soit j'ai reçu une erreur du serveur, ou je n'ai pas pu me connecter au serveur. J'ai toujours des ennemis.Unknown
- Après avoir établi une connexion au serveur, j'ai envoyé la demande - mais je ne sais pas ce qui s'est passé. Cela pourrait signifier que la demande n'a jamais été envoyée au serveur ou que la réponse du serveur n'a jamais été envoyée. Je viens peut-être ou non de commencer une guerre mondiale.Comme vous pouvez le voir, il est très important pour moi de distinguer le cas Failure
et Unknown
, car ils ont des conséquences très différentes et des actions différentes que je dois prendre.
J'aimerais aussi beaucoup utiliser http Keep-Alive - car que puis-je dire, je suis un peu un belliciste et je prévois de faire beaucoup de demandes en rafales (et puis rien pendant de longues périodes)
-
Le cœur de la question est de savoir comment séparer une erreur de connexion/délai d'expiration (qui est un Failure
) d'une erreur/délai d'expiration qui se produit après que la demande a été placée sur le câble (qui est un Unknown
).
Dans la logique du pseudo-code, je veux ceci:
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 */);
}
)
Voici un exemple:
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();
Je vous recommande de jouer avec Netcat, c'est-à-dire:
$ 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
(etc...)
Cela se trouve généralement dans le code d'état des API. Dans le package de demande, vous pouvez y accéder comme ceci
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Print the google web page.
}
})
response.statusCode
étant 200 signifie que cela a fonctionné. 500 serait un échec. Inconnu serait le rappel jamais appelé.
Si l'API que vous décrivez ne suit pas les codes de réponse standard, je ne sais pas. Vous devrez regarder les documents.