1. 程式人生 > >移動平臺遊戲網絡重連方案(轉)

移動平臺遊戲網絡重連方案(轉)

操作 三種 劃分 使用 遊戲服 class 排行 統計 3.4

 1、背景

  移動網絡信號波動頻繁,給移動遊戲開發者帶來諸多困擾,處理不好會造成較差的用戶體驗以及重復扣道具等嚴重問題。因此弱網絡問題在TDR技術評審中作為客戶端重點挑戰項,並且弱網絡專項測試達標後方能上線。本文就過往項目中遇到的問題給出一種比較通用解決方案。

  2、網絡連接方式

  通常遊戲客戶端都是通過創建socket與服務器取得連接,但也會根據使用場景劃分成兩種連接方式:TCP連接和HTTP連接。

  1) TCP連接即我們常說的長連接。這種連接方式下socket連接一旦建立,通信雙方即可相互發送數據,直到一方終止連接。目前公司的移動端聯網遊戲多采用這種數據通訊方式。

  2) HTTP連接即我們常說的短連接。這種連接采用的是“請求-響應”的通訊方式,每次交互由客戶端發起請求,服務器收到請求後才能回復數據,數據傳輸完成後,socket連接便斷開。在下載CDN資源或雲配置時通常會采用這種連接方式。


  3、網絡檢測

  3.1 檢測設備的網絡環境

  iOS和Android都提供了檢測本地網絡環境的方法,具備我們需要的功能:

  1) 網絡環境標識,區分當前網絡環境:WIFI/WWLAN/NOTREACHABLE等。

  2) 網絡切換感知,網絡環境切換後會收到系統消息。

  在蘋果開發者網站(developer.apple.com)上有一個reachability的例子,對底層網絡組件做了封裝,可實現此上的功能。Android上提供了Connectivity Manager服務,可加以封裝實現同樣的功能。附錄中提供了相關的開源代碼,並分別封裝了reachability在iOS和Android平臺上的實現。

  3.2 檢測心跳超時和回包超時

  心跳即每一定時間間隔(假定15秒)客戶端和服務器進行一次請求/應答,來判斷對方是否存活。若客戶端發送請求成功後,長久(假定60秒)未收到服務器的回應,則認為連接已經中斷或者服務器宕機。若服務器長久(假定300秒)未收到客戶端請求,則可以認為客戶端已經離線。另外常規的業務數據包也可以認為是心跳包的擴展,所以每次業務數據包通信成功,客戶端和服務器都要重新計時。一般心跳包是一個空的數據包,以節約流量,但通常也會包含少量字段,比如客戶端和服務器的時間同步信息等。

  一些關鍵協議,比如進入房間的請求,需要等待服務回應後才能扣除體力進入房間。但網絡不穩定時,可能客戶端的請求發送成功,服務器的回應卻遲遲沒有收到,這種情況下,客戶端需要做一個超時控制,比如15秒後客戶端還沒有收到回包,則給出提示,不能讓客戶端無限的等待。這種因果關聯的一對協議我們稱作請求-應答協議,建議所有關鍵協議都采用這種機制。有一點要註意,這種異步操作有一個等待的時間,一般這段時間都會屏蔽輸入(轉菊花/show activity indicator),避免用戶進行其他操作導致重復請求。這也要求我們在代碼邏輯層面上避免多個關鍵協議的嵌套和並發。

<ignore_js_op>技術分享



  3.3 檢測發包失敗

  一般來講reachability足夠靈敏可靠,設備網絡發生變化時能及時感知,只要監聽到狀態切換為NOTREACHABLE便可認為斷線了(需要排除瞬斷的情況),但reachability也有限制,無法感知到傳輸層連接斷開。舉個例子:手機和無線路由器連接正常,但是無線路由器和modem連接中斷,這時reachability是檢測不到網絡斷開的。此時需要依據socket錯誤碼來判斷網絡情況。

  3.4 檢測socket狀態

  以上幾種機制都是在應用層做網絡狀況檢測,基本上可以應對大部分情況,但有時為了更好的用戶體驗,我們需要更加精準的檢測方式。獲取socket底層錯誤碼及狀態能為我們提供更多的判斷依據。因實際項目中並未用到這方面的內容,便不在這裏擴展。

  3.5 檢測網絡延遲

  某些類型的遊戲對網絡延遲特別敏感(如實時對戰類遊戲),較高的網絡延遲將會導致慘不忍睹的體驗。這些類型的遊戲不但要從技術層面做優化,同時也要根據用戶當前的網絡延遲加以限制。比如平均延遲在1000ms以上便提示無法遊戲。我們可以采用兩種方式評估延遲:信號強度(received signal strength indication)和收發包時間統計。

  1) 信號強度(RSSI)檢測:這種判斷網絡延遲的方式不具客觀性,因為網絡延遲不僅取決於信號強度,同時受到帶寬、傳輸節點數、網絡硬件吞吐量等一系列因素的影響。但在其他參數相對固定的情況下,我們仍然可以參考信號強度來評判網絡狀況,同reachability類似,RSSI能及時給我們當前網絡狀態的反饋。在Android平臺上使用WifiManager類可以獲取具體RSSI值及信號強度等級。不幸的是iOS 5.0及以後的系統都不再支持RSSI的獲取(當然jailbreak之後還是可以的)。

  2) 收發包時間統計:即在客戶端和服務器時間同步的情況下,每個數據包帶一個時間戳信息,基於過往的數據包計算平均網絡延遲。這種檢測方式相對合理,但是時效性較差,在網絡波動頻繁時不能及時正確評估,相反在連接平穩的網絡環境中,會得到理想的效果。

  在Android平臺上要取得一個合理的網絡延遲,可以結合以上兩種方式。iOS平臺上暫時還只能采用第二種方式。

  4、斷線重連機制

  當檢測到斷線後,便可以啟動重連模式。根據當前的遊戲狀態確定重連策略,一般有以下三種方式:

  1) 靜默重連,即在用戶無感知的情況下進行重連。一般檢測到斷線後,可以先嘗試靜默重連一定次數(比如3次)。如果在遊戲對戰過程中斷線,一般也會盡量嘗試靜默重連並且忽略重連次數,因為此時彈出提示框會打斷對戰體驗的完整性。靜默重連提供了一種友好的用戶體驗,能應付一些短暫的網絡中斷(比如進出電梯或者進程從後臺喚醒等)。

  2) 顯式重連,在靜默重連一定次數(假定3次)之後,仍然無法連接成功的情況下,此時需要彈出提示框,中斷遊戲流程,告知用戶當前網絡環境較差,引導用戶在網絡較好時再嘗試連接。

  3) 服務器故障重連,這種情況下客戶端無論如何是連接不到遊戲服務器的。此時客戶端也需要給出正確的引導,而不是誤當作斷線故障處理。因此我們在斷線重連失敗之後多加一個步驟:嘗試連接CDN服務器,若CDN服務器可以正常連接,那麽說明網絡暢通,我們去獲取CDN上的雲配置,檢查是否有服務器日常維護的標識,如果有則給出服務器日常維護的公告,否則可以認為服務器宕機,則給出服務器故障的公告。此步驟中若CDN服務器也無法連接,說明網絡確實不暢通,可以繼續走重連流程或者等待。

  5、網絡協議的制定規範

  要做到良好的重連體驗,不僅需要良好的解決方案,也需要有協議上的支持。通常協議制定時可以參考以下規則:

  1) 登錄協議盡量簡單,僅包含必須的字段(如玩家等級,金錢,體力等)。一般重連即需要走重新登錄和鑒權流程,精簡的登錄協議能提高重連效率和節約流量。用戶的非關鍵校驗數據(比如背包數據,排行榜,卡牌信息)等可以延遲到界面開啟時再請求或者使用本地緩存數據。

  2) 協議的解耦,不同業務邏輯需要的請求包不同,這裏就需要進行協議解耦,減少冗余數據,降低傳輸的包量,提高單包發送成功率。

  3) 支持數據包壓縮,對於較大的協議包(比如排行榜數據,好友數據等)需要做針對性的壓縮,提高單包發送成功率。

  4) 關鍵協議需要添加序列號,避免客戶端重復請求造成的多次扣費等問題。

  6、CDN資源下載方案

  隨著硬件和技術的發展,移動遊戲品質也和PC端遊越來越接近,當然資源量也越來越接近。受限於移動網絡帶寬,較大的安裝包給玩家設置了較高的門檻,因此目前的手遊產品也越來越多的考慮微端方案。即安裝包只包含部分遊戲關卡,或者只作為一個下載器,而完整的遊戲資源放在CDN資源服務器上,然後按需下載,這也是一般頁遊的思路。這種情況下,我們對比了幾種打包機制給大家參考。

  <todo>測試數據稍後提供</todo>

  附錄1:斷線重連流程圖

<ignore_js_op>技術分享



  附錄2:RSSI信號強度分級

<ignore_js_op>技術分享

移動平臺遊戲網絡重連方案(轉)