pomelo0.5.5源码分析(2)-通信
一、客户端与服务器的通信
客户端的通信在pomelo-client里封装了。
服务器与客户端的通信在connector里。底层提供websocket、tcp和socket.io三种方式的通信。
(一)connector组件(components/connector.js)
组件构造函数里会this.connector从opts里取connector,或者默认为connectors/sioconnector.js。(connector的实现sioconnector和hybridconnector)
组件的start里会将this.server\this.session\this.connection分别映射到app的对应的组件上。
组件的afterStart里this.connector.start,并监听this.connector的'connection'事件。
'connection'事件处理为:
将connection关联一个session,监听socket的message事件,接受到message时decode message,再将message交给server组件的handle,处理完回调里再将返回信息在connector组件的send里处理。
另外监听session的'bind'事件,处理函数为,调用connection.addLoginedUser。
组件里的send,encode reponse的message,然后交给schedule组件的schedule。
(二)hybridconnector的实现
connectors/hybridconnector.js以及connectors/hybird。hyrbird实现了原生socket和websocket两种。
hybridconnector.start里会this.tcpServer=net.createServer,然后把以这个tcpServer为参数创建一个switcher。之后在switcher的'connection'事件里将tcpsocket装进hybridsocket。
(1)hybrid/switcher.js
switcher构造函数接受一个server参数,并创建this.wsprocessor和this.tcpprocessor。
switcher监听参数server的'connection'事件,事件处理函数里监听原生socket的'data'事件,判断data是否有http头,如果有,则调用wsprocessor.add,这个add会向外emit 'connection'(事件参数为原生socket),并向socket emit 'data'事件;否则非http,则调用tcpprocessor.add,这个add会以刚才的原生socket为参数创建一个tcpsocket,同时向tcpprocessor emit 'connection'(事件参数为原生tcpsocket)、向这个原生socket emit 'data'事件。
switcher也监听了this.wsprocessor和this.tcpprocessor的'connection'事件,处理为向switcher自己emit 'connection'。总结,switcher的职责,将socket的字节流data拼成包,以'message'事件向外emit一个个的完成包msg。
刚才提到的tcpsocket.js这里处理原生socket的操作。监听了原生socket的'data'、'end'、'error'、'close'事件。例如在'data'处理时,当读入的流长度够一个包的body后就向tcpsocket emit 'message'。
(2)hybridsocket.js
将socket和websocket封装为统一接口。构造函数里接受一个id和socket参数。
hybridsocket监听tcpsocket的'message'事件,将msg decode,之后处理。例如Package.TYPE_DATA类型的msg,就将这个msg再向hybridsocket自己emit一个'message'事件,其他可能是'handshake'或'heartbeat'事件。
(三)server组件
官方描述如下“模块使服务器具备处理客户端请求的能力。该模块主要实现了filter服务,根据当前服务器类型,加载对应handler/目录下的代码,并决定一个请求应该是在当前服务器处理还是应该路由给其他服务器处理。”,下面看看代码流程。
组件的start里初始化filter和handler。
二、服务器之间的通信
三、框架调用
四、session
(一)session组件(components/session.js)
session组件直接用的common/service/sessionService。
(二)sessionService
(1)Session(object)
Session里维护的socket和user信息的之间的对应关系。每个socket有个对应的Session,验证用户身份后就将他们绑定。
Session构造函数接受参数socket id\frontendId\socket\service。
Session通过bind\unbind函数将uid绑到this.uid里,并emit 'bind'\'unbind'事件。
Session的set\get函数来给Session设取值,由this.settings维护。
Session的send\sendBatch都是直接通过构造时传入的那个socket来操作。
(2)MockLocalSession(object)
(3)SessionService(object)
负责对Session的管理。构造函数里将this.sessions和this.uidMap初始为空表。
SessionService的create负责new Session,并放到this.sessions里。
bind\unbind函数负责将传入的sid\uid对应绑定到this.sessions\this.uidMap里。uidMap里每个元素是个数组,所以每个uid可以对应多个session?(这个以后再具体了解下)
sendMessage\sendMessageByUid根据sid\uid往对应的session或sessions发消息。
其他函数不一一列举了。
(三)session的使用
看了下chatofpomelo里,是在connector/handler/entryHandler.js里的enter函数,直接用了session.bind。简单用法就是在自己项目的验证uid后自己绑定。
五、pomelo-rpc
(一)rpc-client
client.create\mailstation.create\mailstation.mailboxFactory挂载mailbox\
client.start(callback)\mailstation.start&callback
client.addProxies(remote-calls)\proxy.create\
(二)rpc-server
lib/rpc-server/server将远程调用处理下,加到opts.services里,然后通过gateway来listen端口和处理message。