初入遊戲整理

2022-08-21 03:00:13 字數 2238 閱讀 1227

遊戲開發與我之前的網際網路開發最大不同就是協議資料傳送介面呼叫。在**開發和維護中,一般很少直接呼叫到通訊協議傳送的相關介面。我們可以利用spring restful介面直接進行業務的開發。

因此在開發中,容易疑惑乙個問題。tcp/ip到底可靠麼?這是聽了老大講的充值例子所疑惑的問題。

充值案例討論

手遊開發,我們經常會遇到乙個問題。那就是網路波動巨大。例如,玩家在進電梯前點了乙個遊戲幣下單按鈕(假設沒有訂單號,客戶端沒做處理)。這個訂單會首先傳送到閘道器,分配到對應的伺服器進行處理。處理完訂單後,將資料更新給客戶端。但是玩家此時進入電梯了。網路中斷,他沒更新到資訊。於是老哥開始狂點。接下來會發生什麼事呢?是的,玩家一次性訂購了多批遊戲幣。這是非常嚴重的遊戲資產問題。

這裡很簡單了解到tcp/ip是可靠的。它做到三個很重要的事情

確保了丟失的資料重發。儘管你在電梯裡網路斷絕,但是只要你出電梯,恢復了網路,那麼tcp就會重新傳送訊息。儘管這導致了玩家一次性下了多個訂單。

消除重複。這裡的重複是ip訊息的重複,而不是訂單的重複。

資料報被重新組裝成它們被傳送的順序。

但是上面問題還有個版本,假設進電梯前,客戶端已經傳送出去了訊息。伺服器已經接收到了資訊,訂單已經下了,也回覆了客戶端。但玩家這個時候進入了電梯,網路已經中斷了。客戶端無法確認自己的訊息是否被服務端接受了。客戶端在電梯期間數次重發不成功後,它放棄這條協議。但是經理要求客戶端會自動重發充值資訊(業績啊)。於是客戶端再次傳送了訊息。這裡,玩家在不知情的情況下,他被重複下單了。

第二個版本tcp似乎又是不可靠的了。它不會確保你的訊息必達。同時,客戶端不知道自己的訊息到底被服務端接受了沒。如果接受了,那麼它就安心等待服務端更新資料就好了。

tcp到底可靠麼

拜占庭將軍問題(byzantine failures),是由萊斯利·蘭伯特提出的點對點通訊中的基本問題。含義是在存在訊息丟失的不可靠通道上試圖通過訊息傳遞的方式達到一致性是不可能的。因此對一致性的研究一般假設通道是可靠的,或不存在本問題。
這裡的一致性就是指a端傳送訊息m到b端後,b端收到後,傳送回確認m1的情況下,端a知道端b已經收到了訊息,端b知道端a已經收到了確認m1。基於通道的不可信,我們知道這永遠不可能實現。因為每乙個確認也需要端去回覆。如上面例子中,m1是針對m的確認。為告訴b端a端收到了確認,a端需要傳送給b端訊息m2。m2是針對m1的確認。假設在一系列訊息m,m1,m2 ... mn後,系統達到了一致。其中後乙個訊息是前乙個訊息的確認。但因為通道的不穩定,我們永遠無法確認最後乙個訊息的必達。因此,永遠無法確認最後第二個訊息是否已達。以此類推,無法證明訊息m已達。違反了假設。

上述反證證明了,在通道不穩定的情況下,無法重複(每次派出信使只有乙個且他也不回來了)的雙端通訊無法使雙發達到一致性。對此,tcp/ip協議第乙個解決方案——超時重傳。通道不穩定也就意味著訊息必達是有一定概率的,那麼tcp/ip協議最多只要重發訊息足夠的次數就可以確信自己可以收到乙個來自接受方確認。到這裡,單端的通訊就完成。傳送方傳送了訊息,並確定了接收方一定接受了訊息,無論接收方到底是接受了1個還是複數個相同的訊息。接收方會自己完成去重。同時,傳送方為了避免陷入將軍問題中的無窮確認,不會對接收方發來的確認進行確認。傳送方不在乎接收方是否知道傳送方已經收到了確認。

上面的過程中,傳送方對接收方的單端通訊已經完成。如果接收方需要知道傳送方是否收到了確認,它只需要按照同樣的過程傳送乙個詢問是否收到了確認的訊息就可以了。至此,我們在通道不穩定的情況下,通過分解為兩個單端通訊和多次超時重傳完成兩端訊息的互通。實際中,這可能會更加複雜。例如,這裡的重發不會是無限次,達到一定次數,tcp協議會停止重發,並拋棄相關報文。

tcp就是基於以上的機制成立的。這也是為什麼tcp三次握手的原因。端a傳送給端b syn報文,端b回應 ack報文。端a如果收到了ack報文說明a到b的單端通訊構建成功。端b傳送給端a syn報文,端a回應 ack報文。端b如果收到了ack報文說明b到a的單端通訊構建成功。只不過在通訊剛開始階段,雙發沒有任何需要傳送的資料,因此可以合併端b發給端a的ack報文和syn報文。四次揮手是因為雙方無法確認對面資料是否傳送完畢,無法合併中間的兩個報文。

至此,我們知道tcp是不可靠的。

結語以上,我們可以得到兩個開發教訓

應用級別的確認是必要的。網路硬體問題永遠是無法**的。僅僅依靠tcp協議,必定有部分報文傳送失敗。如果沒對這些報文進行應用級別的確認和重發,這些報文相關的訊息可能會永遠丟失。

網路介面需要確保冪等。即便多次傳送協議,也要確保它不會對系統的一致性造成傷害。例如,上面的充值訂單可以加乙個訂單id,防止乙個訂單多次確認。客戶端在訂單確認期間加以限制。服務端不允許短時間內,玩家多次下單,例如1秒內10單絕對有問題。

2011初入遊戲之道

2011年時是我正式步入遊戲開發行業的第一年,也是我飛速成長的一年。有煩惱 有痛苦,有憂傷 有打擊.自然也少不了後面的,有收穫 有快樂 有喜悅.既然是從工作技術方面引來的話題,也是我最重要的話題,那就從這裡開始說 感謝我在開過過程中遇到難道,為我制定迷津的,形象我做事風格的人。此人就是himi,相信...

2011初入遊戲之道

2011年時是我正式步入遊戲開發行業的第一年,也是我飛速成長的一年。有煩惱 有痛苦,有憂傷 有打擊.自然也少不了後面的,有收穫 有快樂 有喜悅.既然是從工作技術方面引來的話題,也是我最重要的話題,那就從這裡開始說 感謝我在開過過程中遇到難道,為我制定迷津的,形象我做事風格的人。此人就是himi,相信...

初入藍色之路

剛進入公司的前兩天基本沒有事情做,大家只是圍坐在一起,互相了解,聊聊天,還有乙個上一屆的實習生,叫王法,這個名字挺有意思的,不知道還以為是個律師。這個人雖然只是個本科生,年齡也沒有我大,不過給人的感覺挺成熟的,在公司裡已經游刃有餘了。他給我們講了許多公司的事,有了這麼乙個和我們年齡相仿,交流沒有任何...