Websocket Streams

In notebook:
FrontEndMasters Networking and Streams
Created at:
2017-09-30
Updated:
2017-09-30
Tags:
backend Node JS JavaScript Fundamentals

websocket-stream

streaming websockets in node and the browser

Let's create a server:

  const http = require('http')
// ecstatic for serving up static files ↴
// (we will need to send some files to the browser)
const ecstatic = require('ecstatic')
const through = require('through2')

http.createServer(ecstatic(__dirname + '/public')) // (creates the public dir)
server.listen(5000)

// and use the websockets:
// this will create a duplex stream
const wsock = require('websocket-stream')
wsock.createServer({ server: server}, function (stream) {
  // `stream` is a duplex stream
  // an echo server:
  stream.pipe(stream)
  // or an echo server that converts to uppercase
  // for this to work we need through (above)
  stream.pipe(loud()).pipe(stream)
})


function loud () {
  return through(function (buf, enc, enxt) {
    next(null, buf.toString().toUpperCase())
  })
}

Let's now build the client:

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

const wsock = require('websocket-stream')
//  add the websocket or ssl connection address (wss:// for ssl)
//  and use the browser location.host to get the url
var stream = wsock('ws://' + location.host)


// so that we can have an input box,
// and some html to put the result
// his favorite module...
// it uses template strings
const html = require('yo-yo')

function update
  //	****		client.js		****

const wsock = require('websocket-stream')
//  add the websocket or ssl connection address (wss:// for ssl)
//  and use the browser location.host to get the url
var stream = wsock('ws://' + location.host)


// so that we can have an input box,
// and some html to put the result
// his favorite module...
// it uses template strings
const html = require('yo-yo')

// we need through so that we can `pipe` through messages... ↴
var through = require('through2')
var stream = wsock('ws://' + location.host)
// need a root render into
var root = document.body.appendChild(document.createElement('div'))
// we will store the server response here ↴
var output = []
update() // (renders...)

stream.pipe(through(function (buf, enc, next) {
  // put the response into output
  output.push(buf.toString())
  update()
  next()
}))

function update () {
  // insert a block of markup...
  html.update(root, html`<div>
  // onsubmit to handle the submit event ↴
    <form onsubmit=${onsubmit}>
    // note name="msg"
      <input type="text" name="msg">
    </form>
    // the pre tag to handle the response displaying
    <pre>${output.join('')}</pre>
  </div>`)
  // handle the sumbitting
  function onsubmit (ev) {
    // the usual preventDefault
    ev.preventDefault()
    // get the "msg" value:
    stream.write(this.elements.msg.value + '\n')
    // this.reset method available on forms
    // clears out the form records
    this.reset()
  }
}

Then create the minimal html to run:

  <!--//	****		public/index.html		****-->

<body><script src=bundle.js></script></body>

The <body> will help you avoid writing domReady boilerplate stuff.

Then use browserify to create the bundle:

$ browserify client.js > public/bundle.js (of course before you had run $ npm i -g browserify

And then: $ node server.js

Now, you can go to localhost:5000 in a browser and youu have the input box where you can type.