Skip to content

Instantly share code, notes, and snippets.

@ahdinosaur
Created March 22, 2016 00:32
Show Gist options
  • Save ahdinosaur/6a6882d052270f05b5b9 to your computer and use it in GitHub Desktop.
Save ahdinosaur/6a6882d052270f05b5b9 to your computer and use it in GitHub Desktop.
live streams for real-time cats
var Ws = require('websocket-stream')
var ws = Ws('ws://localhost:8000')
var stream = require('readable-stream')
var h = require('virtual-dom/virtual-hyperscript/svg')
var vraf = require('virtual-raf')
var vdom = require('virtual-dom')
var keycode = require('keycode')
var state = { x: 0, y: 0 }
var step = 0.01
var tree = vraf(state, render, vdom)
var main = document.querySelector('main')
main.appendChild(tree.render())
ws
.pipe(stream.Transform({
objectMode: true,
transform: function (chunk, encoding, cb) {
cb(null, JSON.parse(chunk))
}
}))
.pipe(stream.Transform({
objectMode: true,
transform: function (state, encoding, cb) {
console.log('state', state)
state = state
tree.update(state)
cb()
}
}))
window.addEventListener('keydown', function (evt) {
var code = keycode(evt)
switch (code) {
case 'left':
state.x -= step
break
case 'right':
state.x += step
break
case 'up':
state.y -= step
break
case 'down':
state.y += step
break
}
tree.update(state)
writeState()
})
function writeState () {
ws.write(JSON.stringify(state))
}
function render (state) {
return h('svg.container', {
height: '100%',
width: '100%',
viewBox: '0 0 1 1',
preserveAspectRatio: 'none'
}, [
h('circle.cat', {
cx: state.x,
cy: state.y,
r: 0.01
})
])
}
<!DOCTYPE html>
<html>
<head>
<title>real-time cats!</title>
</head>
<body>
<main></main>
<script src='/bundle.js'></script>
</body>
</html
var ws = require('websocket-stream')
var http = require('http')
var browserify = require('browserify')
var ecstatic = require('ecstatic')
var stream = require('readable-stream')
function handleHttp (req, res) {
if (req.url == '/bundle.js') {
browserify('./browser').bundle().pipe(res)
} else {
ecstatic(__dirname)(req, res)
}
}
var httpServer = http.createServer(handleHttp)
var wss = ws.createServer({
server: httpServer
}, handleWs)
var state = {
x: 0.5,
y: 0.5
}
var clients = []
function handleWs (client) {
console.log('client connected')
clients.push(client)
writeState(client)
// client sends action to server
// server uses action to update state
// server sends state to all connected clients
//
client
.pipe(stream.Transform({
objectMode: true,
transform: function (chunk, enc, cb) {
cb(null, JSON.parse(chunk))
}
}))
.pipe(stream.Transform({
objectMode: true,
transform: function (state, enc, cb) {
state = state
clients.forEach(writeState)
cb()
}
}))
}
httpServer.listen(8000, function () {
console.log('server listening on port 8000')
})
function writeState (client) {
client.write(JSON.stringify(state))
}
{
"name": "real-time-cat",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node-dev index.js"
},
"keywords": [],
"author": "Mikey <[email protected]> (http://dinosaur.os)",
"license": "ISC",
"dependencies": {
"browserify": "^13.0.0",
"ecstatic": "^1.4.0",
"keycode": "^2.1.1",
"readable-stream": "^2.0.6",
"virtual-dom": "^2.1.1",
"virtual-raf": "^3.0.0",
"websocket-stream": "^3.1.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment