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

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>
            性欧美大战久久久久久久免费观看| 亚洲精品久久视频| 欧美freesex交免费视频| 欧美激情中文字幕一区二区| 亚洲三级免费| 国产精品久久999| 久久福利视频导航| 亚洲福利免费| 亚洲欧美一区二区三区在线| 激情一区二区| 欧美久久久久久蜜桃| 亚洲欧美日韩精品久久久久| 欧美激情aaaa| 香蕉久久国产| 亚洲片区在线| 国产日韩亚洲欧美| 欧美激情第一页xxx| 欧美亚洲视频在线看网址| 亚洲国产精品一区制服丝袜| 欧美国产精品| 久久综合国产精品台湾中文娱乐网| 亚洲国产婷婷香蕉久久久久久| 亚洲欧美电影在线观看| 亚洲高清自拍| 国产乱码精品一区二区三区av | 精品99视频| 久久国产精品久久国产精品| 美日韩精品视频| 中文一区在线| 久久亚洲精品视频| 亚洲欧美激情四射在线日| 欧美aa在线视频| 欧美一区二区视频网站| 91久久精品一区| 国产日韩欧美一二三区| 浪潮色综合久久天堂| 亚洲欧美成人在线| 欧美国产在线电影| 久久久久久一区| 一区二区三区蜜桃网| 国产精品欧美风情| 欧美精品亚洲| 亚洲欧美日韩人成在线播放| 日韩午夜在线| 久久夜色精品国产噜噜av| 午夜精品久久久久久99热| 亚洲黄色av| 一区二区三区在线免费观看| 国产精品magnet| 亚洲国产欧美一区二区三区丁香婷| 欧美一区免费| 在线免费观看日本一区| 国内成+人亚洲+欧美+综合在线| 欧美日韩国产精品自在自线| 久久久久久高潮国产精品视| 亚洲网站啪啪| 一本色道久久精品| 亚洲福利免费| 欧美激情一区二区三区| 久久久精品午夜少妇| 久久精品国产第一区二区三区最新章节| 日韩亚洲欧美精品| 日韩一二三区视频| 亚洲第一天堂av| 国自产拍偷拍福利精品免费一| 国产精品久久久久久久久婷婷 | 久久久亚洲一区| 亚洲香蕉网站| 日韩午夜电影| 亚洲国产一区在线观看| 亚洲人成欧美中文字幕| 激情综合在线| 在线观看日韩| 国产一区在线免费观看| 狠狠色丁香久久婷婷综合_中| 国产精品免费网站在线观看| 国产伦精品免费视频 | 久久久精品五月天| 久久久久久久一区二区| 久久国产日韩| 久久综合久久久| 久久久人成影片一区二区三区观看| 久久久xxx| 久久久亚洲一区| 亚洲视频一区二区免费在线观看| 亚洲中字黄色| 国内一区二区三区| 亚洲黄色成人| 国产精品日韩久久久久| 老司机成人网| 欧美精品久久久久a| 欧美激情精品久久久| 欧美午夜宅男影院| 国产精品男女猛烈高潮激情 | 免费欧美在线视频| 女主播福利一区| 欧美日韩视频专区在线播放| 欧美日韩在线影院| 国产精品一区二区你懂的| 国产午夜精品一区理论片飘花| 在线精品视频在线观看高清| 亚洲电影毛片| 亚洲视频观看| 欧美在线视频在线播放完整版免费观看| 久久久久亚洲综合| 欧美激情a∨在线视频播放| 中国女人久久久| 欧美中文字幕第一页| 亚洲欧美日韩电影| 美女视频网站黄色亚洲| 亚洲电影第1页| 亚洲一区欧美| 久久久精品性| 国产精品chinese| 国产又爽又黄的激情精品视频| 亚洲欧洲久久| 亚洲一区二区黄色| 免费日韩av片| 亚洲精品网站在线播放gif| 欧美一区二区在线播放| 免费视频最近日韩| 国产日本欧美视频| 亚洲电影在线看| 香蕉久久夜色精品| 欧美**人妖| 亚洲男人的天堂在线aⅴ视频| 久久激情视频久久| 欧美三级韩国三级日本三斤| 国产亚洲美州欧州综合国| 日韩视频在线一区| 亚洲男人的天堂在线观看| 欧美不卡在线| 亚洲视频在线观看免费| 欧美大片免费观看| 国产人久久人人人人爽| 在线一区二区三区做爰视频网站| 久久久久国产精品www| 一区二区高清| 久久国产精品99国产精| 亚洲国产精品日韩| 午夜精品久久久久久久久久久久久| 欧美激情麻豆| 国产一区二区电影在线观看| 亚洲午夜国产成人av电影男同| 老司机成人网| 午夜精品一区二区三区在线| 欧美精品一区二区三区一线天视频| 精品av久久707| 午夜视频在线观看一区二区三区 | 亚洲综合国产精品| 欧美成人免费网站| 在线观看久久av| 欧美一区二区三区免费在线看| aa国产精品| 久热re这里精品视频在线6| 国产一区二区三区在线观看免费视频 | 欧美片网站免费| 亚洲电影有码| 久久精品人人做人人爽| 亚洲欧美区自拍先锋| 欧美激情aaaa| 欧美精品成人91久久久久久久| 欧美三级特黄| 亚洲精品国精品久久99热一| 欧美a级一区| 欧美一区在线直播| 国产一区二区看久久| 亚洲欧美成人网| 亚洲视频一区二区免费在线观看| 欧美成人免费网站| 亚洲毛片av在线| 美女视频一区免费观看| 久久天天躁夜夜躁狠狠躁2022| 国产精品一区亚洲| 欧美专区亚洲专区| 亚洲视频在线播放| 国产美女扒开尿口久久久| 亚洲欧美综合一区| 亚洲免费伊人电影在线观看av| 欧美日韩在线观看视频| 亚洲图片你懂的| 亚洲理论在线观看| 欧美精品v国产精品v日韩精品| 亚洲高清网站| 亚洲日本va在线观看| 欧美国产日韩一区二区在线观看 | 国产日本欧美在线观看| 欧美一区二区三区精品| 久久国产成人| 国产亚洲一区精品| 女人色偷偷aa久久天堂| 麻豆精品一区二区av白丝在线| 亚洲精选在线观看| 亚洲国产婷婷综合在线精品| 欧美色精品天天在线观看视频 | 欧美小视频在线| 欧美一区高清| 久久www成人_看片免费不卡| 亚洲青色在线| 亚洲三级电影全部在线观看高清|