Multiplex

In notebook:
FrontEndMasters Networking and Streams
Created at:
2017-10-01
Updated:
2017-10-01
Tags:
backend Node JS JavaScript

multiplex

pack multiple streams into a single stream

For example in browsers the number of outgoing connections is limited. Or with webrtc, you don't always want to open up a new socket connection.


multiplex: server

  //	****		server.js		****

var net = require('net')
var multiplex = require('multiplex')
var rpc = require('rpc-stream')
var fs = require('fs')

// the tcp connection 
net.createServer(function (stream) {
// plex is also is a duplex stream
  var plex = multiplex()
  // we pipe the tcp connection into a duplex, multiplex stream
  stream.pipe(plex).pipe(stream)
  // it's creating more streams
  var client = rpc({
    // we expose this method
    // the client can call this function 
    read: function (name, cb) { 
    // we take the name as an argument
      if (!/^[\w-]+$/.test(name)) { //test if the name is correctly formatted
        return cb(new Error('file not allowed'))
      }
      // otherwise create another stream ↴
      var r = fs.createReadStream('files/' + name)
      r.on('error', cb)
      // then another stream ↴
      // this is a readstream. It creates another channel for bulk data. 
      r.pipe(plex.createStream('file-' + name)).pipe(r)
      cb(null)
    }
  })
  client.pipe(plex.createSharedStream('rpc')).pipe(client)
}).listen(5000)

Talks again about the satellite example, where you have a controlling port and a higher speed frequncy port.


multiplex: client

  //	****		client.js		****

var net = require('net')
var multiplex = require('multiplex')
var rpc = require('rpc-stream')

var plex = multiplex(function (stream, id) {
  if (/^file-/.test(id)) {
    // if a stream starts with file
    console.log('RECEIVED FILE ' + id.replace(/^file-/,''))
    stream.pipe(process.stdout)
  }
})
plex.pipe(net.connect(5000)).pipe(plex)

var client = rpc()
// we wire up the rpc connection
client.pipe(plex.createSharedStream('rpc')).pipe(client)

var remote = client.wrap(['read'])
// call the remote with the `.read` method 
remote.read(process.argv[2], function (err) {
  if (err) console.error(err)
})

###Demo

$ node server.js

The creates a files directory where the server will read files from. He creates two text files in there.

$ node client.js hello ☛ passes the name of the file hello

The server then replies with the name contents of the file hello

It's almost an ad hoc implementation of http but pipelined.