Routes
module.exports = ({ Router, io }) => {
const router = Router()
/* GET users listing. */
router
.get('/', function (req, res, next) {
res.render('message', { title: 'Message Page' })
})
.post('/', (req, res) => {
io.emit('client-message', { ...req.body, id: 'POST' })
res.json(req.body)
})
return router
}
File: routes/io-message.js
App
module.exports = ({ express, app, io }) => {
const { Router } = express
app.use('/message', require('./routes/io-message')({ Router, io }))
io.on('connection', socket => {
console.log('Socket Connect:', { id: socket.id })
socket.on('disconnect', log => {
console.log({ id: socket.id, log })
})
socket.on('server-message', msg => {
console.log('message:', { msg })
io.emit('client-message', { id: socket.id, message: msg })
})
})
return app
}
Snippet: app.js
Server
#!/usr/bin/env node
var http = require('http'),
express = require('express'),
app = express()
/**
* Create HTTP server.
*/
var server = http.createServer(app)
var io = require('socket.io')(server)
require('../app')({ express, app, io })
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port)
Snippet: bin/www
View
<style rel="stylesheet/less" type="text/less">
body {
margin: 0;
padding: 0;
}
.app-tpl {
height: ~'calc(100vh)';
overflow-y: auto;
overflow-x: hidden;
background-color: rgb(248, 239, 201);
}
.messages {
list-style: none;
margin: 0;
padding: 0;
li {
&:nth-child(odd) {
background-color: yellow;
}
}
}
</style>
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/2.7.1/less.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script type="text/html" id="app-tpl">
<div class="app-tpl">
<h1>{{title}}</h1>
<input v-model="formData.message" placeholder="Message" />
<div>
<button @click="onEmit">Emit Message</button>
<button @click="onPost">Post Message</button>
</div>
<ul class="messages">
<li v-for="msg in messages"><pre v-text="msg" /></li>
</ul>
</div>
</script>
<script>
var socket = io(),
el = document.currentScript
const storeMessages = {
state: Vue.observable({
messages: []
}),
methods: {
onMessage(message) {
this.state.messages.unshift(message)
}
}
},
App = new Vue({
template: '#app-tpl',
data: () => ({
formData: {
message: ''
}
}),
computed: {
messages() {
return storeMessages.state.messages
}
},
methods: {
onEmit() {
const { formData } = this
socket.emit('server-message', formData.message)
console.log('onEmit:', formData.message)
formData.message = ''
},
onPost() {
const { formData } = this,
url = '//localhost:3000/message'
console.log('onPost:', formData.message)
fetch(url, {
method: 'POST',
body: JSON.stringify(formData)
})
.then(res => res.json())
.then(console.log.bind(console, 'RESPONSE:'))
.catch(console.error.bind(console, 'FAIL - onPost:'))
formData.message = ''
}
}
})
App.$mount(el)
socket.on(
'client-message',
storeMessages.methods.onMessage.bind(storeMessages)
)
</script>
File: views/message.hbs