Skip to content

Instantly share code, notes, and snippets.

@patrickbrandt
Last active August 30, 2023 21:28
Show Gist options
  • Save patrickbrandt/1cd98a02c42e9e22a5a9 to your computer and use it in GitHub Desktop.
Save patrickbrandt/1cd98a02c42e9e22a5a9 to your computer and use it in GitHub Desktop.
Simple socket.io integration with Express + Angular

Socket.io integration between an Express and Angular app is a breeze. I'll outline the Express implementation first, then outline Angular integration.

Express + socket.io

Reference socket.io in layout.jade

npm install socket.io --save and then reference socket.io in your layout.jade file:

doctype html
html(ng-app="example")
  head
    title= title
    link(rel='stylesheet', href='/bootstrap/dist/css/bootstrap.css')
    link(rel='stylesheet', href='/stylesheets/style.css')
  body
    div(class="container-fluid")
        block content    
        
    script(type='text/javascript' src='/socket.io/socket.io.js')
    script(type='text/javascript' src='/angular/angular.js')
    script(type='text/javascript' src='/angular-resource/angular-resource.js')
    script(type='text/javascript' src='/angular-route/angular-route.js')
    script(type='text/javascript' src='/javascripts/app.js')
    script(type='text/javascript' src='/javascripts/services.js')
    script(type='text/javascript' src='/javascripts/controllers.js')

Create socket.io middleware

Include the following code in your app.js module (other standard Express module dependancies and middleware left out for brevity):

var express = require('express');
var http = require('http');
var io = require('socket.io');
var routes = require('./routes/index');

var app = express();

/**
 * Create HTTP server.
 */

var server = http.createServer(app);

/**
 * Setup custom app middleware
 */

/* setup socket.io */
io = io(server);
app.use(function(req, res, next) {
  req.io = io;
  next();
});
io.on('connection', function(socket) {
  //log.info('socket.io connection made');
  console.log('socket.io connection made');
});

app.use('/', routes);

server.listen('3000');

You can now emit socket.io events from any route handler (./routes/index in this example):

var express = require('express');
var router = express.Router();

router.post('/', function(req, res, next) {
  req.io.emit('some_event');
  //do some stuff
  req.io.emit("some_other_event"); //we did some stuff - emit a related event
});

module.exports = router;

#Angular + socket.io Create a service that wraps the socket.io global object:

angular.module('example')
.factory('io', ['$window', '$rootScope', function($window, $rootScope) {
  var _socket = $window.io('//localhost:3000');
  return {
    on: function(eventType, cb) {
      _socket.on(eventType, function() {
        cb(); 
        //NOTE: calling $apply will ensure that any model changes are reflected in the view
        $rootScope.$apply();
      });
    },
    emit: function(eventType, data) {
      _socket.emit(eventType, data);
    }
  };
}]);

Use the io service in a controller:

angular.module('example')
  .controller('MainCtrl', ['io', function(io) {
    this.state = 'something';
  	io.on('some_event', function() {
		  this.state = 'something else';
	  }.bind(this));
  }]);
@patrickbrandt
Copy link
Author

Note for me; good article on Angular providers: https://gist.github.com/demisx/9605099

@HungParfait
Copy link

Please help me, I don't know why you do:
app.use(function(req, res, next) { req.io = io; next(); });
io is assigned to req and io can only be used when client makes HTTP request POST to route '/'. Why don't we use socket.emit('post-event') in client instead of HTTP POST request. Thank you!!! And if client makes HTTP POST request, is a new TCP/IP connection established?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment