服务器匹配原理,王者荣耀实现原理学习笔记
原作來自騰訊游戲?qū)W院
以下是原文部分節(jié)選
一、服務(wù)器架構(gòu)
“房間模式”
房間類玩法和MMORPG有很大不同:
1.廣播單元的不確定性
2.廣播數(shù)量很小
3.需要匹配一臺房間服務(wù)器讓少數(shù)人進入同一個服務(wù)器
這一類游戲最重要的是其“游戲大廳”的承載量,每個“游戲房間”受邏輯所限,需要維持和廣播的玩家數(shù)據(jù)是有限的,但“游戲大廳”需要維持相當高的在線用戶數(shù),所以仍然需要“分服”。
大廳:“自動匹配”玩家進入一個“游戲房間”,這需要對所有在線玩家做搜索和過濾,以及為了更好的體驗,會對玩家分地區(qū)匹配,以方便獲得更快速的同步。
大體流程:
登錄------>大廳服務(wù)器------>選擇組隊游戲功能------>服務(wù)器通知參與的所有客戶端------>新開一條連接------>連接到房間服務(wù)器------>用戶在房間服務(wù)器里進行交互
二、通信方式
1.http:每次通信完成以后都會斷開(這種方式對于需要頻繁交互的雙方來說效率太低)
2.socket:適用于實時性要求較高的游戲
(socket通信有TCP和UDP兩種,其區(qū)別如下,王者榮耀采用的是UDP)
為什么采用UDP?
(1)tcp保證數(shù)據(jù)可靠是有代價的
TCP發(fā)送一個包,等待一段時間,直到檢測到數(shù)據(jù)包丟失,如果沒有接收到它的ACK(Acknowledgement——確認字符,表示發(fā)來的數(shù)據(jù)已準確無誤地接收),接下來就會重新發(fā)送丟失的數(shù)據(jù)包到目標計算機。重復的數(shù)據(jù)包將被丟棄在接收端,亂序的數(shù)據(jù)包將被重新排序。以此來保證包的可靠性和有序性。TCP:無論什么情況,只要數(shù)據(jù)包出錯,就必須等待數(shù)據(jù)包重發(fā),即使最新的數(shù)據(jù)已經(jīng)到達,但還是不能訪問這些數(shù)據(jù)包,新的數(shù)據(jù)會被放在一個隊列中,需要等待丟失的包重新發(fā)送過來之后,所有數(shù)據(jù)沒有丟失才可以訪問。(當出現(xiàn)一個數(shù)據(jù)包丟失的情況,所有事情都需要停下來等待這個數(shù)據(jù)包重發(fā),客戶端會出現(xiàn)等待接收數(shù)據(jù)、操作出現(xiàn)卡頓和響應(yīng)不及時的現(xiàn)象。)
(2)udp的可靠性 —— 手動DIY組裝
UDP不能保證包的順序,比如第100個收到的數(shù)據(jù)包不一定是第100個發(fā)出的數(shù)據(jù)包,同時也無法保證不丟包,期間有一個包丟失,udp是不會去校驗的。
解決UDP可靠性的關(guān)鍵:順序、丟包
大體解決思路:
一、為每個數(shù)據(jù)包增加序列號,每發(fā)一次包,增加本地序列號。
二、每個數(shù)據(jù)包增加一段位域,用來容納多個確認字符。確認字符的數(shù)目由應(yīng)用發(fā)包速率來決定,速率越高,確認字符的數(shù)量也相應(yīng)越多。
三、每次收到包,把收到的包上的序列號變?yōu)榇_認字符,發(fā)送包的時候帶上這些確認字符。
四、如果從確認字符里面發(fā)現(xiàn)某個數(shù)據(jù)包有丟失,把它留給應(yīng)用程序來編寫一個包含丟失數(shù)據(jù)的新的數(shù)據(jù)包,必要的話,這個包還會用一個新的序列號發(fā)送。
五、多次收到同一包的時候可以放棄它。
三、同步方案
狀態(tài)同步:采用c/s架構(gòu),所有狀態(tài)由服務(wù)器來控制,安全性比較高,但流量比較大。(大型MMORPG)
幀同步:采用囚徒模式,所有客戶端強制采用一個邏輯幀率,從而保證輸出一致,其特點是流量小,安全性較差。
1.幀率
2.Lockstep ----- 幀同步
將一個游戲看成一個巨大的狀態(tài)機,所有參與者都采用同一個邏輯幀率來不斷向前推進
A B C 分別表示三個玩家的時間軸,這個時間軸不是電腦上的本地時間,而是A、B、C聯(lián)機時定義的一個時間軸。
虛線分割出來的時間片稱為“turn”,可以理解成一“幀”。箭頭表示玩家將自己的操作指令廣播給其他玩家。
一盤游戲可以看成一個大型的狀態(tài)機,因為是同一個游戲,因此初始狀態(tài)S0和幀率F是相同的。在第1個“turn”結(jié)束時,所有玩家都接收到完全一樣的輸入 I(I指的是當前游戲中所有玩家的操作指令集);由于幀率 F 和?S0 以及 I 是固定的,所以在 t1 時刻每個玩家電腦上計算出的下一個狀態(tài) S1 一定是相同的。
由上面可以知道:
1.游戲的過程就是每一個“turn”不斷向前推進的過程,每一個玩家的“turn”推進速度一致。(這里的“turn”借鑒了“幀”的概念,與游戲的渲染幀率不是同一個概念)
2.每一幀只有當服務(wù)器集齊了所有玩家的操作指令,也就是輸入I確定了之后才可以進行計算,進入下一個“turn”,否則就要等待最慢的玩家。所有玩家的操作指令收集齊后再廣播給所有的玩家,如此才能保證幀同步。
3.LockStep的游戲是嚴格“turn”向前推進的,如果有人延遲比較高,其他玩家必須等待該玩家跟上之后再繼續(xù)計算,不存在某個玩家領(lǐng)先或者落后其他玩家若干個“turn”的情況。使用LockStep同步機制的游戲中,每個玩家的延遲都等于延遲最高的那個人的延遲。
4.由于大家的“turn”一致,以及輸入固定,所以每一個“turn”各個客戶端的計算結(jié)果都是一致的。
具體執(zhí)行流程:
這種囚徒模式的幀同步,在第2個“turn”的時候,因為玩家1有延遲,而導致第二幀的同步時間發(fā)生延遲,從而導致所有玩家都在等待,出現(xiàn)卡頓現(xiàn)象。
四、樂觀鎖和斷線重連
上面說到囚徒模式的幀同步有一個致命的缺陷:若聯(lián)網(wǎng)玩家有一個網(wǎng)速慢了,勢必影響其他玩家的游戲體驗,因為服務(wù)器要等待所有玩家的輸入到達后再同步到各個客戶端。另外如果中途有人掉線了,游戲就會無法繼續(xù)或者掉線玩家無法重連,因為在嚴格的幀同步的情況下,中途加入游戲從技術(shù)上來講是非常困難的。因為你重新進來之后,你的初始狀態(tài)和大家不一致,而且你的狀態(tài)信息都是丟失狀態(tài)的,比如你的等級,隨機種子,角色的屬性信息等。(王者榮耀服務(wù)器會保存當場游戲的游戲指令以及狀態(tài)信息)
嚴格的幀同步,是要等到所有玩家都輸入之后,再去通知廣播客戶端更新,但如果服務(wù)器一直沒有輸入同步過來,大家是要等著的,那么如何解決這個問題?
方法:采用“定時不等待”的樂觀方式在每次Interval時鐘發(fā)生時將固定操作廣播給所有用戶,不依賴具體每個玩家是否有操作更新。如此幀率的時鐘由服務(wù)器控制,當客戶端有操作的時候及時地發(fā)送到服務(wù)器,然后服務(wù)端每秒鐘20-50次向所有客戶端發(fā)更新消息。
服務(wù)器不會等到收集完所有用戶的輸入后進行下一幀,而是按照固定頻率來同步玩家的輸入信息到客戶端,如果有玩家網(wǎng)絡(luò)延遲,服務(wù)器的幀步進是不會等待的。
通俗理解:網(wǎng)絡(luò)延遲,指令“遲到”,服務(wù)器幫你發(fā)送了個空白指令或預設(shè)指令。
五、技能同步
“偽隨機”
N臺電腦采用相同的隨機種子,第N次隨機的結(jié)果是一致的。
游戲開始前,服務(wù)器為每個玩家分配一個隨機種子,同步給各個客戶端,如此每個客戶端在計算每個角色的技能時,能保證傷害一致。
幀同步的兩種實現(xiàn)形式:
1.服務(wù)器要求接收到每一個客戶端的幀執(zhí)行完成消息時才發(fā)送執(zhí)行下一幀的命令(等待每個人)
2.服務(wù)器如同一個節(jié)拍器,只關(guān)心發(fā)送時機,不會等待。如果有個客戶端沒有趕上某一幀的操作收集,那就當他是沒有操作處理了。(收作業(yè)的時候不交就當你沒交了2333333)
MOBA類的幀同步:服務(wù)器只是負責一個通知作用,并不會管哪個客戶端卡了還是出狀況等問題。如果是狀態(tài)同步的話服務(wù)器負責計算結(jié)果,客戶端負責展現(xiàn)。
如何判斷掛機?
服務(wù)器在規(guī)定時間內(nèi)沒有收到玩家的操作指令。(有些情況是判斷攻擊指令以防止泉水掛機的現(xiàn)象)
總結(jié)
以上是生活随笔為你收集整理的服务器匹配原理,王者荣耀实现原理学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 股票语音播报软件 炒股语音实时播报
- 下一篇: 高数_关于e两个重要的积分公式