青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 311, comments - 0, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

上一篇分析客戶端登陸的過程。當用戶登陸成功后,聊天又是個什么過程呢?下面就來分析聊天時,客戶端與服務器端的交互過程。

客戶端

我們先來看看下,聊天發送消息的過程。當用戶在文本框內輸入文字,并回車就可以發送消息了

   1: $("#entry").keypress(function (e) {
   2:var route = "chat.chatHandler.send";
   3:var target = $("#usersList").val();
   4:if (e.keyCode != 13 /* Return */) return;
   5:var msg = $("#entry").attr("value").replace("\n", "");
   6:if (!util.isBlank(msg)) {
   7:             pomelo.request(route, {//route = "chat.chatHandler.send"
   8:                 rid: rid,
   9:                 content: msg,
  10:                 from: username,
  11:                 target: target
  12:             }, function (data) {
  13:                 $("#entry").attr("value", ""); // clear the entry field.
  14:if (target != '*' && target != username) {
  15:                     addMessage(username, target, msg);
  16:                     $("#chatHistory").show();
  17:                 }
  18:             });
  19:         }
  20:     });

#1:entry就是聊天文本框的id了,當焦點在entry(就用id來代表控件了),每次按下鍵盤都會觸發keypress()方法,方法接受一個事件e

#2:route,決定客戶端向服務器端的哪個方法發送請求。

#3:target,entry的上方有個名為users的下拉框,target就是下拉框的值了,決定用戶向誰發送消息。

#4-#5:對輸入的字符判斷,如果不是回車就返回,如果是回車就將entry中的換行符替換成空字符串

#6:util是client.js定義的一個對象,里面包含了一些對字符的處理方法,其中isBlank()是判斷字符串是否是空字符串

#7:如果不是空字符串,就將這條消息發送給服務器,route就是#2所定義的服務器的處理方法 chat.chatHandelr.send

#8-#11:客戶端將用戶所在的channel,發送的消息了,用戶名以及發送消息的對象封裝成對象,發送給服務器




#12:定義回調函數,處理服務器返回的結果對象data

#13:清空entry

#14:根據發送的對象判斷是否將發送的添加到聊天記錄中

#15:在聊天記錄(id=chatHistory)顯示

服務器端

接下來,在看服務器端收到客戶端發送的請求是怎么處理的。打開chatofpomelo\game-server\app\servers\chat\handler\chatHandler.js

找到handler.send

   1: handler.send = function(msg, session, next) {
   2:var rid = session.get('rid');
   3:var username = session.uid.split('*')[0];
   4:var channelService = this.app.get('channelService');
   5:var param = {
   6:         route: 'onChat',
   7:         msg: msg.content,
   8:         from: username,
   9:         target: msg.target
  10:     };
  11:     channel = channelService.getChannel(rid, false);
  12:
  13://the target is all users
  14:if(msg.target == '*') {
  15:         channel.pushMessage(param);
  16:     }
  17://the target is specific user
  18:else {
  19:var tuid = msg.target + '*' + rid;
  20:var tsid = channel.getMember(tuid)['sid'];
  21:         channelService.pushMessageByUids(param, [{
  22:             uid: tuid,
  23:             sid: tsid
  24:         }]);
  25:     }
  26:     next(null, {
  27:         route: msg.route
  28:     });
  29: };

#1:解釋下參數 msg就是客戶端發送的對象,session就是服務器端與當前用戶的會話,next相當于把結果發送給客戶端 PS:next的真正功能我也描述不清,還請各位指點。

#2-#3:從session中取得roomID(rid)和用戶名usernmae,chatofpomelo\game-server\app\servers\connector\handler\entryHandler.js的enter()方法有對于session的設置

#4:獲取ChannelService(管理Channel)

#5-#10:把發送的信息,用戶名和發送信息的對象以及route。這里的route:onChat由服務器端定義的,客戶端監聽。每個客戶端都會監聽onXXX事件,監聽服務器發送的消息。這樣用戶發送的消息才能由服務器發送給其他用戶。

#11:根據用戶發送的rid,獲取對應的channel

#14-#25:判斷發送對象,是廣播還是發送給特定用戶。

#26-28:將結果返回給客戶端

其實,分析這么多代碼,前面我寫的很詳細,后面就寫的簡略了。分析完后可以發現,其實交互部分情況類似,只要弄懂了其中一部分,其余的也就好懂了。

PS:到此,這個demo的雛形就完成了,本來到這結束了……確實,如果你的servers.json里只有一個chat服務器,那么一切流程都可正常運行。但是,如果不只一個chat服務器,那肯定會遇到問題的,是不是信息發不出去,在看服務器端,報錯了?。?/span>

是不是channel為undefined?看上面的第11行

   1: channel = channelService.getChannel(rid, false);

很抱歉,channelService里并沒有channel,你一定很奇怪,當用戶登錄時,不是創建了channel了嗎,怎么會沒有呢?

為了驗證,我把add和send時的app打印出來,對比

image

發現確實創建的channel沒有了,到底是怎么回事?

再比較,就會發現還有一個不同之處。

image

你會發現,登陸和聊天時所在的服務器不一樣,難怪channel消失。

其實,聊天和登陸一樣,用戶在發送消息時,看上面客戶端代碼的第8行和第10行,會發現客戶端不只會發送消息,還會把用戶名username和rid同時發送給服務器端。服務器端會根據username和rid,實際上只有rid,判斷該用戶是位于哪臺chat-server上,這就是為什么game-server/app.js會有這幾行代碼

   1: app.configure('production|development', function () {
   2:// route configures
   3:     app.route('chat', routeUtil.chat);//routes的chat屬性對應routeUtil.chat()方法 
   4:     app.filter(pomelo.timeout());
   5: });

#2:當服務器類型是chat,就會把路由到routeUtil.chat方法。

然后在進入該方法,看看是怎么判斷用戶屬于哪個路由器的。

   1: exp.chat = function(session, msg, app, cb) {
   2:  
   3:     console.log("uid = " + session.uid + " rid = " + session.get("rid"));
   4:var chatServers = app.getServersByType('chat');//根據類型 獲取服務器列表
   5:  
   6:if(!chatServers || chatServers.length === 0) {//如果服務器列表不存在或為空,則調用回調函數cb,將錯誤傳給該回調
   7:         cb(new Error('can not find chat servers.'));
   8:return;
   9:     }
  10:  
  11:var res = dispatcher.dispatch(session.get('rid'), chatServers);//通過rid獲得具體的chat服務器
  12:     console.log("chat服務器:" + res.id);
  13:     cb(null, res.id);
  14: };

#11:之前的代碼,相信大家都明白了。我們直接看11行代碼,是不是很眼熟?dispatcher好像見過!還記得之前客戶端連接gate服務器,然后由gate服務器分配connector服務器,再返回其host和clientPort嗎?不錯,這里同樣是調用該方法,只不過connectors改成了chatServers。這樣根據傳入的rid,就可判斷用戶當初登陸的那個chat-server,這樣也就能找到對應的channel

疑問:雖然解決了這一問題,但是還是不明白如果不添加對chat的路由,即沒有這行代碼:

   1: app.route('chat', routeUtil.chat);

是怎么分配chat-server,是隨機分配,還是自增分配?

還有就是這句代碼是何時被調用的。

希望各位能夠指點一下。

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            一本久久青青| 中文一区二区| 欧美日韩免费看| 久久精品盗摄| 久久av红桃一区二区小说| 香港成人在线视频| 欧美在线精品一区| 久久综合久久综合久久综合| 久久久久久电影| 美国三级日本三级久久99| 美国成人直播| 国产精品mv在线观看| 国产精品一区二区欧美| 国产手机视频一区二区| 在线免费观看成人网| 亚洲精品日日夜夜| 亚洲欧美日韩一区二区在线| 欧美伊人久久久久久午夜久久久久 | 久久成人免费视频| 老司机午夜精品视频| 亚洲大胆女人| 亚洲黄色尤物视频| 亚洲欧美电影在线观看| 久久夜色精品国产亚洲aⅴ| 欧美人与性动交cc0o| 国产日韩一区二区| 99re66热这里只有精品4| 欧美一区二区三区免费视频 | 亚洲日本激情| 亚洲自啪免费| 欧美成人网在线| 国产精品一区免费观看| 在线观看一区欧美| 亚洲欧美国产va在线影院| 麻豆精品在线视频| 一区二区三区色| 久久久国产精品亚洲一区 | 久久亚洲视频| 亚洲精品一区二区三区福利| 欧美少妇一区二区| 欧美激情在线免费观看| 国产一区91| 亚洲——在线| 亚洲狠狠丁香婷婷综合久久久| 亚洲午夜精品在线| 欧美国产精品| 在线成人免费视频| 久久免费少妇高潮久久精品99| 亚洲黄色片网站| 免费观看亚洲视频大全| 国内揄拍国内精品少妇国语| 性欧美大战久久久久久久免费观看| 欧美高清视频一区| 久久精品伊人| 极品av少妇一区二区| 亚洲欧美日本国产有色| 亚洲精品免费网站| 免播放器亚洲| 91久久香蕉国产日韩欧美9色| 久久国产视频网| 亚洲欧美日韩国产成人| 欧美视频在线免费看| 亚洲午夜羞羞片| 亚洲片国产一区一级在线观看| 久久最新视频| 最新亚洲一区| 亚洲狠狠丁香婷婷综合久久久| 久久夜色精品亚洲噜噜国产mv| 精品动漫av| 欧美大片一区| 欧美福利视频一区| 日韩亚洲成人av在线| 亚洲开发第一视频在线播放| 欧美日本高清视频| 亚洲先锋成人| 亚洲一区二区三区成人在线视频精品| 欧美国产日韩xxxxx| 一本色道久久综合亚洲精品婷婷| 亚洲日本欧美日韩高观看| 欧美激情综合色综合啪啪| 一本大道久久a久久精品综合 | 久久在线免费观看视频| 久久香蕉国产线看观看av| 91久久中文| 亚洲精品美女久久7777777| 国产精品成人一区二区三区夜夜夜 | 亚洲精品影院| 国产精品成人一区| 久久久久久久综合色一本| 久久久久久夜| 日韩一区二区精品在线观看| 亚洲视频图片小说| 欧美一区二区三区四区在线| 欧美一级午夜免费电影| 在线观看欧美亚洲| 亚洲免费观看| 国产午夜精品理论片a级大结局| 老司机成人在线视频| 欧美日韩国产一级| 久久精品国产2020观看福利| 久久亚洲私人国产精品va| 一区二区免费看| 欧美一区二区在线观看| 日韩视频免费看| 午夜在线a亚洲v天堂网2018| 亚洲日本欧美| 亚洲欧美视频在线观看| 亚洲国产精品黑人久久久| 亚洲天堂成人在线观看| 亚洲国产黄色| 午夜精品久久久久久久男人的天堂 | 欧美电影打屁股sp| 国产精品免费看| 欧美激情综合| 国产日韩欧美精品| 亚洲欧洲综合另类在线| 国产一区二区三区丝袜| 亚洲精品在线看| 一区二区三区我不卡| 一区二区三区欧美| 亚洲精品欧美精品| 欧美中文在线观看| 亚洲欧美日韩在线一区| 欧美黄在线观看| 裸体歌舞表演一区二区| 国产精品护士白丝一区av| 亚洲精品黄网在线观看| 亚洲第一精品在线| 欧美一区在线视频| 午夜精品999| 欧美亚一区二区| 亚洲日本理论电影| 亚洲日本无吗高清不卡| 欧美a级一区| 免费成人网www| 国产资源精品在线观看| 亚洲午夜羞羞片| 亚洲欧美视频在线观看视频| 欧美午夜理伦三级在线观看| 亚洲精品国产日韩| 日韩特黄影片| 欧美精品aa| 亚洲精品免费电影| 日韩性生活视频| 欧美视频一区二区三区…| 夜夜嗨av一区二区三区网页| 亚洲最新视频在线| 欧美色图五月天| 夜色激情一区二区| 亚洲欧美国产va在线影院| 国产精品日韩久久久久| 在线一区亚洲| 欧美在线观看www| 久久夜色精品国产噜噜av| 久久色在线播放| 麻豆国产精品一区二区三区| 精品电影一区| 欧美国内亚洲| 日韩一级网站| 欧美亚洲免费电影| 国产日韩欧美制服另类| 久久久久免费| 亚洲国产精品久久久久婷婷884 | 女人天堂亚洲aⅴ在线观看| 亚洲国产精品尤物yw在线观看 | 久久亚洲一区二区| 亚洲激情综合| 一区二区三区精品视频在线观看| 欧美视频三区在线播放| 香蕉免费一区二区三区在线观看| 久久久久九九九| 亚洲二区在线视频| 欧美色视频一区| 久久大综合网| 日韩视频在线观看免费| 午夜精品久久久久久久99水蜜桃| 国产亚洲欧美一区| 欧美精品v国产精品v日韩精品| 日韩亚洲成人av在线| 久久蜜臀精品av| 一区二区免费看| 国内成+人亚洲| 欧美日韩在线三区| 久久久国产精品亚洲一区| 99这里只有精品| 欧美+亚洲+精品+三区| 午夜精彩视频在线观看不卡| 在线不卡视频| 欧美性猛交视频| 久久亚洲午夜电影| 中文久久乱码一区二区| 欧美激情第8页| 欧美一区二区三区在线| 日韩香蕉视频| 亚洲第一久久影院| 黑人巨大精品欧美黑白配亚洲| 国产精品国产三级国产专区53| 欧美黄色日本| 免费观看成人www动漫视频| 香蕉久久一区二区不卡无毒影院|