Socket.io integration between an Express and Angular app is a breeze. I'll outline the Express implementation first, then outline Angular integration.
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')
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));
}]);
Please help me, I don't know why you do:
app.use(function(req, res, next) { req.io = io; next(); });
io
is assigned toreq
andio
can only be used when client makes HTTP request POST to route '/'. Why don't we usesocket.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?