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);
- };
|