var EventEmitter = require('events').EventEmitter; var util = require('util'); var logger = require('pomelo-logger').getLogger('pomelo', __filename); var utils = require('../../util/utils'); var FRONTEND_SESSION_FIELDS = ['id', 'frontendId', 'uid', '__sessionService__']; var EXPORTED_SESSION_FIELDS = ['id', 'frontendId', 'uid', 'settings']; var ST_INITED = 0; var ST_CLOSED = 1; /** * Session service maintains the internal session for each client connection. * * Session service is created by session component and is only * available in frontend servers. You can access the service by * `app.get('sessionService')` or `app.sessionService` in frontend servers. * * @param {Object} opts constructor parameters * @class * @constructor */ var SessionService = function(opts) { opts = opts || {}; this.singleSession = opts.singleSession; this.sessions = {}; // sid -> session this.uidMap = {}; // uid -> sessions }; module.exports = SessionService; /** * Create and return internal session. * * @param {Integer} sid uniqe id for the internal session * @param {String} frontendId frontend server in which the internal session is created * @param {Object} socket the underlying socket would be held by the internal session * * @return {Session} * * @memberOf SessionService * @api private */ SessionService.prototype.create = function(sid, frontendId, socket) { var session = new Session(sid, frontendId, socket, this); this.sessions[session.id] = session; return session; }; /** * Bind the session with a userstate id. * * @memberOf SessionService * @api private */ SessionService.prototype.bind = function(sid, uid, cb) { var session = this.sessions[sid]; if(!session) { process.nextTick(function() { cb(new Error('session does not exist, sid: ' + sid)); }); return; } if(session.uid) { if(session.uid === uid) { // already bound with the same uid cb(); return; } // already bound with other uid process.nextTick(function() { cb(new Error('session has already bound with ' + session.uid)); }); return; } var sessions = this.uidMap[uid]; if(!!this.singleSession && !!sessions) { process.nextTick(function() { cb(new Error('singleSession is enabled, and session has already bound with uid: ' + uid)); }); return; } if(!sessions) { sessions = this.uidMap[uid] = []; } for(var i=0, l=sessions.length; i