Liam Kaufman

Software Developer and Entrepreneur

Pushing Files to the Browser Using Delivery.js, Socket.IO and Node.js

Recently I’ve been working with both the HTML 5 File API and Socket.IO and it occured to me that those technologies could be used to send, and push, files between the client and server. Immediately I set about making delivery.js, a simple node module that makes it extremely easy to send and push files between the client and the server via Socket.IO.

I should note that this is my first node module, so constructive critism and feedback are welcome and encouraged!

Example: Pushing An Image To The Client

Delivery.js on Github

In the following example, once a client connects to the server an image will be pushed to the client. When the client receives the image, the image’s data URL (“data:image/gif;base64,R0lGODlhEAAOALMAAOazT…”) is assigned to the src attribute of an img element.

Client
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$(function(){
  var socket = io.connect('http://0.0.0.0:5001');

  socket.on('connect', function(){
    var delivery = new Delivery(socket);

    delivery.on('receive.start',function(fileUID){
      console.log('receiving a file!');
    });

    delivery.on('receive.success',function(file){
      if (file.isImage()) {
        $('img').attr('src', file.dataURL());
      };
    });
  });
});
Server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var io  = require('socket.io').listen(5001),
    dl  = require('delivery');

io.sockets.on('connection', function(socket){
  var delivery = dl.listen(socket);
  delivery.on('delivery.connect',function(delivery){

    delivery.send({
      name: 'sample-image.jpg',
      path : './sample-image.jpg'
    });

    delivery.on('send.success',function(file){
      console.log('File successfully sent to client!');
    });

  });
});

Advantages

While delivery.js is more of an experiment, there could be some advantages to using Web Sockets to transfer files. Once a Web Socket connection is established messages (frames) sent between the client and server contain only 2 additional bytes of overhead. In contrast, a traditional POST request, and response, may have headers totaling 871 bytes. This could be a significant addition if many files are being sent, and would be even more significant if files are being divided into batches before being sent to the server. When pushing files to the client, the overhead of traditional polling methods provides an even starker contrast to Web Sockets.

Disadvantages

The most apparent disadvantage would be the fact that it bipasses traditional caching methods. Instead of caching based on a file’s URL, caching would be based on the content of the Web Socket’s message. One possibility would be to cache a base64, or text, version of the file within Redis for fast, in memory, access.

Future

With zip.js files could be deflated, or inflated, within the browser. In-browser file zipping could have a positive impact on transfer speeds. To check the integrity of the unzipped file an md5 checksum could be generated client-side, using Paul Johnston’s JavaScript MD5 implementation, and then passed along with the zipped file.

For more documentation and examples see Delivery.js on Github:
Delivery.js on Github

Comments