In this article, I am going to show you the procedure to build a real-time dashboard in MEAN stack using WebSocket. Suppose you add a few new documents in the MongoDB collection, How can you get it into the dashboard in a push mode? This is similar to how Gmail brings in new emails without the user having to do anything. For this, we need to use socket.io to push from server to client whenever it wants to. Let us first understand about WebSockets and Socket.io.

What is WebSockets?

WebSocket, is a protocol that allows a web application to have two-way communication between browser and server by creating a full-duplex channel over TCP. WebSocket is protocol is compatible with Http. It uses TCP 80. It allows web applications to be real-time and allows advanced communication between the client and the server. It supports all the major browsers like Firefox, IE, Chrome, Safari, etc.

Socket.IO allows us to build real-time two-way event-based communication applications very easily. It is a Javascript library and Node.js module.

Pre-requisites & Setup

Node.js & NPM

At first, we need to make sure that node.js & npm is installed in your system

# To check node version $ node -v # To check npm version $ npm -v 1 2 3 4 # To check node version $ node - v # To check npm version $ npm - v

Here I assumed that you already have set up an app in MEAN stack. If you didn’t, please check here for more details. Here we will focus on WebSocket and Mongoose webhook to build a real-time dashboard

Add socket.IO and mongoose-webhooks to package.json

Here package.json is a file, It contains metadata and dependencies of our project, npm can use this package.json to download modules.

Now we add socket.io and mongoose-webhooks like a dependency on our project.

{ "name": "medical-dashboard", "version": "0.0.0", "private": true, "scripts": { "start": "node ./bin/www" }, "dependencies": { "body-parser": "~1.16.0", "cookie-parser": "~1.4.3", "debug": "~2.6.0", "dotenv": "4.0.0", "ejs": "~2.5.2", "express": "~4.14.1", "helmet": "3.4.0", "mongoose": "~4.8.1", "mongoose-webhooks": "0.0.1", "morgan": "~1.7.0", "serve-favicon": "~2.3.2", "socket.io": "1.7.3" } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 { "name" : "medical-dashboard" , "version" : "0.0.0" , "private" : true , "scripts" : { "start" : "node ./bin/www" } , "dependencies" : { "body-parser" : "~1.16.0" , "cookie-parser" : "~1.4.3" , "debug" : "~2.6.0" , "dotenv" : "4.0.0" , "ejs" : "~2.5.2" , "express" : "~4.14.1" , "helmet" : "3.4.0" , "mongoose" : "~4.8.1" , "mongoose-webhooks" : "0.0.1" , "morgan" : "~1.7.0" , "serve-favicon" : "~2.3.2" , "socket.io" : "1.7.3" } }

Socket.io is real-time framework server

Mongoose-webhooks is a mongoose plugin to send webhook on mongoose model events.

# Run below command to install the above dependencies $ npm install 1 2 # Run below command to install the above dependencies $ npm install

Adding Socket.IO to app.js

Here we are adding Socket.IO to app.js. Just replace the following code in app.js to do this.

/** * Create HTTP server. */ var server = http.createServer(app); // exports.io = require('socket.io')(server) app.io = require('socket.io')(server) app.io.sockets.on('connection', function (socket) { console.log('connected') }); /** * Listen on provided port, on all network interfaces. */ server.listen(port); 1 2 3 4 5 6 7 8 9 10 11 12 13 /** * Create HTTP server. */ var server = http . createServer ( app ) ; // exports.io = require('socket.io')(server) app . io = require ( 'socket.io' ) ( server ) app . io . sockets . on ( 'connection' , function ( socket ) { console . log ( 'connected' ) } ) ; /** * Listen on provided port, on all network interfaces. */ server . listen ( port ) ;

This can hold the HTTP server is in a variable called server passes it for Socket.IO module to attach it. The last code block will take this server variable and then execute the listen function which will start HTTP server.

Mongoose Webhook handler

We assume you already setup mongo collection and their schema. It looks like below

(function(){ "use strict"; var mongoose = require('mongoose'); var mongooseWebhooks = require('mongoose-webhooks'); //create a schema for hospital_rounds var hospitalRoundSchema = mongoose.Schema({ _id: { type: mongoose.Schema.Types.ObjectId}, HospitalAlias: { type: String}, DateOfService: { type: String}, DoctorAlias: { type: String}, Charge: { type: String}, Level: { type: String} }); hospitalRoundSchema.plugin(mongooseWebhooks, {'url': process.env.DEPLOY_HOST+'/rounds/websocket'}); // module.exports = mongoose.model('HospitalRound', hospitalRoundSchema) module.exports = mongoose.model('HospitalRound', hospitalRoundSchema, "hospital_rounds") })(); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ( function ( ) { "use strict" ; var mongoose = require ( 'mongoose' ) ; var mongooseWebhooks = require ( 'mongoose-webhooks' ) ; //create a schema for hospital_rounds var hospitalRoundSchema = mongoose . Schema ( { _id : { type : mongoose . Schema . Types . ObjectId } , HospitalAlias : { type : String } , DateOfService : { type : String } , DoctorAlias : { type : String } , Charge : { type : String } , Level : { type : String } } ) ; hospitalRoundSchema . plugin ( mongooseWebhooks , { 'url' : process . env . DEPLOY_HOST + '/rounds/websocket' } ) ; // module.exports = mongoose.model('HospitalRound', hospitalRoundSchema) module . exports = mongoose . model ( 'HospitalRound' , hospitalRoundSchema , "hospital_rounds" ) } ) ( ) ;

Suppose you added a few new documents/rows into mongo DB collection. Mongoose webhook trigger POST request to send event through socket.io after document inserted into specific collections.The code looks like below in model

hospitalRoundSchema.plugin(mongooseWebhooks, {'url': process.env.DEPLOY_HOST+'/rounds/websocket'}); 1 hospitalRoundSchema . plugin ( mongooseWebhooks , { 'url' : process . env . DEPLOY_HOST + '/rounds/websocket' } ) ;

Emitting a new record received on the socket channel

Socket.IO provides a function called emit, for sending events.

Any new record inserted into the mongo collection will be emitted every connection on this socket by calling emit to send events.

The code looks like below,

//Emitting a new record received on socket connection router.post('/websocket', function(req, res, next) { req.app.io.sockets.emit('pageview'); }); 1 2 3 4 //Emitting a new record received on socket connection router . post ( '/websocket' , function ( req , res , next ) { req . app . io . sockets . emit ( 'pageview' ) ; } ) ;

Broadcasting a new record received on the socket channel

Any new record received on the socket channel will be broadcast to all the other connections on this socket by calling emit an event with the message.

The code looks like below,

// real-time - broadcasting new record on socket channel var socket = io.connect(window.location.host); socket.on('connect', function () { socket.send(window.location); socket.on('pageview', function (msg) { $scope.doctor_specification($scope.doctorAliasName) }); }); 1 2 3 4 5 6 7 8 // real-time - broadcasting new record on socket channel var socket = io . connect ( window . location . host ) ; socket . on ( 'connect' , function ( ) { socket . send ( window . location ) ; socket . on ( 'pageview' , function ( msg ) { $ scope . doctor_specification ( $ scope . doctorAliasName ) } ) ; } ) ;

Conclusion

That’s all. Now we have built a real-time dashboard using WebSocket i.e without the user having to do anything in the browser, Now you will be able to see new record changes in a dashboard chart. For any queries and doubts comment below. For more on MEAN stack web development follow AgiraTechnologies.