質問

私はhttp.ServerRequestからの要求(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を遅らせることです。リクエストのは無効であることが判明した場合に滑らかな印象の1が同時に要求を検証し、受信データを解析を開始し、接続をドロップすることです。

質問です:私はこれのいずれかを行うだろうか?この問題あれば、私は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() Aハック保留中のイベント A>。

scroll top