expressjs app with socket.io

Tuesday, October 11, 2016

I have the following app structure generated by express generator. I start the app with $ DEBUG=foo:* npm start

.
|____app.js
|____bin
| |____www
|____data
| |____readings.db
|____LICENSE
|____node_modules
| |____express
| |____ …
|____package.json
|____public
| |____stylesheets
| |____javascripts
| |____images
|____README.md
|____routes
| |____index.js
| |____readings.js
| |____sensors.js
|____views
| |____error.hjs
| |____index.hjs

In app.js

var express = require('express');
var app = express();
var io = require('socket.io')();
app.io = io;

// notice the `(io)` for the routes that need to be socket-aware
var routes = require('./routes/index');
var sensors = require('./routes/sensors');
var readings = require('./routes/readings')(io);

…

// start listening with socket.io
app.io.on('connection', function(socket){  
    console.log('a user connected');
});

module.exports = app;

In ./bin/www

app.io.attach(server);

Then in ./routes/readings.js that should be socket-aware

var express = require('express');
var app = express();
var router = express.Router();
var path = require('path');
var Datastore = require('nedb');
var db_readings = new Datastore({
    filename: path.join(__dirname. '..' , 'data' , 'readings.db'), 
    autoload: true
});

module.exports = function(io) {
    router.put('/', jsonParser, function(req, res, next) {
        if (!req.body) return res.sendStatus(400);

        db_readings.insert(req.body, function (err, newDoc) {
            io.emit("reading", {id: newDoc._id});
            res.send('Success PUTting data! id: ' + newDoc._id);
        });
    });

    return router;
}

Finally, in the index.hjs template for the client-side

<script src="/socket.io/socket.io.js"></script>
<script>
    var socket = io();
    socket.on('reading', function (data) {
        console.log(data);
    });
</script>

The above works. When data are inserted into readings.db via an http PUT (see readings.js), an event is emitted by io.emit('reading', data) and the browser receives that event and shows it in the browser console with socket.on('reading', function (data) { … });