Skip to content

Instantly share code, notes, and snippets.

@sktt
Last active October 12, 2017 22:25
Show Gist options
  • Save sktt/0f6fbf04939e0f65195634015ca7ec60 to your computer and use it in GitHub Desktop.
Save sktt/0f6fbf04939e0f65195634015ca7ec60 to your computer and use it in GitHub Desktop.
Skeleton code for setting up a websocket server, with a route for piping stdin to the websocket. So you could for instance do `ping google.com | node websocket.js` and maybe plot the results in the browser.... :D
const URL = require('url')
const Rx = require('rxjs/Rx')
const WebSocketServer = require('ws').Server
/** pipe stdin out on websocket */
function pipe (conn) {
process.stdin.setEncoding('utf8')
return Rx.Observable.create(obs => {
process.stdin.on('data', obs.next.bind(obs))
process.stdin.on('end', obs.complete.bind(obs))
})
}
const wsHandlers = {
'/pipe': pipe
}
const WS_OPEN = 1
const wss$ = ((wss) => {
wss.on('listening', () => {
console.log('wss:', wss.options.host + ':' + wss.options.port)
})
return Rx.Observable.create((obs) => {
wss.on('connection', obs.next.bind(obs))
wss.on('rror', obs.error.bind(obs))
return () => {
console.log('wss: closing all client connections')
wss.close()
}
})
})(new WebSocketServer({ host: '127.0.0.1', port: 8888 }))
const wssSubscription = wss$.subscribe({
next (conn) {
const url = URL.parse(conn.upgradeReq.url)
const handler = wsHandlers[url.pathname]
if (!handler || !(handler instanceof Function)) {
console.error('No handler available for', url.pathname)
}
handler(conn)
.takeUntil(Rx.Observable.merge(
Rx.Observable.fromEvent(conn, 'error'),
Rx.Observable.fromEvent(conn, 'close')).take(1)
)
.subscribe({
next (data) {
if (conn.readyState !== WS_OPEN) {
console.error(
'ERR: tried to send data to a websocket with readyState:',
conn.readyState)
} else {
conn.send(data)
}
},
error (err) {
console.error('ERR: handler messed up!')
console.error(err)
conn.close()
},
complete () {
console.log('Handler finished!')
conn.close()
}
})
},
error (err) {
console.error('wss: ERR:', err)
},
complete () {
console.log('wss: complete!')
}
})
process.on('SIGINT', () => {
wssSubscription.unsubscribe()
process.exit(130)
})
process.on('uncaughtException', (e) => {
console.error(e.stack)
console.error('uncaughtException: ', e)
wssSubscription.unsubscribe()
process.exit(1)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment