游戲匹配和結(jié)算實現(xiàn)

匹配

匹配.png
//請求匹配
message CM_Match {
  int type; //匹配房間類型
  String name; //玩家名稱
  long targetPlayerId; //加入他人比賽傅蹂,目標(biāo)玩家id
}

//匹配成功
message L2RM_MatchSucc {
  int roomId;
  int roomType;
  boolean createRoomIfNotExist;  //場景中的第一個玩家為true
  RoomPlayerEnt ent;  //房間服需要的玩家信息
}

//業(yè)務(wù)服收到此消息創(chuàng)建房間
message R2LM_AddRoom {
  int id;
  int sign;  //房間簽名
  int type;
  Date createTime;
}

//業(yè)務(wù)服收到此消息励稳,在房間銷毀前(R2LM_RemoveRoom),玩家都可以斷線重連房間服
message R2LM_AddPlayer {
  long playerId;
  int roomId;
  int roomSign;
  int roomType;
  int token;   //登錄令牌犬金,斷線重連時下發(fā)給客戶端
}

//客戶端收到此消息后連接房間服
message SM_RoomServerPermission {
  String host;
  int port;
  String token;  //本次登錄的令牌
}

業(yè)務(wù)服房間管理

業(yè)務(wù)服維護(hù)了房間服的Room念恍。房間服創(chuàng)建Room,業(yè)務(wù)服創(chuàng)建對應(yīng)Room晚顷,房間服銷毀Room峰伙,業(yè)務(wù)服銷毀對應(yīng)Room。其變化通過處理房間服的R2LM_AddRoom该默,R2LM_RemoveRoom等消息完成瞳氓。
在匹配規(guī)則中另外維護(hù)了MatchRoom。匹配規(guī)則認(rèn)為需要創(chuàng)建一個新的房間時栓袖,則馬上創(chuàng)建MatchRoom匣摘,當(dāng)一個玩家被匹配到某個MatchRoom中,MatchRoom中立即添加該玩家裹刮。新增過程不依賴房間服的消息音榜。
Room的作用是用于統(tǒng)計房間服的信息,玩家的斷線重連捧弃。MatchRoom用于完成匹配邏輯赠叼。兩者的作用不同決定生命周期不同,Room的生命周期由房間服決定塔橡,MatchRoom在匹配時創(chuàng)建梅割,在人滿時銷毀霜第,在房間服的房間銷毀時也會銷毀葛家。

class Room {
  int id;
  int sign;
  RoomType type;
  Date createTime;
  int playerNum;  //玩家數(shù)量
  int watcherNum;  //觀戰(zhàn)者數(shù)量
  RoomServer server;  //所屬房間服
}
class MatchRoom {
  int id;
  List<Long> playerIds;
  RoomServer server;  //所屬房間服
}

進(jìn)入房間服

進(jìn)入房間服.png
message CM_EnterRoom {
  long playerId;
  String token; //登錄令牌
}

//業(yè)務(wù)服收到此消息,將玩家加入房間服玩家集合
message R2LM_PlayerEnterRoom {
  long playerId;
  int roomId;
  int roomType;
  int status;  //狀態(tài) 0.游戲 1.觀戰(zhàn)
}

//場景快照
message SM_SceneSnapshot {
}

離開房間服

離開房間服.png
//業(yè)務(wù)服收到此消息泌类,將玩家從房間服玩家集合中移除
message R2LM_PlayerLeaveRoom {
  long playerId;
  int roomId;
  String token; //登錄令牌相同才能移除玩家
}

玩家結(jié)算

玩家結(jié)算.png
//結(jié)算消息分成兩部分癞谒,第一部分在房間服計算底燎,比如排行榜
message SM_RoomResult {
  根據(jù)結(jié)算面板確定...
}

//通知客戶端斷開房間服連接,返回業(yè)務(wù)服
message SM_DisconnectRoomServer {
  連接業(yè)務(wù)服的信息...
}

//將結(jié)算內(nèi)容發(fā)到業(yè)務(wù)服弹砚,由業(yè)務(wù)服計算獎勵等數(shù)據(jù)
message R2LM_PlayerResult {
  
}

//業(yè)務(wù)服收到此消息双仍,清理玩家斷線重連的相關(guān)信息。
//房間服再次收到R2LM_AddPlayer消息才允許玩家登陸桌吃。
message R2LM_RemovePlayer {
  long playerId;
  String token; //登錄令牌相同才能移除玩家
}

房間結(jié)算

房間結(jié)算.png
//房間結(jié)算朱沃,包含了所有需要結(jié)算的玩家
message R2LM_RoomResult {
  
}

//業(yè)務(wù)服收到此消息,清理房間服
message R2LM_RemoveRemove {
  long playerId;
  String token; //登錄令牌相同才能移除玩家
}

房間結(jié)算時茅诱,所有玩家必須結(jié)算逗物。

房間服消息作用

房間服發(fā)給業(yè)務(wù)服的消息主要有6個

  • R2LM_AddRoom
  • R2LM_RemoveRoom
  • R2LM_AddPlayer
  • R2LM_RemovePlayer
  • R2LM_PlayerEnterRoom
  • R2LM_PlayerLeaveRoom

R2LM_AddRoom/R2LM_RemoveRoom用于維護(hù)業(yè)務(wù)服的房間的創(chuàng)建和銷毀。
R2LM_AddPlayer/R2LM_RemovePlayer主要用于維護(hù)玩家能否斷線重連房間服瑟俭。
R2LM_PlayerEnterRoom/R2LM_PlayerLeaveRoom用于維護(hù)哪些玩家在房間服翎卓,以及相關(guān)狀態(tài)的修改。
玩家離開房間服的行為會導(dǎo)致房間服發(fā)送R2LM_PlayerLeaveRoom給業(yè)務(wù)服摆寄,而玩家完成一局游戲才會導(dǎo)致房間服發(fā)送R2LM_RemovePlayer給業(yè)務(wù)服失暴。

房間服線程模型

每個房間綁定到線程池中的一個線程,房間的所有業(yè)務(wù)都單線程處理微饥。
房間支持消息隊列逗扒,可以向其投遞各種消息。玩家進(jìn)入房間欠橘,玩家離開房間缴阎,玩家結(jié)算,房間結(jié)算等任務(wù)简软,都在房間線程中處理蛮拔。
第一個玩家進(jìn)入房間時,啟動房間定時器痹升,并處理房間消息建炫。房間銷毀后停止定時器,不再處理房間消息疼蛾。

class Room {
  ConcurrentLinkedQueue<IRoomTask> taskQueue;
}

<b>問題:</b>
當(dāng)房間服收到L2RM_MatchSucc時肛跌,會創(chuàng)建新玩家,將玩家放入緩存察郁,如果緩存中已存在玩家衍慎,則需要銷毀已存在的玩家。銷毀玩家的任務(wù)需要投遞到房間線程中執(zhí)行皮钠,可能會發(fā)生執(zhí)行順序錯誤問題稳捆。

  • 代碼順序
Player oldPlayer = playerMap.put(playerId, player);
if(oldPlayer != null && oldPlayer.getScene() != null) {
    oldPlayer.getScene().removePlayerAsync(oldPlayer);
    ...
}
send R2LM_AddPlayer message
  • 執(zhí)行順序
thread 1: send R2LM_AddPlayer message
thread 2: send R2LM_RemovePlayer message  //removePlayer是異步執(zhí)行

<b>解決方法:</b>

并不糾正執(zhí)行順序,而是在R2LM_AddPlayer和R2LM_RemovePlayer消息中增加token字段麦轰。player和oldPlayer的玩家id相同乔夯,但是登錄token不同砖织。業(yè)務(wù)服通過對比token,可以知道本次R2LM_RemovePlayer是否有效末荐,如果在R2LM_RemovePlayer之前已經(jīng)收到了包含新的token的R2LM_AddPlayer消息侧纯,則忽略R2LM_RemovePlayer消息的處理。

由于執(zhí)行順序依然是異步的甲脏,在同一時間眶熬,房間服可能同時存在相同id的兩個Player。所以除了在全局維護(hù)Player集合块请,每個房間還維護(hù)了自己的Player集合聋涨,房間中需要獲取玩家通過內(nèi)部的Player集合獲取,不要通過全局的Player集合獲取负乡,因為獲取到的可能是新的Player牍白。

異常情況

L2RM_MatchSucc問題

1.玩家匹配到一個已經(jīng)銷毀的房間
解決方案
1.盡可能在房間銷毀前停止匹配,比如持續(xù)12分鐘的房間抖棘,可以在最后30s停止匹配茂腥。
2.提示錯誤。玩家手動重新匹配切省。

CM_EnterRoom問題

1.玩家不存在最岗,或登錄令牌錯誤
解決方案:報錯。
2.房間不存在
解決方案:報錯朝捆,重連業(yè)務(wù)服般渡。
3.投遞消息時房間存在,(在房間線程)執(zhí)行消息時房間不存在
解決方案:報錯芙盘,重連業(yè)務(wù)服驯用。

只匹配,但不登錄房間服的玩家如何清理

定時30分鐘檢查儒老,Player關(guān)聯(lián)的房間銷毀則清理Player蝴乔。

沒有啟動定時器的房間如何銷毀

定時30分鐘檢查,30分鐘都沒有玩家進(jìn)入則銷毀房間驮樊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末薇正,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子囚衔,更是在濱河造成了極大的恐慌挖腰,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件练湿,死亡現(xiàn)場離奇詭異猴仑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)鞠鲜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門宁脊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來断国,“玉大人贤姆,你說我怎么就攤上這事榆苞。” “怎么了霞捡?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵坐漏,是天一觀的道長。 經(jīng)常有香客問我碧信,道長赊琳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任砰碴,我火速辦了婚禮躏筏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘呈枉。我一直安慰自己趁尼,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布猖辫。 她就那樣靜靜地躺著酥泞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪啃憎。 梳的紋絲不亂的頭發(fā)上芝囤,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機(jī)與錄音辛萍,去河邊找鬼悯姊。 笑死,一個胖子當(dāng)著我的面吹牛贩毕,可吹牛的內(nèi)容都是我干的挠轴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼耳幢,長吁一口氣:“原來是場噩夢啊……” “哼岸晦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起睛藻,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤启上,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后店印,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冈在,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年按摘,在試婚紗的時候發(fā)現(xiàn)自己被綠了包券。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纫谅。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖溅固,靈堂內(nèi)的尸體忽然破棺而出付秕,到底是詐尸還是另有隱情,我是刑警寧澤侍郭,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布询吴,位于F島的核電站,受9級特大地震影響亮元,放射性物質(zhì)發(fā)生泄漏猛计。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一爆捞、第九天 我趴在偏房一處隱蔽的房頂上張望奉瘤。 院中可真熱鬧,春花似錦煮甥、人聲如沸盗温。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肌访。三九已至,卻和暖如春艇劫,著一層夾襖步出監(jiān)牢的瞬間吼驶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工店煞, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留蟹演,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓顷蟀,卻偏偏與公主長得像酒请,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子鸣个,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 單區(qū)單服 游戲采用單區(qū)單服模式羞反,職能上分成業(yè)務(wù)服和房間服。第一個版本的設(shè)計囤萤,業(yè)務(wù)服為單點服務(wù)器昼窗,房間服可以無限拓展...
    瘋狂豬寶寶閱讀 3,681評論 3 7
  • 在開發(fā)球球游戲的過程中费尽,為了解決事先沒有考慮到的問題逃默,最終的實現(xiàn)和設(shè)計有所出入匣沼。其中有一部分是關(guān)于防御式編程的心得...
    瘋狂豬寶寶閱讀 492評論 0 3
  • 126.析構(gòu)器 在一個類實例銷毀前,一個析構(gòu)器會立即調(diào)用壮虫。使用deinit 關(guān)鍵字來表示析構(gòu)器, 跟構(gòu)造器寫法類似...
    無灃閱讀 798評論 0 4
  • 我之夜曲思路 因為電影《鋼琴家》朱监,更加知道了肖邦饭豹,又因為孩子學(xué)琴我開始系統(tǒng)留意鋼琴曲子,肖邦在鋼琴音樂中的至...
    城邊書室閱讀 2,095評論 1 5
  • 1毕贼、穿壽衣 我叫李一兩温赔,從小就沒有娘,聽說我娘是在生我的時候帅刀,難產(chǎn)走了让腹,墳就埋在我們家后面远剩。懂事之后扣溺,逢年過節(jié)我都...
    Smile_39ca閱讀 2,293評論 0 2