From 3a172711f47c451d9c71828a5da0c66894bfb364 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 28 Nov 2014 19:33:07 -0500 Subject: [PATCH] socket.io index refactor --- src/socket.io/index.js | 254 +++++++++++++++++++++-------------------- 1 file changed, 133 insertions(+), 121 deletions(-) diff --git a/src/socket.io/index.js b/src/socket.io/index.js index cb913a0f8d..a2b74857c7 100644 --- a/src/socket.io/index.js +++ b/src/socket.io/index.js @@ -19,173 +19,185 @@ var SocketIO = require('socket.io'), Sockets = {}, Namespaces = {}; -/* === */ - - var io; Sockets.init = function(server) { var config = { - transports: ['polling', 'websocket'], + transports: ['websocket', 'polling'], path: nconf.get('relative_path') + '/socket.io' }; + requireModules(); + io = new SocketIO(); addRedisAdapter(io); io.use(socketioWildcard); + io.use(authorize); + + io.on('connection', onConnection); io.listen(server, config); Sockets.server = io; +}; - fs.readdir(__dirname, function(err, files) { - files.splice(files.indexOf('index.js'), 1); +function onConnection(socket) { + socket.ip = socket.request.connection.remoteAddress; - async.each(files, function(lib, next) { - if (lib.substr(lib.length - 3) === '.js') { - lib = lib.slice(0, -3); - Namespaces[lib] = require('./' + lib); - } + logger.io_one(socket, socket.uid); - next(); - }); + onConnect(socket); + + socket.on('disconnect', function() { + onDisconnect(socket); }); - io.use(function(socket, next) { - console.log('AUTH'); + socket.on('*', function(payload) { + onMessage(socket, payload); + }); +} - var handshake = socket.request, - sessionID; +function onConnect(socket) { + if (socket.uid) { + socket.join('uid_' + socket.uid); + socket.join('online_users'); + + async.parallel({ + user: function(next) { + user.getUserFields(socket.uid, ['username', 'userslug', 'picture', 'status'], next); + }, + isAdmin: function(next) { + user.isAdministrator(socket.uid, next); + } + }, function(err, userData) { + if (err || !userData.user) { + return; + } + socket.emit('event:connect', { + username: userData.user.username, + userslug: userData.user.userslug, + picture: userData.user.picture, + isAdmin: userData.isAdmin, + uid: socket.uid + }); - if (!handshake) { - return next(new Error('[[error:not-authorized]]')); - } + socket.broadcast.emit('event:user_status_change', {uid: socket.uid, status: userData.user.status}); + }); + } else { + socket.join('online_guests'); + socket.emit('event:connect', { + username: '[[global:guest]]', + isAdmin: false, + uid: 0 + }); + } +} - cookieParser(handshake, {}, function(err) { - if (err) { - return next(err); - } +function onDisconnect(socket) { + var socketCount = Sockets.getUserSocketCount(socket.uid); - var sessionID = handshake.signedCookies['express.sid']; + if (socket.uid && socketCount <= 0) { + socket.broadcast.emit('event:user_status_change', {uid: socket.uid, status: 'offline'}); + } - db.sessionStore.get(sessionID, function(err, sessionData) { - if (err) { - return next(err); - } - if (sessionData && sessionData.passport && sessionData.passport.user) { - socket.uid = parseInt(sessionData.passport.user, 10); - } else { - socket.uid = 0; - } - next(); - }); - }); - }); + // TODO : needs fixing for cluster - io.on('connection', function(socket) { - console.log('CONNECTED', socket.uid, socket.id); + // for(var roomName in io.sockets.manager.roomClients[socket.id]) { + // if (roomName.indexOf('topic') !== -1) { + // io.sockets.in(roomName.slice(1)).emit('event:user_leave', socket.uid); + // } + // } +} - socket.ip = socket.request.connection.remoteAddress; +function onMessage(socket, payload) { + if (!payload.data.length) { + return winston.warn('[socket.io] Empty payload'); + } - logger.io_one(socket, socket.uid); + var eventName = payload.data[0]; + var params = payload.data[1]; + var callback = typeof payload.data[payload.data.length - 1] === 'function' ? payload.data[payload.data.length - 1] : function() {}; - if (socket.uid) { - socket.join('uid_' + socket.uid); - socket.join('online_users'); + if (!eventName) { + return winston.warn('[socket.io] Empty method name'); + } - async.parallel({ - user: function(next) { - user.getUserFields(socket.uid, ['username', 'userslug', 'picture', 'status'], next); - }, - isAdmin: function(next) { - user.isAdministrator(socket.uid, next); - } - }, function(err, userData) { - if (err || !userData.user) { - return; - } - socket.emit('event:connect', { - status: 1, - username: userData.user.username, - userslug: userData.user.userslug, - picture: userData.user.picture, - isAdmin: userData.isAdmin, - uid: socket.uid - }); - - socket.broadcast.emit('event:user_status_change', {uid: socket.uid, status: userData.user.status}); - }); - } else { - socket.join('online_guests'); - socket.emit('event:connect', { - status: 1, - username: '[[global:guest]]', - isAdmin: false, - uid: 0 - }); - } + if (ratelimit.isFlooding(socket)) { + winston.warn('[socket.io] Too many emits! Disconnecting uid : ' + socket.uid + '. Message : ' + payload.name); + return socket.disconnect(); + } - socket.on('disconnect', function() { - var socketCount = Sockets.getUserSocketCount(socket.uid); - console.log('DISCONNECT', socket.uid, socket.id); - if (socket.uid && socketCount <= 0) { - socket.broadcast.emit('event:user_status_change', {uid: socket.uid, status: 'offline'}); + var parts = eventName.toString().split('.'), + namespace = parts[0], + methodToCall = parts.reduce(function(prev, cur) { + if (prev !== null && prev[cur]) { + return prev[cur]; + } else { + return null; } + }, Namespaces); + + if(!methodToCall) { + if (process.env.NODE_ENV === 'development') { + winston.warn('[socket.io] Unrecognized message: ' + eventName); + } + return; + } - // for(var roomName in io.sockets.manager.roomClients[socket.id]) { - // if (roomName.indexOf('topic') !== -1) { - // io.sockets.in(roomName.slice(1)).emit('event:user_leave', socket.uid); - // } - // } + if (Namespaces[namespace].before) { + Namespaces[namespace].before(socket, eventName, function() { + callMethod(methodToCall, socket, params, callback); }); + } else { + callMethod(methodToCall, socket, params, callback); + } +} + +function requireModules() { + fs.readdir(__dirname, function(err, files) { + files.splice(files.indexOf('index.js'), 1); - socket.on('*', function(payload) { - if (!payload.data.length) { - return winston.warn('[socket.io] Empty payload'); + async.each(files, function(lib, next) { + if (lib.substr(lib.length - 3) === '.js') { + lib = lib.slice(0, -3); + Namespaces[lib] = require('./' + lib); } - var eventName = payload.data[0]; - var params = payload.data[1]; - var callback = typeof payload.data[payload.data.length - 1] === 'function' ? payload.data[payload.data.length - 1] : function() {}; + next(); + }); + }); +} - if (!eventName) { - return winston.warn('[socket.io] Empty method name'); - } +function authorize(socket, next) { + var handshake = socket.request, + sessionID; - if (ratelimit.isFlooding(socket)) { - winston.warn('[socket.io] Too many emits! Disconnecting uid : ' + socket.uid + '. Message : ' + payload.name); - return socket.disconnect(); - } + if (!handshake) { + return next(new Error('[[error:not-authorized]]')); + } - var parts = eventName.toString().split('.'), - namespace = parts[0], - methodToCall = parts.reduce(function(prev, cur) { - if (prev !== null && prev[cur]) { - return prev[cur]; - } else { - return null; - } - }, Namespaces); - - if(!methodToCall) { - if (process.env.NODE_ENV === 'development') { - winston.warn('[socket.io] Unrecognized message: ' + eventName); - } - return; - } + cookieParser(handshake, {}, function(err) { + if (err) { + return next(err); + } - if (Namespaces[namespace].before) { - Namespaces[namespace].before(socket, eventName, function() { - callMethod(methodToCall, socket, params, callback); - }); + var sessionID = handshake.signedCookies['express.sid']; + + db.sessionStore.get(sessionID, function(err, sessionData) { + if (err) { + return next(err); + } + if (sessionData && sessionData.passport && sessionData.passport.user) { + socket.uid = parseInt(sessionData.passport.user, 10); } else { - callMethod(methodToCall, socket, params, callback); + socket.uid = 0; } + next(); }); }); -}; +} function addRedisAdapter(io) { if (nconf.get('redis')) {