1

I have the following simple NodeJS code:

var http = require("http");

http.createServer( function(request, response){
    response.writeHead(200);
    setTimeout(function(){
        response.write("This printed 3 secs later, ait?");
        response.end();
    }, 3000);

    response.write("This will be printed before.\n");
}).listen(8080);

If I run the script with node scriptname.js and then access it via curl in terminal like this:

curl http://localhost:8080

I get an output as expected, first it prints This will be printed before., then after 3 seconds it prints This printed 3 secs later, ait?.

However, when I open http://localhost:8080 in my browser (newest versions of Chrome, Firefox) page loads for 3 seconds and it prints the text This will be printed before. This printed 3 secs later, ait? all at once. Why does this happen and how could I make the same behavior in the browser?

edit: So, as Ken stated in his answer

...this is simply due to the behavior of the browser rendering engine to render the contents. The rendering engine cashes the contents until response.end();

and advised to go and check out Socket.IO, I came up with this working example which uses express and Socket.IO:

//timeoutTest.js

var express = require('express'),
    app = express(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server);

server.listen(8080);

app.use(express.static(__dirname + '/'));

app.get('/', function (req, res) {
   res.sendfile(__dirname + '/timeoutTest.html');
});

io.sockets.on('connection', function (client) {
   client.emit('msg', "This prints right now on connection.");

   setTimeout(function(){
      client.emit('msg', "This prints out after 3 secs.");      
   }, 3000);
});

//timeoutTest.html

<!DOCTYPE html>
<html>
<head>
    <script src="/socket.io/socket.io.js"></script>
    <script src="jquery.js"></script>
    <script>
    $(document).ready(function(){
        var server = io.connect('http://localhost');
        server.on('msg', function(data){
            $('body').append(data + "<br/>");
        });
    });
    </script>
</head>
<body>
</body>
</html>
Nikola
  • 14,888
  • 21
  • 101
  • 165
  • PS. I have recommended to you `Socket.IO` for the starter of server-browser interaction issue. This technology is generally called `RPC(remote procedure cal)` . `Socket.IO` is familiar to many people and you can find abundant resource on the web, so good thing to start. Just for future references, I personally do not use it anymore since it's a huge library just to do RPC between node and browser. The more concise and sophisticated (I think) and seamless way to do RPC here is to use `https://github.com/substack/dnode or https://github.com/dominictarr/rpc-stream with 'Browserify'. –  Feb 24 '14 at 01:08
  • Please refer my answer to a related question here. http://stackoverflow.com/questions/12832402/is-socket-io-a-must-in-developing-client-apps-for-nodejs-servers –  Feb 24 '14 at 01:59
  • Thanks for additional comments! – Nikola Feb 24 '14 at 08:30

1 Answers1

3

I think this is simply due to the behavior of the browser rendering engine to render the contents.

The rendering engine cashes the contents until response.end(); arrives, then renders whole.

Basically, HTML contents in the browser are never updated automatically by incremental server push such as response.write.

You must pull data from the server to the browser client by Ajax and DHTML/js technique.

curl in terminal is completely different story in terms of the mere output of the node server.

If you seek more interactive behavior between node server and browser client, if you want server push feature, websocket is the way to go, and also investigate node stream stuff.

Socket.IO is famous, and for node stream https://github.com/substack/stream-handbook should be interesting to you.

I personally do this on my own project:

http://kenokabe.github.io/MarkdownLive/

I write stuff using Markdown and needed a streaming preview, so I created by myself. The preview screen is a Browser HTML page, and the HTML contents rendered and updated incrementally in streaming manner.

  • Thanks Ken, your answer made me go and explore this further. You can check out what I came up with in my edit. Thx! – Nikola Feb 23 '14 at 20:55
  • It's my pleasure, Nikola. Glad to hear that my little comment help you. –  Feb 24 '14 at 00:54