我想从http.ServerRequest get请求(POST)的身体,但这样做不直,当我的请求函数被调用,但只有经过一段时间后(Redis的查询)。

我有一个非常简单的例子来说明:

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

在这个例子中dataend事件彻底无缘,即使我打电话req.pause() / req.resume(),所以请求的“卡壳”。

如果我注释掉setTimeout()呼叫,并在请求函数直做的一切,预期一切正常。但我想查询的Redis看到,每当请求的有效。帖子都是大文件上传,我不想浪费时间等待失败的上传完成。

在简单的方式做,这是拖延几毫秒的POST(在我的情况职位将至少需要几秒钟,所以这种微小的延迟是相当显着)。更合适的一个是开始解析传入的数据,同时使所述请求生效和丢弃连接请求是否的发现是无效的。

现在的问题是:我怎么会做任何的吗?我使用Node.js的版本0.1.97-14-g0055dd1如果这事。

感谢您的任何建议。

有帮助吗?

解决方案

不知道,每当我这样做的权利,但这似乎适合我:

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

<强>增加::当连接中间件希望进行一些asynchonous请求(即控制传递回事件循环)它的工作原理围绕这样:

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

其中utils.pause()一劈缓冲挂起的事件

scroll top