Pregunta

Quiero solicitud cuerpo (POST) de http.ServerRequest, pero no lo hacen recta cuando mi función de petición se llama, pero sólo después de algún tiempo (Redis consulta).

Tengo un ejemplo muy simple para ilustrar:

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);

En este ejemplo data eventos y end se pierden por completo, a pesar de que estoy llamando req.pause() / req.resume(), por lo que la solicitud de "pegado".

Si comento hacia fuera llamada setTimeout() y hacer todo lo recta en función de petición, todo funciona como se esperaba. Pero quiero consultar Redis para ver siempre de la solicitud válida. Los postes son grandes cargas de archivos, y no quieren perder el tiempo de espera para la carga completa sin éxito.

La forma más sencilla de hacer esto es para retrasar el cargo durante algunos milisegundos (en mi caso POST tomaría al menos varios segundos, por lo que tan pequeño retraso es insignificante). El uno más ordenado es empezar a analizar los datos entrantes, validando de forma simultánea la solicitud y soltar la conexión si la solicitud del considere no válida.

La pregunta es: ¿cómo lo haría nada de esto? Estoy usando Node.js versión 0.1.97-14-g0055dd1 si esto es importante.

Gracias por cualquier sugerencia.

¿Fue útil?

Solución

No sé cuando estoy haciendo bien, pero esto parece correcto para mí:

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);

Adición: Cuando Conectar middleware quiere llevar a cabo algunas de las solicitudes asynchonous (es decir, pasar de nuevo el control al bucle de eventos) que funciona en torno de esta manera:

var pause = utils.pause(req);
fs.readFile(path, function(){
    next();
    pause.resume();
});

Cuando utils.pause() es un truco para amortiguar eventos pendientes .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top