(搬運工)Pomelo官方demo ChatofPomelo簡析之一——用戶登錄
Posted on 2013-11-07 18:30 點點滴滴 閱讀(4307) 評論(0) 編輯 收藏 引用 所屬分類: 02 編程語言-
connector:frontend前端服務(wù)器,承載連接,并把請求轉(zhuǎn)發(fā)到后端的服務(wù)器群
-
gate:客戶端線連接gate服務(wù)器,然后再由gate決定客戶端和哪個connector連接
-
chat:backend后端服務(wù)器,真正處理業(yè)務(wù)邏輯的地方
一、登陸
1: $("#login").click(function () {
2: username = $("#loginUser").attr("value");
3: rid = $('#channelList').val();//Channel的ID
4:
5: if (username.length > 20 || username.length == 0 || rid.length > 20 || rid.length == 0) {
6: showError(LENGTH_ERROR);
7: return false;
8: }
9:
10: if (!reg.test(username) || !reg.test(rid)) {
11: showError(NAME_ERROR);
12: return false;
13: }
14:
15://query entry of connection
16: queryEntry(username, function (host, port) {//host,post是gate服務(wù)器分配給該客戶端的connector服務(wù)器的host和clientPort
17: pomelo.init({//pomeloclient.js中的init()方法
18: host: host,
19: port: port,
20: log: true
21: }, function () {//根據(jù)返回的connector服務(wù)器的host和port,連接connector
22: var route = "connector.entryHandler.enter";
23: pomelo.request(route, {//向connector的服務(wù)器發(fā)送username和channel(roomid = rid)
24: username: username,
25: rid: rid
26: }, function (data) {//data是connector返回給客戶端的數(shù)據(jù)(對象),是同一channel的用戶列表
27: if (data.error) {
28: showError(DUPLICATE_ERROR);
29: return;
30: }
31: setName();
32: setRoom();
33: showChat();
34: initUserList(data);
35: });
36: });
37: });
38: });
1:function queryEntry(uid, callback) {
2:var route = 'gate.gateHandler.queryEntry';
3: pomelo.init({//連接game服務(wù)器
4: host: window.location.hostname,
5: port: 3014, <!--servers.json下的gate的中clientPort為3014-->
6: log: true
7: }, function () {
8: pomelo.request(route, {
9: uid: uid
10: }, function (data) {//data是gate服務(wù)器返回給客戶端的數(shù)據(jù)(對象)
11: pomelo.disconnect();//斷開gate服務(wù)器,連接connector服務(wù)器
12: if (data.code === 500) {
13: showError(LOGIN_ERROR);
14: return;
15: }
16: callback(data.host, data.port);//調(diào)用回調(diào)函數(shù) 并將data數(shù)據(jù)傳給回調(diào)方法
17: });
18: });
19: };
1: handler.queryEntry = function(msg, session, next) {
2: var uid = msg.uid;
3: if(!uid) {//uid為空 說明用戶不存在
4: next(null, {
5: code: 500
6: });
7: return;
8: }
9:// get all connectors 獲取所有的connector
10:var connectors = this.app.getServersByType('connector');
11:if(!connectors || connectors.length === 0) {
12: next(null, {
13: code: 500
14: });
15: return;
16: }
17:// select connector
18:var res = dispatcher.dispatch(uid, connectors);//根據(jù)算法 返回一個服務(wù)器
19: next(null, {
20: code: 200,
21: host: res.host,
22: port: res.clientPort
23: });//將該服務(wù)器的host和客戶端端口clientPort返回給客戶端
24: };
1: var crc = require('crc');
2:
3: module.exports.dispatch = function(uid, connectors) {
4: var index = Math.abs(crc.crc32(uid)) % connectors.length;
5: return connectors[index];
6: };
1: handler.enter = function(msg, session, next) {
2: var self = this;
3: var rid = msg.rid;
4: var uid = msg.username + '*' + rid
5: var sessionService = self.app.get('sessionService');
6:
7://duplicate log in 如果session中已經(jīng)存在sessionService 說明已登陸
8: if( !! sessionService.getByUid(uid)) {
9: next(null, {
10: code: 500,
11: error: true
12: });
13: return;
14: }
15:
16: session.bind(uid);//將uid(username*rid)綁定到當(dāng)前的session
17: session.set('rid', rid);//session.settings[rid] = rid;
18: session.push('rid', function(err) {
19:if(err) {
20: console.error('set rid for session service failed! error is : %j', err.stack);
21: }
22: });
23: session.on('closed', onUserLeave.bind(null, self.app));//監(jiān)聽“close”事件 調(diào)用onUserLeave()
24:
25://put user into channel
26: self.app.rpc.chat.chatRemote.add(session, uid, self.app.get('serverId'), rid, true, function(users){
27: next(null, {//得到的user是同一channel的用戶列表(數(shù)組),將這用戶列表傳給客戶端
28: users:users
29: });
30: });
31: };
1:ChatRemote.prototype.add = function(uid, sid, name, flag, cb) {
2:var channel = this.channelService.getChannel(name, flag);
3:var username = uid.split('*')[0];
4:var param = {
5: route: 'onAdd',
6: user: username
7: };
8: channel.pushMessage(param);//Push message to all the members in the channel
9:
10:if( !! channel) {
11: channel.add(uid, sid);
12:}
13:
14:cb(this.get(name, flag));//this.get()返回(name,flag)標(biāo)記的Channel的用戶
15: }
1: ChatRemote.prototype.get = function(name, flag) {
2:var users = [];
3:var channel = this.channelService.getChannel(name, flag);
4:if( !! channel) {
5: users = channel.getMembers();
6:}
7:for(var i = 0; i < users.length; i++) {
8: users[i] = users[i].split('*')[0];
9: }
10:return users;
11: };
-
客戶端連接gate服務(wù)器,gate返回給客戶端connector的port和clientPort
-
客戶端連接connector服務(wù)器,connector將新登錄的用戶添加到channel里,通知channel里的所用用戶,并返回該channel的所有用戶名
-
客戶端根據(jù)得到的用戶名,更新界面