pomelo源码分析(8)--session
来源:互联网 发布:电气专用画图软件 编辑:程序博客网 时间:2024/06/10 07:45
作者:shihuaping0918@163.com,转载请注明作者
pomelo中有session/frontendSession/backendSession/sessionService。名字看起来都有点像,这一篇准备讲session和sessionService。session是对用户连接的一个抽象,它会调用sessionService。sessionService是session的具体实现底层。session只在frontend服务器中存在。如果还有印象的话,应该能记得gate负责接受外部连接,做frontend的负载均衡,将连接分派到不同的frontend上。connector再做路由处理,转到不同的backend服务器上,也就是逻辑服务器。
在分析session.js前要先分析sessionService.js,因为session实际是抽象了sessionService。从底向上更容易理解。
sessionService.js,先看一下Session的定义,Session中有一个id,uid,还有一个frontendId,还有一个socket。id就是sid,uid就是用户id,socket就是连接对应的socket。ftontendId就是frontend服务器id。sid和uid分别是从哪里来的呢?
/** * Session maintains the relationship between client connection and user information. * There is a session associated with each client connection. And it should bind to a * user id after the client passes the identification. * * Session is created in frontend server and should not be accessed in handler. * There is a proxy class called BackendSession in backend servers and FrontendSession * in frontend servers. */var Session = function(sid, frontendId, socket, service) { EventEmitter.call(this); this.id = sid; // r this.frontendId = frontendId; // r this.uid = null; // r 注意这里,uid初始是null this.settings = {}; // private this.__socket__ = socket; this.__sessionService__ = service; this.__state__ = ST_INITED;};
sid实际上是socket创建时指定的一个id。sid = socket.id;
,它是在connector中生成的,对于sioconnector,有这样一段代码。
var curId = 1; sio.on('connection', function (socket) { var siosocket = new SioSocket(curId++, socket); //curId++就是sid self.emit('connection', siosocket); siosocket.on('closing', function(reason) { siosocket.send({route: 'onKick', reason: reason}); }); });
所以这个sid是connector内部维护的,在服务生命周期内自增的一个ID。uid这这个时候是null,没有赋值的。
connector.js
session.on('bind', function(uid) { logger.debug('session on [%s] bind with uid: %s', self.app.serverId, uid); // update connection statistics if necessary if (self.connection) { self.connection.addLoginedUser(uid, { loginTime: Date.now(), uid: uid, address: socket.remoteAddress.ip + ':' + socket.remoteAddress.port }); } self.app.event.emit(events.BIND_SESSION, session); });
connectorService.js
Session.prototype.bind = function(uid) { this.uid = uid; this.emit('bind', uid);};
uid是在bind事件发生时出现的。这个bind被调用的时候,把uid给赋进去了。注意是sessionService里的Session.on(‘bind’…)。pomelo把这个session的名字复用了太多次。有点混乱。
为了避免概念上的混乱,下面总结一下,先说明一下session是指对客户端连接的一个抽象,它里面包含uid,sid,socket,以后出现session这单个单词,就是指连接的抽象。pomelo核心中有一个session component,这个session component是对sessionService的抽象。sessionService位于service下,实现session管理的具体工作。session的具体结构是在sessionService中出现的,叫Session。很绕啊,这就是名字取得不好的弊端。
下面再来看一下session component和sessionService之间是什么样的关系。
var SessionService = require('../common/service/sessionService');module.exports = function(app, opts) { var cmp = new Component(app, opts); app.set('sessionService', cmp, true); return cmp;};/** * Session component. Manage sessions. * * @param {Object} app current application context * @param {Object} opts attach parameters */var Component = function(app, opts) { opts = opts || {}; this.app = app; this.service = new SessionService(opts); //创建sessionService //这段话结尾有个(),代表函数调用 var getFun = function(m) { return (function() { return function() { return self.service[m].apply(self.service, arguments); //arguments是随调用变化的 }; })(); }; // proxy the service methods except the lifecycle interfaces of component var method, self = this; for(var m in this.service) { //遍历sessionService的成员 if(m !== 'start' && m !== 'stop') { //如果不是start和stop方法 method = this.service[m]; //取出成员 if(typeof method === 'function') { //如果成员是函数 this[m] = getFun(m); //把函数加到自己模块里 } } }};Component.prototype.name = '__session__';
根据上面的分析,session component实际上是对sessionService做了一层代理。把sessionService的函数都加载到sesssion component里来了。这个代理的实现,下一篇文章会专门去讲它。
- pomelo源码分析(8)--session
- pomelo源码分析(一)
- pomelo源码分析(二)
- pomelo源码分析(三)
- pomelo源码分析(四)
- pomelo源码分析(五)
- pomelo源码分析(六)
- pomelo之session与sessionService分析
- pomelo之session与sessionService分析
- 【Pomelo源码分析】2016-09-20 入门(pomelo命令)
- Pomelo聊天室源码分析(一)
- Pomelo中session创建和connection连接过程分析
- 【Pomelo源码分析】2016-09-21 程序入口(app.js, pomelo.js, application.js)
- pomelo源码分析(4)--connector之网络监听
- pomelo源码分析(5)--node.js中的this
- pomelo源码分析(6)--connector协议处理message
- pomelo源码分析(7)--connector与其它组件交互
- pomelo 源码结构
- Android进程生命周期(Process LifeCycle)
- uva572(DFS 油田)
- 重装系统时遇到的"setup was unable to create a new system partition"错误
- python+selenium自动化软件测试(第4章):场景判断与封装
- PAT[1006]换个格式输出整数
- pomelo源码分析(8)--session
- 友盟第三方分享QQ分享不走回调方法或者显示取消分享的问题
- Kafka 基本原理
- C++中变量的初始化
- springboot统一异常处理
- Tomcat Server.xml详解
- Servlet实现网页重定向
- Spring笔记5-基于配置文件的方式配置AOP
- Python学习笔记 3