examples: add sse

This commit is contained in:
Yoshua Wuyts
2016-06-20 23:51:29 +01:00
parent bae31831fe
commit 9486df4725
5 changed files with 130 additions and 1 deletions
+1 -1
View File
@@ -397,7 +397,7 @@ app.model({
} }
], ],
effects: { effects: {
'sse:close': () => stream.close() 'sse:close': () => stream.close(),
'app:error': (state, event) => console.error(`error: ${event.payload}`), 'app:error': (state, event) => console.error(`error: ${event.payload}`),
'app:print': (state, event) => console.log(`sse: ${event.payload}`) 'app:print': (state, event) => console.log(`sse: ${event.payload}`)
} }
+46
View File
@@ -0,0 +1,46 @@
const choo = require('../../')
const app = choo()
app.model(createModel())
app.router((route) => [
route('/', mainView)
])
const tree = app.start()
document.body.appendChild(tree)
function mainView (params, state, send) {
return choo.view`
<div>${state.logger.msg}</div>
`
}
function createModel () {
const stream = new window.EventSource('/sse')
return {
namespace: 'logger',
state: {
msg: ''
},
subscriptions: [
function (send) {
stream.onerror = (e) => {
send('logger:error', { payload: JSON.stringify(e) })
}
stream.onmessage = (e) => {
const msg = JSON.parse(e.data).message
send('logger:print', { payload: msg })
}
}
],
reducers: {
'print': (action, state) => {
return ({ msg: state.msg + ' ' + action.payload })
}
},
effects: {
close: () => stream.close(),
error: (action, state) => console.error(`error: ${action.payload}`)
}
}
}
+14
View File
@@ -0,0 +1,14 @@
{
"name": "http",
"private": true,
"main": "client.js",
"scripts": {
"start": "NODE_ENV=development node server.js"
},
"dependencies": {
"bankai": "^2.0.2",
"browserify": "^13.0.1",
"server-router": "^2.1.0",
"sse": "0.0.6"
}
}
+55
View File
@@ -0,0 +1,55 @@
const serverRouter = require('server-router')
const browserify = require('browserify')
const bankai = require('bankai')
const http = require('http')
const SSE = require('sse')
const clients = []
const PORT = 8080
const server = http.createServer(createRouter())
server.listen(PORT, () => {
process.stdout.write(`listening on port ${PORT}\n`)
var sse = new SSE(server)
// code adapted from: https://github.com/markbrown4/server-sent-events-demo
sse.on('connection', (stream) => {
clients.push(stream)
console.log('Opened connection 🎉')
var json = JSON.stringify({ message: 'Gotcha' })
stream.send(json)
console.log('Sent: ' + json)
stream.on('close', () => {
clients.splice(clients.indexOf(stream), 1)
console.log('Closed connection 😱')
})
})
})
// emit data every 1.5 seconds
setInterval(() => {
var json = JSON.stringify({ message: 'Hello hello!' })
clients.forEach((stream) => {
stream.send(json)
console.log('Sent: ' + json)
})
}, 1500)
function createRouter () {
const router = serverRouter('/404')
const html = bankai.html({ css: false })
router.on('/', (req, res) => html(req, res).pipe(res))
const js = bankai.js(browserify, require.resolve('./client.js'))
router.on('/bundle.js', (req, res) => js(req, res).pipe(res))
router.on('/404', (req, res) => {
res.statusCode = 404
res.end('{ "message": "the server is confused" }')
})
return router
}
+14
View File
@@ -0,0 +1,14 @@
const choo = require('../../../')
module.exports = function (params, state, send) {
const error = state.app.error[0]
const title = state.api.title
return choo.view`
<section>
<h1>${title}</h1>
<h2>Latest error: ${error}</h2>
<button onclick=${(e) => send('api:good')}>OK!</button>
<button onclick=${(e) => send('api:bad')}>Naughty</button>
</section>
`
}