corpo POST in Node.js e alcuni asincrono controllo condizione
-
25-09-2019 - |
Domanda
Voglio arrivare richiesta corpo (POST) da http.ServerRequest
, ma faccio in modo non rettilineo quando la mia funzione di richiesta viene chiamata, ma solo dopo un certo tempo (query Redis).
Ho un esempio molto semplice per illustrare:
var http = require('http'),
sys = require('sys');
http.createServer(function (req, res) {
sys.puts("Got request");
req.pause();
setTimeout(function() { // In real code I'm accessing Redis here.
var body = "";
req.addListener('data', function (chunk) {
sys.puts("Got 'data' event");
body += chunk;
});
req.addListener('end', function () {
sys.puts("Got 'end' event");
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(body);
});
req.resume();
}, 10);
}).listen(8000);
In questo esempio, gli eventi e data
end
sono completamente mancati, anche se sto chiamando req.pause()
/ req.resume()
, quindi di richiesta di "bloccato".
Se io commento chiamata setTimeout()
e faccio tutto dritto nella funzione richiesta, tutto funziona come previsto. Ma voglio interrogare Redis a vedere ogni volta che la richiesta del valido. I posti sono grandi upload di file, e non voglio sprecare il tempo di attesa per il caricamento non riuscito di completa.
Il modo più semplice per farlo è quello di ritardare il POST per alcuni millisecondi (nel mio caso POST ci vorranno almeno alcuni secondi, in modo così piccolo ritardo è del tutto insignificante). L'uno più ordinato è quello di iniziare l'analisi dei dati in entrata, contemporaneamente convalidare la richiesta e interrompere la connessione, se la richiesta di ritenuta non valida.
La domanda è: come farei di tutto questo? Sto usando Node.js versione 0.1.97-14-g0055dd1 se questo importa.
Grazie per eventuali suggerimenti.
Soluzione
Non so ogni volta che sto facendo questo diritto, ma questo sembra giusto per me:
var http = require('http'),
sys = require('sys');
http.createServer(function (req, res) {
var body = "",
body_complete = false,
wait_complete = false;
sys.debug("Got request");
// This will be called on each process' completion
var final_cb = function(err) {
if (err) throw new Error(err);
if (body_complete && wait_complete) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(body);
}
};
// Async process one: get POST body
req.addListener('data', function (chunk) {
sys.debug("Got 'data' event");
body += chunk;
});
req.addListener('end', function () {
sys.debug("Got 'end' event");
body_complete = true;
final_cb(null)
});
// Async process two: wait 10ms
setTimeout(function() { // In real code I'm accessing Redis here.
sys.debug("Timeout passed");
if (false) { // Okay, timeout can't go wrong
res.writeHead(403);
res.end('Sorry');
}
wait_complete = true;
final_cb(null);
}, 10);
}).listen(8000);
Aggiunta: quando colleghi middleware vuole eseguire alcune richieste asynchonous (vale a dire passare il controllo per il ciclo degli eventi) che funziona in tutto in questo modo:
var pause = utils.pause(req);
fs.readFile(path, function(){
next();
pause.resume();
});
Dove utils.pause()
è un hack per tamponare gli eventi in attesa .