Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

respond to each request without having to wait until current stream is finished

respond to each request without having to wait until current stream is finished

Problem

I'm testing streaming by creating a basic node.js app code that basically streams a file to the response. Using code from here and here.

But If I make a Request from http://127.0.0.1:8000/, then open another browser and request another file, the second file will not start to download until the first one is finished. In my example I created a 1GB file. dd if=/dev/zero of=file.dat bs=1G count=1

But if I request three more files while the first one is downloading, the three files will start downloading simultaneously once the first file has finished.

How can I change the code so that it will respond to each request as it's made and not have to wait for the current download to finish?

var http = require('http');
var fs = require('fs');
var i = 1;

http.createServer(function(req, res) {

    console.log('starting #' + i++);
    // This line opens the file as a readable stream
    var readStream = fs.createReadStream('file.dat', { bufferSize: 64 * 1024 });

    // This will wait until we know the readable stream is actually valid before piping
    readStream.on('open', function () {
        console.log('open');
        // This just pipes the read stream to the response object (which goes to the client)
        readStream.pipe(res);
    });

    // This catches any errors that happen while creating the readable stream (usually invalid names)
    readStream.on('error', function(err) {
        res.end(err);
    });
}).listen(8000);

console.log('Server running at http://127.0.0.1:8000/');
Problem courtesy of: capdragon

Solution

Your code seems fine the way it is. I checked it with node v0.10.3 by making a few requests in multiple term sessions:

$ wget http://127.0.0.1:8000

Two requests ran concurrently. I get the same result when using two different browsers (i.e. Chrome & Safari). Further, I can get concurrent downloads in Chrome by just changing the request url slightly, as in:

http://localhost:8000/foo

and

http://localhost:8000/bar

The behavior you describe seems to manifest when making multiple requests from the same browser for the same url.

This may be a browser limitation - it looks like the second request isn't even made until the first is completed or cancelled.

To answer your question, if you need multiple client downloads in a browser

  1. Ensure that your server code is implemented such that file-to-url mapping is 1-to-many (i.e. using a wildcard).
  2. Ensure your client code (i.e. javascript in the browser), uses a different url for each request.
Solution courtesy of: Andrew

Discussion

View additional discussion.



This post first appeared on Node.js Recipes, please read the originial post: here

Share the post

respond to each request without having to wait until current stream is finished

×

Subscribe to Node.js Recipes

Get updates delivered right to your inbox!

Thank you for your subscription

×