- connect组件
要了解connector,上面一个类图,一个时序图就描述的很清楚了。
一切从Connector开始。
- Connector收到socket的connect消息后,通过cosessions组件去获取sessions,如果没有就创建一个session,并且session绑定socket的消息。这里也会让coConection组件统计用户信息。
- 把消息交给 coserver组件, 执行doHandler(). 全局前头过滤—>前头过滤---->Handler ---->后头过滤---->全局后头过滤。
- 处理完成之后。通过coPushScheduler组件 把消息回调给客户端,回调有两个模式,带buffer的和不带buffer的。最后通过
session.send —> socket.send 把消息发送给客户端。
源码阅读:
- 找到 pomelo/connectors下的sioconnector.js,里的
sio.on('connection', function(socket){
var siosocket = new SioSocket(curId++, socket);//连接了就new一个socket wapper
//test end
self.emit('connection', siosocket);//这是发送一个地方
siosocket.on('closing', function(reason) {//断开
siosocket.send({route: 'onKick', reason: reason});
});
});
这里是socket.io的绑定,其他socket也是类似。这里的sioSocket是对socket的一个包装。
2.找到找到 pomelo/components下的connector.js,里的
pro.afterStart = function(cb) {
console.error(".............component afterStart");
this.connector.start(cb);
this.connector.on('connection', hostFilter.bind(this, bindEvents));
};
这里如果有 'connenction 消息过来会执行 bindEvents。
bindEvents才是做事的人。
2.1 通过getsession去获取session,没有就创建一个,因为传入了socket,所以session会绑定socket。
2.2 这里socket绑定了 message, 如果有消息过来,就会执行handleMessage
// new message
socket.on('message', function(msg) {
var dmsg = msg;
if (self.useAsyncCoder) {
return handleMessageAsync(self, msg, session, socket);
}
if (self.decode) {
dmsg = self.decode(msg, session);
} else if (self.connector.decode) {
dmsg = self.connector.decode(msg, socket);
}
if (!dmsg) {
// discard invalid message
return;
}
// use rsa crypto
if (self.useCrypto) {
var verified = verifyMessage(self, session, dmsg);
if (!verified) {
logger.error('fail to verify the data received from client.');
return;
}
}
handleMessage(self, session, dmsg);//处理消息
}); //on message end
2.3. handleMessage主要是处理过滤的一些问题,这里我就详细写了,调试一下就好了。
只是回调的时候,如果请求的是前台服务器走 doHandle。如果请求的是后台服务器走doForward。
2.4 做完过滤和处理后,开始回调。
pro.doSend = function(reqId, route, emsg, recvs, opts, cb) {
if (!emsg) {
process.nextTick(function() {
return cb && cb(new Error('fail to send message for encode result is empty.'));
});
}
//实际发送
this.app.components.__pushScheduler__.schedule(reqId, route, emsg,
recvs, opts, cb);
}
这里回调时通过pushScheduler来控制回调的方式,是否带buff.
3. 转到/pomelo/pushSchedulers/direct.js
这里可以看到消息就直接发送了。
var doBatchPush = function(self, msg, recvs) {
var sessionService = self.app.get('sessionService');
for(var i=0, l=recvs.length; i<l; i++) {
sessionService.sendMessage(recvs[i], msg);//会话发送消息
}
};
pro.sendMessage =function(sid, msg) {
var session = this.sessions[sid];
if (!session) {
logger.debug('Fail to send message for non-existing session, sid: ' + sid + ' msg: ' + msg);
return false;
}
return send(this, session, msg);
}
var send = function (service, session, msg) {
session.send(msg);
return true;
};
Sro.send = function(msg) {
this.__socket__.send(msg);//最后还是socket发送出去了。
};
最后还是socket发送出去了。
这就是消息的大致过程。
欢迎大家加我QQ:2402063615,注明来意。