第一部分
先介紹三種協議,分別是TCP、UDP、HTTP。
TCP是可靠的傳輸層協議,但是其端到端的連接比較耗服務器資源,而且一旦丟包就會重發,阻塞住后續的數據包,因而可能會產生一個較大的瞬時延遲。其中“長連接”指的是tcp socket,tcp socket是操作系統為tcp協議的實現(說白了就是操作系統為tcp提供的api)。據說魔獸世界據說是用TCP。可能因為魔獸世界的游戲設計能很好的隱藏延遲,TCP用起來更簡單些。
UDP 是“不可靠”的,不會丟包重傳,會導致ip分片從而丟包,數據包不會按序送達,只保證到達的包數據是完整的,它的好處就是,不會產生tcp丟包時的隊列阻塞,數據報頭較小,只有8個字節,是一個無連接協議。
HTTP:因為http不需要持續地保持連接,是一個無狀態的連接(可以通過cookie來實現客戶端狀態的驗證),不會產生tcp所產生的斷線重連的問題,服務器也不需要維護過多的連接。缺點就是需要經常的進行tcp握手操作(不會影響玩家體驗),而且由於http的無狀態性,通常游戲數據需要實時保存,不過現在的內存數據庫 nosql的興起和計算機性能的提升,這塊劣勢已經不存在,而且越來越多的游戲都采用實時數據保存,防止游戲服務器宕機數據回檔的風險。再一個就是服務器無法主動向客戶端推送數據,導致在某些功能上會無法實現。由於http的無狀態性,需要做心跳處理,基於http的游戲服務器可以橫向擴展(每一個游戲服務器進程就是一個單純的邏輯計算器),數據庫架構設計的好的話,一個游戲服很容易實現1億+的玩家同服的情況。(該段部分摘自https://www.zhihu.com/question/39849641/answer/83774680)
第二部分
對於網絡游戲尤其是動作類游戲,采用純TCP協議是不符合業務要求的,但是采用其他協議如UDP就涉及到丟包問題。這里介紹幾種網絡游戲使用的協議方式以及一些針對丟包的方法。
1、UDP+TCP
如用戶登錄類業務采用TCP,而玩家動作操作上傳等使用UDP協議。
關於丟包檢查,可以采用一個近似TCP的ack機制,可以給每個數據包都添加一個sequence ID,然后發送端就依次發送數據包,接收端收到數據包后就可以根據sequence ID來判斷是否有丟包了。seqid肯定是唯一,並且是遞增的。
接收端處理先發包后到的情況,比如seqid在前的包比seqid在后的包晚到,這種情況就屬於亂序了,收到一個包時,和上一個確認收到的包比對一下seqid,如果不連續說明這個包是亂序的。此時就可以根據需求,或者實現超時重傳,或者直接跳過,因為有的同步消息不需要可靠的連接,比如位置同步信息偶爾丟一兩個也沒問題。網絡路徑的動態變化導致肯定會出現亂序的情況出現,因為我讓:消息id的編號是連續遞增的,而且每個消息包的序列號是唯一的,如:0、1、2、3、4,所以一旦有亂序,接收端可以察覺到(收到了0、1、3,你能知道 2 沒有收到)。
如何應對亂序,取決與你的游戲設計以及你的同步策略設計。如果不要求絕對精准(能夠replay重放的級別),那么直接使用id最新的包插值即可(不管2,直接處理3,2收到以后根據需求緩存或者丟棄)。但是如果你的同步要求非常嚴格,當你收到了3時,2還沒有收到,你的客戶端只好等2收到了再做同步,客戶端的狀態就會卡在1上,或者你的游戲邏輯允許根據1的狀態預測插值。
總之亂序是網絡的特性,如果你的游戲對同步的精度要求不高,你可以忽略它,如果要求精度很高(客戶端精確的還原狀態)你是不能忽略它的。
關於同步的體驗,有一種思路大體是這樣,你可以強制讓客戶端比服務端延遲個100~200毫秒,這個概念類似視頻的緩沖,如果你看一個高清視頻但是網絡不夠好經常卡,暫停等一下,讓緩沖條多走一截,再播放就能得到流暢的體驗。游戲也是一樣的,你讓客戶端的update比服務器遲150ms,但是網絡收包還是正常執行,那么,只要不出現150ms以上的延遲,同步就始終是精准而流暢的。
2、reliable udp(如UDT、KCP)
Reliable UDP(可靠的UDP)是一套服務品質的增強,比如擁擠控制調整,數據重傳,薄化服務器算法等,這些增強可以提高服務器在數據包丟失和網絡擁擠的條件下向RTP客戶表現品質良好的RTP流的能力。Reliable UDP’的擁擠控制機制使系統在沒有影響協議的實時本質的情況下,在行為上具備TCP協議的友好方式。
為了在英特網上處理好TCP網絡流量,Reliable UDP使用數據重傳和擁擠控制算法,與TCP協議采取的算法類似。另外,這些算法是經過時間考驗的,可以很好地利用現有帶寬。
Relibable UDP包括如下特性:
- 客戶端對服務器發出的數據包進行回應
- 對窗口緩沖和擁擠進行控制,使服務器不超過當前可用的帶寬。
- 發生丟包時,服務器向客戶重新發送數據
- 比實時流更快的緩沖機制,稱為“overbuffering”
客戶端是否使用Reliable UDP取決於客戶端發出的RTSP((Real-TimeStream Protocol )是一種基於文本的應用層協議) SETUP請求中的內容。
下圖顯示的是Reliable UDP應答包的格式。
3、http+udp
這種相對保守一些,邏輯相關的使用http協議,保證游戲邏輯不會出通訊上的問題,推送類的使用udp,比如聊天,世界公告等等。如果實時性要求非常高的戰斗功能,請使用udp。