| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 | 
							- /**
 
-  * backend session service for backend session
 
-  */
 
- var utils = require('../../util/utils');
 
- var EXPORTED_FIELDS = ['id', 'frontendId', 'uid', 'settings'];
 
- /**
 
-  * Service that maintains backend sessions and the communiation with frontend
 
-  * servers.
 
-  *
 
-  * BackendSessionService would be created in each server process and maintains
 
-  * backend sessions for current process and communicates with the relative
 
-  * frontend servers.
 
-  *
 
-  * BackendSessionService instance could be accessed by
 
-  * `app.get('backendSessionService')` or app.backendSessionService.
 
-  *
 
-  * @class
 
-  * @constructor
 
-  */
 
- var BackendSessionService = function(app) {
 
-   this.app = app;
 
- };
 
- module.exports = BackendSessionService;
 
- BackendSessionService.prototype.create = function(opts) {
 
-   if(!opts) {
 
-     throw new Error('opts should not be empty.');
 
-   }
 
-   return new BackendSession(opts, this);
 
- };
 
- /**
 
-  * Get backend session by frontend server id and session id.
 
-  *
 
-  * @param  {String}   frontendId frontend server id that session attached
 
-  * @param  {String}   sid        session id
 
-  * @param  {Function} cb         callback function. args: cb(err, BackendSession)
 
-  *
 
-  * @memberOf BackendSessionService
 
-  */
 
- BackendSessionService.prototype.get = function(frontendId, sid, cb) {
 
-   var namespace = 'sys';
 
-   var service = 'sessionRemote';
 
-   var method = 'getBackendSessionBySid';
 
-   var args = [sid];
 
-   rpcInvoke(this.app, frontendId, namespace, service, method,
 
-             args, BackendSessionCB.bind(null, this, cb));
 
- };
 
- /**
 
-  * Get backend sessions by frontend server id and userstate id.
 
-  *
 
-  * @param  {String}   frontendId frontend server id that session attached
 
-  * @param  {String}   uid        userstate id binded with the session
 
-  * @param  {Function} cb         callback function. args: cb(err, BackendSessions)
 
-  *
 
-  * @memberOf BackendSessionService
 
-  */
 
- BackendSessionService.prototype.getByUid = function(frontendId, uid, cb) {
 
-   var namespace = 'sys';
 
-   var service = 'sessionRemote';
 
-   var method = 'getBackendSessionsByUid';
 
-   var args = [uid];
 
-   rpcInvoke(this.app, frontendId, namespace, service, method,
 
-             args, BackendSessionCB.bind(null, this, cb));
 
- };
 
- /**
 
-  * Kick a session by session id.
 
-  *
 
-  * @param  {String}   frontendId cooperating frontend server id
 
-  * @param  {Number}   sid        session id
 
-  * @param  {Function} cb         callback function
 
-  *
 
-  * @memberOf BackendSessionService
 
-  */
 
- BackendSessionService.prototype.kickBySid = function(frontendId, sid, cb) {
 
-   var namespace = 'sys';
 
-   var service = 'sessionRemote';
 
-   var method = 'kickBySid';
 
-   var args = [sid];
 
-   rpcInvoke(this.app, frontendId, namespace, service, method, args, cb);
 
- };
 
- /**
 
-  * Kick sessions by userstate id.
 
-  *
 
-  * @param  {String}          frontendId cooperating frontend server id
 
-  * @param  {Number|String}   uid        userstate id
 
-  * @param  {Function}        cb         callback function
 
-  *
 
-  * @memberOf BackendSessionService
 
-  */
 
- BackendSessionService.prototype.kickByUid = function(frontendId, uid, cb) {
 
-   var namespace = 'sys';
 
-   var service = 'sessionRemote';
 
-   var method = 'kickByUid';
 
-   var args = [uid];
 
-   rpcInvoke(this.app, frontendId, namespace, service, method, args, cb);
 
- };
 
- /**
 
-  * Bind the session with the specified userstate id. It would finally invoke the
 
-  * the sessionService.bind in the cooperating frontend server.
 
-  *
 
-  * @param  {String}   frontendId cooperating frontend server id
 
-  * @param  {Number}   sid        session id
 
-  * @param  {String}   uid        userstate id
 
-  * @param  {Function} cb         callback function
 
-  *
 
-  * @memberOf BackendSessionService
 
-  * @api private
 
-  */
 
- BackendSessionService.prototype.bind = function(frontendId, sid, uid, cb) {
 
-   var namespace = 'sys';
 
-   var service = 'sessionRemote';
 
-   var method = 'bind';
 
-   var args = [sid, uid];
 
-   rpcInvoke(this.app, frontendId, namespace, service, method, args, cb);
 
- };
 
- /**
 
-  * Unbind the session with the specified userstate id. It would finally invoke the
 
-  * the sessionService.unbind in the cooperating frontend server.
 
-  *
 
-  * @param  {String}   frontendId cooperating frontend server id
 
-  * @param  {Number}   sid        session id
 
-  * @param  {String}   uid        userstate id
 
-  * @param  {Function} cb         callback function
 
-  *
 
-  * @memberOf BackendSessionService
 
-  * @api private
 
-  */
 
- BackendSessionService.prototype.unbind = function(frontendId, sid, uid, cb) {
 
-   var namespace = 'sys';
 
-   var service = 'sessionRemote';
 
-   var method = 'unbind';
 
-   var args = [sid, uid];
 
-   rpcInvoke(this.app, frontendId, namespace, service, method, args, cb);
 
- };
 
- /**
 
-  * Push the specified customized change to the frontend internal session.
 
-  *
 
-  * @param  {String}   frontendId cooperating frontend server id
 
-  * @param  {Number}   sid        session id
 
-  * @param  {String}   key        key in session that should be push
 
-  * @param  {Object}   value      value in session, primitive js object
 
-  * @param  {Function} cb         callback function
 
-  *
 
-  * @memberOf BackendSessionService
 
-  * @api private
 
-  */
 
- BackendSessionService.prototype.push = function(frontendId, sid, key, value, cb) {
 
-   var namespace = 'sys';
 
-   var service = 'sessionRemote';
 
-   var method = 'push';
 
-   var args = [sid, key, value];
 
-   rpcInvoke(this.app, frontendId, namespace, service, method, args, cb);
 
- };
 
- /**
 
-  * Push all the customized changes to the frontend internal session.
 
-  *
 
-  * @param  {String}   frontendId cooperating frontend server id
 
-  * @param  {Number}   sid        session id
 
-  * @param  {Object}   settings   key/values in session that should be push
 
-  * @param  {Function} cb         callback function
 
-  *
 
-  * @memberOf BackendSessionService
 
-  * @api private
 
-  */
 
- BackendSessionService.prototype.pushAll = function(frontendId, sid, settings, cb) {
 
-   var namespace = 'sys';
 
-   var service = 'sessionRemote';
 
-   var method = 'pushAll';
 
-   var args = [sid, settings];
 
-   rpcInvoke(this.app, frontendId, namespace, service, method, args, cb);
 
- };
 
- var rpcInvoke = function(app, sid, namespace, service, method, args, cb) {
 
-   app.rpcInvoke(sid, {namespace: namespace, service: service, method: method, args: args}, cb);
 
- };
 
- /**
 
-  * BackendSession is the proxy for the frontend internal session passed to handlers and
 
-  * it helps to keep the key/value pairs for the server locally.
 
-  * Internal session locates in frontend server and should not be accessed directly.
 
-  *
 
-  * The mainly operation on backend session should be read and any changes happen in backend
 
-  * session is local and would be discarded in next request. You have to push the
 
-  * changes to the frontend manually if necessary. Any push would overwrite the last push
 
-  * of the same key silently and the changes would be saw in next request.
 
-  * And you have to make sure the transaction outside if you would push the session
 
-  * concurrently in different processes.
 
-  *
 
-  * See the api below for more details.
 
-  *
 
-  * @class
 
-  * @constructor
 
-  */
 
- var BackendSession = function(opts, service) {
 
-   for(var f in opts) {
 
-     this[f] = opts[f];
 
-   }
 
-   this.__sessionService__ = service;
 
- };
 
- /**
 
-  * Bind current session with the userstate id. It would push the uid to frontend
 
-  * server and bind  uid to the frontend internal session.
 
-  *
 
-  * @param  {Number|String}   uid userstate id
 
-  * @param  {Function} cb  callback function
 
-  *
 
-  * @memberOf BackendSession
 
-  */
 
- BackendSession.prototype.bind = function(uid, cb) {
 
-   var self = this;
 
-   this.__sessionService__.bind(this.frontendId, this.id, uid, function(err) {
 
-     if(!err) {
 
-       self.uid = uid;
 
-     }
 
-     utils.invokeCallback(cb, err);
 
-   });
 
- };
 
- /**
 
-  * Unbind current session with the userstate id. It would push the uid to frontend
 
-  * server and unbind uid from the frontend internal session.
 
-  *
 
-  * @param  {Number|String}   uid userstate id
 
-  * @param  {Function} cb  callback function
 
-  *
 
-  * @memberOf BackendSession
 
-  */
 
- BackendSession.prototype.unbind = function(uid, cb) {
 
-   var self = this;
 
-   this.__sessionService__.unbind(this.frontendId, this.id, uid, function(err) {
 
-     if(!err) {
 
-       self.uid = null;
 
-     }
 
-     utils.invokeCallback(cb, err);
 
-   });
 
- };
 
- /**
 
-  * Set the key/value into backend session.
 
-  *
 
-  * @param {String} key   key
 
-  * @param {Object} value value
 
-  */
 
- BackendSession.prototype.set = function(key, value) {
 
-   this.settings[key] = value;
 
- };
 
- /**
 
-  * Get the value from backend session by key.
 
-  *
 
-  * @param  {String} key key
 
-  * @return {Object}     value
 
-  */
 
- BackendSession.prototype.get = function(key) {
 
-   return this.settings[key];
 
- };
 
- /**
 
-  * Push the key/value in backend session to the front internal session.
 
-  *
 
-  * @param  {String}   key key
 
-  * @param  {Function} cb  callback function
 
-  */
 
- BackendSession.prototype.push = function(key, cb) {
 
-   this.__sessionService__.push(this.frontendId, this.id, key, this.get(key), cb);
 
- };
 
- /**
 
-  * Push all the key/values in backend session to the frontend internal session.
 
-  *
 
-  * @param  {Function} cb callback function
 
-  */
 
- BackendSession.prototype.pushAll = function(cb) {
 
-   this.__sessionService__.pushAll(this.frontendId, this.id, this.settings, cb);
 
- };
 
- /**
 
-  * Export the key/values for serialization.
 
-  *
 
-  * @api private
 
-  */
 
- BackendSession.prototype.export = function() {
 
-   var res = {};
 
-   EXPORTED_FIELDS.forEach(function(field) {
 
-     res[field] = this[field];
 
-   });
 
-   return res;
 
- };
 
- var BackendSessionCB = function(service, cb, err, sinfo) {
 
-   if(err) {
 
-     utils.invokeCallback(cb, err);
 
-     return;
 
-   }
 
-   if(!sinfo) {
 
-     utils.invokeCallback(cb);
 
-     return;
 
-   }
 
-   var sessions = [];
 
-   if(Array.isArray(sinfo)){
 
-       // #getByUid
 
-       for(var i = 0,k = sinfo.length;i<k;i++){
 
-           sessions.push(service.create(sinfo[i]));
 
-       }
 
-   }
 
-   else{
 
-       // #get
 
-       sessions = service.create(sinfo);
 
-   }
 
-   utils.invokeCallback(cb, null, sessions);
 
- };
 
 
  |