Skip to content

Instantly share code, notes, and snippets.

@ben-bradley
Last active August 29, 2015 14:02
Show Gist options
  • Save ben-bradley/651de8ca850c2ec4506c to your computer and use it in GitHub Desktop.
Save ben-bradley/651de8ca850c2ec4506c to your computer and use it in GitHub Desktop.
Making Express, Socket.IO, and Angular play nicely together
// File: client/scripts/controllers/main.js
// With this, you can use 'socket' very nicely (IMHO)
'use strict';
angular.module('theApp')
.controller('MainCtrl', function ($scope, socket) {
$scope.now = 'loading...';
var ioTime = socket.connect('/io/time');
ioTime.on('time', function(now) {
$scope.now = now;
});
var ioPing = socket.connect('/io/ping');
ioPing.on('pong', function(data) {
console.log(data);
});
});
// File: server/server.js
// This is the Node file to fire up an Socket.IO enabled Express server
// Code your io stuff as normal
var express = require('express'),
session = require('express-session'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
http = require('http'),
socketio = require('socket.io');
var app = express();
var server = http.createServer(app);
var io = socketio.listen(server);
var sessionStore = new session.MemoryStore();
app.use(express.static(__dirname+'/../client')); // serve the client
app.use(bodyParser());
app.use(cookieParser());
app.use(session({
store: sessionStore,
secret: ''+new Date().getTime()
}));
// this is the authentication middleware that links the
// Express session with the socket. You need to manage
// the session within the authentication stack of the
// Express app:
/*
app.get('/signout', function(req, res) {
...
req.session.destroy();
...
})
*/
io.use(function(socket, next) {
var cookie = socket.handshake.headers.cookie,
sid = cookie.match(/connect.sid=s%3A([^\.]+)\.*/);
if (sid)
sid = sid[1];
else
return next('no session', false);
sessionStore.get(sid, function(err, session) {
if (!session)
return next('no session', false);
// check every 5 seconds to see if the express session is active
var checkSession = setInterval(function() {
sessionStore.get(sid, function(err, session) {
if (!session) {
socket.disconnect(true);
clearInterval(checkSession);
}
});
}, 5000);
next();
});
});
io.of('/io/ping').on('connection', function(socket) {
setInterval(function() { // emit a pong every 1 sec
socket.emit('pong', { pong: new Date() });
}, 1000);
});
io.of('/io/time').on('connection', function(socket) {
setInterval(function() { // emit a new Date() every .5 sec
socket.emit('time', new Date());
}, 500);
});
server.listen(8000);
// File: client/scripts/services/socket.js
// Here's the good stuff! =)
// Heavily inspired by another developer's work whom I've lost track of
'use strict';
angular.module('theApp')
.service('socket', function($rootScope) {
this.connect = function(namespace) {
console.log('connecting: ', namespace)
var _socket = io.connect(namespace);
_socket._on = _socket.on;
_socket._emit = _socket.emit;
_socket.on = function(eventName, callback) {
_socket._on(eventName, function() {
var args = arguments;
$rootScope.$apply(function() {
callback.apply(_socket, args);
});
});
};
_socket.emit = function(eventName, data, callback) {
_socket._emit(eventName, data, function() {
var args = arguments;
$rootScope.$apply(function() {
if (callback) {
callback.apply(_socket, args);
}
});
});
};
return _socket;
};
})
@ben-bradley
Copy link
Author

I'm struggling with authentication on the socket, if anyone has any ideas for nice, clean solutions, please let me know.

@ben-bradley
Copy link
Author

I think I've sorted out the authentication sync between Express & Socket.IO in server.js

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