开发者

Why is this node.js code blocking?

开发者 https://www.devze.com 2023-03-21 17:40 出处:网络
I tried to play a bit with node.js and wrote following code (it doesn\'t make sense, but that does 开发者_高级运维not matter):

I tried to play a bit with node.js and wrote following code (it doesn't make sense, but that does 开发者_高级运维not matter):

var http = require("http"),
    sys  = require("sys");

sys.puts("Starting...");

var gRes = null;
var cnt = 0;

var srv = http.createServer(function(req, res){
    res.writeHeader(200, {"Content-Type": "text/plain"});
    gRes = res;
    setTimeout(output,1000);
    cnt = 0;
}).listen(81);

function output(){
    gRes.write("Hello World!");
    cnt++;
    if(cnt < 10)
        setTimeout(output,1000);
    else
        gRes.end();
}

I know that there are some bad things in it (like using gRes globally), but my question is, why this code is blocking a second request until the first completed?

if I open the url it starts writing "Hello World" 10 times. But if I open it simultaneous in a second tab, one tab waits connecting until the other tab finished writing "Hello World" ten times.

I found nothing which could explain this behaviour.


Surely it's your overwriting of the gRes and cnt variables being used by the first request that's doing it?

[EDIT actually, Chrome won't send two at once, as Shadow Wizard said, but the code as is is seriously broken because each new request will reset the counter, and outstanding requests will never get closed].

Instead of using a global, wrap your output function as a closure within the createServer callback. Then it'll have access to the local res variable at all times.

This code works for me:

var http = require("http"),
    sys  = require("sys");

sys.puts("Starting...");

var srv = http.createServer(function(req, res){
    res.writeHeader(200, {"Content-Type": "text/plain"});

    var cnt = 0;

    var output = function() {
        res.write("Hello World!\n");
        if (++cnt < 10) {
            setTimeout(output,1000);
        } else {
            res.end();
        }
    };

    output();

}).listen(81);

Note however that the browser won't render anything until the connection has closed because the relevant headers that tell it to display as it's downloading aren't there. I tested the above using telnet.


I'm not familiar with node.js but do familiar with server side languages in general - when browser send request to the server, the server creates a Session for that request and any additional requests from the same browser (within the session life time) are treated as the same Session.

Probably by design, and for good reason, the requests from same session are handled sequentially, one after the other - only after the server finish handling one request it will start handling the next.

0

精彩评论

暂无评论...
验证码 换一张
取 消