1

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.

3
  • 1
    Try opening from two different browsers maybe the server handles requests from the same session one at a time. Commented Jul 21, 2011 at 8:05
  • hm strange. if I open it from two browsers it works simultaneous but is overwriting gRes to the second page call, but thats ok (i have seen this problem before). But why isn't it working for two tabs from one browser? Commented Jul 21, 2011 at 8:07
  • Dunno why as I'm not familiar with node.js however as it proved to be correct, posted it as answer. :) Commented Jul 21, 2011 at 8:17

2 Answers 2

5

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.

Sign up to request clarification or add additional context in comments.

1 Comment

great answer :) much easier than my "workaround" which did not handle all cases
0

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.

1 Comment

Cheers, glad you got real solution! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.