Multiple data streams over just one socket with mux-demux and shoe (node)
In a realtime app it’s common to have multiple data streams coming from the server. The mechanism to handle the different connections could include among others:
- frequent pooling to the server (possible perf issues if multiple requests are made at the same time)
- one socket per data stream ( possible perf issues in server and client)
A better alternative
Multiple data streams but just one channel (1 web socket).
This is what mux-demux refers to (multiplex-demultiplex), and can be very useful for situations when having multiple transport channels (in this case sockets) is not practical.
How to use mux-demux?
To have a reference for future projects i created a minimal sample that demostrates how to send multiple data streams over one connection. The following modules are used:
shoe: Creates a stream over a websocket so we can use the same streams Api we love.
reconnect-core : Gives us the ability to execute a method everytime we need to reconnect to the server in case connection is lost.
mux-demux : Inject multiple streams into another stream and extract them from the other side.
browserify : Use npm modules in the browser.
The example consist of 9 streams that emit random numbers. We want to send those streams to the browser and display them in realtime.
Animated gif:
The code
The important part is here (index.js)
var shoe = require('shoe'); | |
var through = require('through'); | |
var http = require('http'); | |
var ecstatic = require('ecstatic'); | |
var MuxDemux = require('mux-demux'); | |
var server,sock,sourcestreams = []; | |
var samplestream = require("./samplestream.js"); | |
//Create an array with 100 streams and send them through one shoe connection | |
for(var i = 0;i<10;i++){ | |
sourcestreams.push(new samplestream()); | |
} | |
//Setup http server, use ecstatic to serve the content in public directory. | |
server = http.createServer(ecstatic({root:__dirname+'/public'})); | |
server.listen(7777,function(){ | |
console.log("listening on port 7777"); | |
}); | |
//Setup websocket connection | |
sock = shoe(function(stream){ | |
var mx = MuxDemux(); | |
//Setup mux-demux "device" | |
stream.pipe(mx).pipe(stream); | |
//For each sample stream in sourcestreams array | |
//create a write stream , mux-demux will create readable | |
//streams on the other side (the browser) | |
for (var i=0;i<sourcestreams.length;i++) { | |
//We have to name each stream so we can get them in the browser code | |
var name = "mystream"+i; | |
var datasetstream = mx.createWriteStream(name); | |
sourcestreams[i].pipe(datasetstream); | |
}; | |
}); | |
//Create one socket in the path /numbers | |
sock.install(server,'/numbers'); |
Reconnection.
If the server goes down, we need to reconnect. For this there is a module callled reconnect-core that we can use.
Check browser.js to see how to implement it.