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.

È stato utile?

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 .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top