Kontra

Let’s have some fun with express, angularjs and socket.io.
For backend, we will use latest version of Express (4.xx at the time of writing),
for template engine – EJS,
for express session… well… express-session,
and to connect socket.io (1.3) with express session, we’ll use express-socket.io-session.
We will also need body parser because in new express version it’s no longer bundled with express.
Ok, so let’s set it all up as simply as possible.
First, create some project structure. In this tutorial we’ll use:

[js]/ -views --pages ---index.ejs --public ---angular.js -index.js [/js] 

index.js is our main file, in views folder we have pages subfolder for all pages we can template and public subfolder is for everything you want to expose publicly, for example: images, client javascript…
Now let’s checkout our index.js

[js]var express = require('express'), bodyParser = require('body-parser'), http = require('http'), app = express(), session = require('express-session')({ secret: "aliensAreAmongUs", resave: true, saveUninitialized: true }), sharedsession = require('express-socket.io-session'), port = 3016; app.set('view engine', 'ejs'); app.use(express.static(__dirname + '/views/public')); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); app.use(session); app.all('/', function (req, res) { req.session.myCustomData = {msg:"add something you need to session, like userID", userID:Math.floor(Math.random()*100)} res.render('pages/index', {msg:"hello", session: req.session}); }); var httpServer = http.Server(app); httpServer.listen(port, function(){ console.log("server listening on port", port); }); io = require('socket.io').listen(httpServer); io.use(sharedsession(session)); io.on('connection', function(socket){ console.log("connected"); socket.emit("greetings", {msg:"hello"}); socket.on("something", function(data){ console.log("client["+socket.handshake.session.myCustomData.userID+"] sent data: " + data); }) }); [/js]

if you get any errors after copy/pasting this code, check if you have installed all packages mentioned above, just do “npm install <package name you’re missing>”
views/pages/index.ejs:

[html]<!doctype html> <html lang="en" ng-app="fenixApp"> <head> <title>playing around</title> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22%2Fsocket.io%2Fsocket.io.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" /> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.2.25%2Fangular.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" /> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.2.25%2Fangular-route.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" /> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22angular.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" /> </head> <body ng-controller="mainController"> <div> msg: <%= msg %> session: <%= JSON.stringify(session) %> recievedTroughSocket: {{recievedTroughSocket}} <button ng-click="sendWithSocket('hello server')">send something</button> </div> </body> </html> [/html]

views/public/angular.js

[js]var fenixApp = angular.module('fenixApp', ['ngRoute']); fenixApp.factory('socket', ['$rootScope', function ($rootScope) { var socket = io.connect(); console.log("socket created"); return { on: function (eventName, callback) { function wrapper() { var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); } socket.on(eventName, wrapper); return function () { socket.removeListener(eventName, wrapper); }; }, emit: function (eventName, data, callback) { socket.emit(eventName, data, function () { var args = arguments; $rootScope.$apply(function () { if(callback) { callback.apply(socket, args); } }); }); } }; }]); fenixApp.config(['$routeProvider', function($routeProvider){ $routeProvider //route for home page .when('/', { templateUrl : '/', controller : 'mainController' }) }]); fenixApp.controller('mainController', function($scope, socket) { $scope.recievedTroughSocket = "still waiting for data..."; $scope.sendWithSocket = function(msg){ socket.emit("something", msg); } socket.on("greetings", function(data){ console.log("user data: " + JSON.stringify(data)); $scope.recievedTroughSocket = data.msg; }); });[/js]

clicking on button will send to server string specified in sendWithSocket function argument, you can change string to object if you want to send more data. Server will output something like this:

[html]client[38] sent data: hello server[/html]

Personally I like this setup (plus mongodb), you can use jade if you don’t like ejs, also you don’t need to use angularjs, you can strip down this code to bare bones and just go with node and socket.io. You can also try templating js files in case you need more control over what you want to expose to clients.
For example you can transfer angular.js from public folder to some other folder in views and name it angular.ejs just edit the route for it like so:

[js]app.get('/otherFolder/angular.js', function (req, res) { res.setHeader('Content-Type', 'text/javascript'); res.render('otherFolder/angular', {someData:"to pass to ejs"}); });[/js]

That’s it, have fun.



Author

Kontra Agency

We are a group of people gathered under one roof who become a family. Always looking for some new ideas, new tools and strategies, new ways of communication and above all, new ways of having fun while working.


Comments

One response to “How To Combine Express, AngularJS and Socket.io”

  1. […] a code example I will use code from my previous tutorial which you can check out How to combine Express, Angularjs and Socket.io. It is not required to use the same code as me, you can shortcut it and try it in yours but it […]

Leave a Reply

Your email address will not be published. Required fields are marked *

Shares

Subscribe to our blog

If you liked this article, join other 10.000 subscribers to get fresh news from development and design world.