手機客戶端弱網路下的斷線重連處理
網路條件異常
在弱網路情況下,網路會顯式的丟擲一些異常,大部分情況下是NetworkException,少部分情況是Timeout(當然還有連線關閉等等其他異常,就不一一贅述)。在這種顯式丟擲異常的情況下,就說明網路已經無法順利的和伺服器進行連線,在這些訊息型別中,對於客戶端斷網或網路波動導致的原因,客戶端這邊就會觸發斷線重連流程。
2 心跳包觸發以及觸發時間的確定
上一種情況的觸發條件是客戶端手機本身斷網或網路發生異常的情況的觸發,但實際情況中,還有可能發生客戶端網路並未斷開,也並沒有異常丟擲,但是卻出現客戶端和伺服器無法正常進行收發訊息的情況。
這種情況一方面原因是中間鏈路的連線異常,另一方面也會由於延遲過高或丟包導致的TCP重發造成的延遲過大,影響到伺服器和客戶端之間正常的收發訊息。
在 市區低速移動的網路的模擬測試中,我們收集到的最大心跳包延遲是10s左右,也就是說,在此“弱”網路情況下,網路延遲峰值大概有10s以上。因此,我們對心跳包在一定時間內如果沒有收到返回包的情況下也認為是一種掉線情況,會觸發斷線重連處理,目前在大廳設定的觸發時間是30s,戰鬥中觸發的時間是20s。
遊戲切出
有一種情況是由於客戶端切出遊戲,或者中間接到電話等導致遊戲暫停等情況,在一定時間後伺服器會主動斷開和客戶端的連線,客戶端也需要主動觸發重連。
3、斷線重連的大致流程圖
斷線重連收到網路異常訊息階段處理流程:
斷線重連結果處理階段:
4、對流程圖的補充說明
1)在重連過程中,如果收到客戶端主動斷開的訊息,會遮蔽所有重連行為
2)由於在收到NetworkException的時候無法保證網路狀態,如果此時網路已經連線上,會無法觸發後續重連過程,所以會在NetworkException的時候double check一下是否連線到網路。
5、關於狀態機:
斷線重連並不是一個瞬間操作,而是一個過程。在整個斷線重連的過程中,存在著一個個階段,也就對應一個個的狀態。初步來說,主要分為以下幾個階段。
A. Start:網路正常狀態,簡稱S
B. Wait:網路已經斷開,等待網路恢復,簡稱W
C. Reconnect:重新連線狀態,簡稱R
D. End: 重新連線失敗,簡稱E
狀態轉換圖見下:
6、重連後的相關處理
在程式斷線重連的過程中除非重連失敗,否則最理想的情況是希望玩家在斷線前後無感知,可以流暢的繼續遊戲而不受到斷線的影響。
1) 對於大廳的後續處理
A.拉取相關屬性和物品。再重新連線後,由於在斷開過程中可能會有相關資料的變化,會拉取人物相關屬性和物品
B.重發斷線前的相關請求:這個和具體的系統相關,如果斷線前的系統進行的是一些對資料敏感的操作,比如合成物品,購買物品等,在發起的時候會做無法二次點選的處理並加入到重發列表中,在網路恢復之後重發。此時如果伺服器未做處理便會直接處理,如果做了處理需要伺服器忽略(注,這個需要伺服器配合)
2)對於戰鬥的後續處理
A.重新拉取戰鬥狀態資料:這個是由於我們遊戲是對戰鬥實時性要求較高的遊戲,所以在斷線過程中的戰鬥狀態可能會發生很大的改變,這些改變必須需要重新同步,比如可能會死亡,球變大或變小,位置改變等都有可能,所以在重連之後,我們是全量拉取玩家戰鬥資料,同步到最新的狀態。
7、對重連的一些說明
1)在戰鬥過程中,其實還伴隨這大廳這個連線,所以很多情況下,戰鬥連線的斷開也會伴隨著大廳連線的同時斷開。對此,我們對於不同連線建立不同的重連器,從而達到兩個連線相互獨立,無論只是單個連線的斷開還是兩者同時斷開,都不會相互影響,各自走各自的重連過程。
8、對之前版本遊戲更加容易掉線的一些思考
雖然其實很多時候確實是wifi不穩定導致的網路問題,但之前版本確實比其他遊戲更容易掉線,具體體現在在同一個網路下,兩個差不多的手機,玩我們遊戲的時候掉線的頻率更高,對此以下是我的一些想法。
對於網路經常觸發異常的原因,除了網路本身的不穩定外,主要還是TCP協議中,客戶端緩衝區在網路不穩定的時候容易寫滿導致的問題。
對於這個問題,一方面可以適當的擴大緩衝區的大小,對此把客戶端網路的緩衝區擴大,從1024*100,擴大到1024*2000,也確實改善了遊戲的網路狀況。
但這種方式只是並沒有從本質上解決這個問題,網路其實的壓力還是很大,流量過大也是我們遇到的問題之一。
由於包頭和TCP持續計時器的原因,在每個包的包頭都會有一些不屬於遊戲協議內容的造成的流量,對於一些能夠合併到一起傳送的小包,合併小包和減少包量可以很大幅度的減少流量。而且也容易避免由於滑動視窗可傳送部分的迅速充滿導致的網路擁塞。
另一方面,單個包的大小過大也會迅速的撐大緩衝區,而且在傳輸過程中造成傳輸峰值,造成網路延遲,拆分過大的包,比如一瞬間全量拉取排行榜等的資料通過分批拉取,減緩網路壓力,也能達到優化網路的目的。
9、對於為什麼會有wait狀態
其實對於一般的想法來說,其實斷線重連只需要Start,Reconnect,End三種狀態,確實,這三種狀態可以把整個斷線重連的過程完成,對於wait,主要一下幾個原因。
1.Wait 狀態和Reconnect狀態的區別在於Wait狀態手機網路並沒有連線,而Reconnect狀態的網路已經恢復了,這個其實是有差別的,可以對網路的狀態進行不同的處理。
2.因為由於一些原因(比如在wait狀態可能由於Apollo錯誤原因而無法收到網路恢復的訊息等)我們也低頻嘗試了重新和伺服器建立連線,但是其目的是發現是否能夠建立連線,更多的時候會返回失敗的訊息,是一種double check 的保證策略,而Reconnect狀態下的重連是我們知道了網路已經恢復,嘗試去連線伺服器,目的是為了真正的建立連線,這兩種情況無論在目的上還是在連線的頻率上都有差別,而且將兩個狀態區分便於我們在不同狀態下做不同處理。
相關推薦
手機客戶端弱網路下的斷線重連處理
1、弱網路下的斷線重連 玩家在遊戲過程中,所處的網路環境是複雜多變的,可能是wifi的網路不穩定,或處在3G甚至2G的環境下等。在這些情況下,網路遊戲會由於網路或包量等原因而出現延遲,拉拽,甚至掉線等問題。對於這些問題,一方面要對程式的包量和通訊進行優化,從根本上減緩
斷線重連處理
繼承 RtpFeedback #ifndef CHANNEL_RTPFEEDBACKIMPL_H #define CHANNEL_RTPFEEDBACKIMPL_H #include "rtp_rtcp_defines.h" #include "xx\defines.
使用netty進行客戶端網路程式設計及斷線重連功能實現
不管做哪個方向開發,都會有那麼一兩個牛B閃閃的庫,可以極大的方便開發,比如java網路程式設計中的netty庫。無論客戶端還是服務端網路程式設計,netty基本都是首選網路庫,健壯、高效、穩定,並且已經得到很多商業專案驗證。 當用netty進行客
WebSocket在服務端和客戶端通訊demo,支援心跳檢測+斷線重連
一、為什麼需要 WebSocket? 初次接觸 WebSocket 的人,都會問同樣的問題:我們已經有了 HTTP 協議,為什麼還需要另一個協議?它能帶來什麼好處? 答案很簡單,因為 HTTP 協議有一個缺陷:通訊只能由客戶端發起。 舉例來說,我們想了解今天的天氣,只能是客戶端向伺服器發出
Windows C語言 Socket程式設計 client端(客戶端)--斷線重連版
瞭解了最基礎的C語言客戶端的編寫流程,稍稍加以改動即可實現斷線重連。 當伺服器掉線時,客戶端會以固定的頻率不停的重連。 #include <stdio.h> #include <winsock2.h> #pragma comme
Apache mina 入門(四) —— 客戶端長連線方式實現斷線重連監聽
通過前面 Apache Mina 入門 (二)—— 非同步通訊機制 我們可以實現一個長連線的客戶端。但會發現一個問題,就是當網路、伺服器、應用程式出現問題而導致連線斷開後,我們的客戶端不能自動重連伺服器。導致客戶端程式癱瘓,不能使用。這個時候,通過增加一
mina作為客戶端斷線重連
定義:這裡討論的Mina 斷線重連是指使用mina作為客戶端軟體,連線其他提供Socket通訊服務的伺服器端。Socket伺服器可以是Mina提供的伺服器,也可以是C++提供的伺服器。 一、斷線重連的方式; 1. 在建立Mina客戶端時增加一個
即時通訊判斷網路狀態和斷線重連機制
本文借鑑csdn大神way的xmpp客戶端學習改造而來,不足之處希望大家多多指教! 1. 由於近半年來一直寫針對於tigase伺服器的即時通訊軟體的開發,框架的重構,對即時通訊的理解也較之前更進一步,在客戶端的IM開發中,最重要的除去通訊的建立,就是保持網路環境不斷更換時
nodejs中mysql斷線重連
調試 狀態 pan var 參考 ble prot nec clas 之前寫了個小程序Node News,用到了MySQL數據庫,在本地測試均沒神馬問題。放上服務器運行一段時間後,偶然發現打開頁面的時候頁面一直處於等待狀態,直到Nginx返回超時錯誤。於是上服務器檢查了遍,
android 實現mqtt訊息推送,以及不停斷線重連的問題解決
前段時間專案用到mqtt的訊息推送,整理一下程式碼,程式碼的原型是網上找的,具體哪個地址已經忘記了。 程式碼的實現是新建了一個MyMqttService,全部功能都在裡面實現,包括連伺服器,斷線重連,訂閱訊息,處理訊息,釋出訊息等基本操作。 首先新增依賴: dependencies { &
django的資料庫斷線重連
django每次查詢都會被把連線關閉,想保持長連線方法如下: from django.core import signals from django.db import close_connection # 取消訊號關聯,實現資料庫長連線 signals.request
【UE4】 第12講 FSocket斷線重連
(版權宣告,禁止轉載) 【第03講】 實現了FSocket的連網基礎功能,這一講實現一下 斷線重連 <如果資深前輩發現有理解錯誤,還請不吝指正> <1> 建立Socket,設定阻塞模式(預設創建出來的就是阻塞模式,不用設定)  
teamtalk socket斷線重連問題的查詢
之前從teamtalk的核心庫裡面剝離出一個跨平臺網路庫,一開始用的好好的,可是在某些地方使用的時候總是出怪問題,有時候斷線重連就一直連不上,導致應用失聯,在實際使用場景中一直出問題,好不尷尬。 經過連三天的苦思冥想,除錯程式碼看輸出終於有些眉目了。 我是從以下幾個方面著手解決的,特此記錄一
ActiveMQ的斷線重連機制
primary active 節點 語法 無限 機制 新的 bubuko 獲取 斷線重連機制是ActiveMQ的高可用性具體體現之一。ActiveMQ提供failover機制去實現斷線重連的高可用性,可以使得連接斷開之後,不斷的重試連接到一個或多個brokerURL。 默認
關於資料庫斷線重連的一點點思考
最近在寫資料庫連結池,一個不可逃避的問題就是資料庫斷線重連。 查了很多資料,因為公司有很多專案用了 TP5 於是也去看了它的原始碼。 tp5的實現其實很簡單,配置了一些資料庫連線相關的錯誤資訊關鍵詞(句),然後在執行語句時 catch 異常資訊進行比對: // 伺服器斷線標識字元 p
QT 中Socket客戶端與伺服器異常斷開後重連
在現在的專案開發中,經常要使用TCP/IP協議來進行通訊,但有時候與伺服器端的連結由於網路問題導致連線異常或斷開,這就需要我們的軟體能自動重連,在Linux中,我們的思維一般是通過心跳包來監控連線是否斷開,有時候還單獨開一個執行緒,但是在QT中,就變得簡單多了,當連線異常
Yii2實現mysql斷線重連[轉載]
最近遇到“Yii2實現mysql斷線重連”問題,找了好久資料,最後找到這篇文件是說明了該情況的,感謝這位作者的分享,記錄下來,必備以後查閱。 原文連結:https://www.yiichina.com/topic/7296 Yii2實現資料庫斷線重連 一、前話 在工作中,有時候一
netty4.0 心跳檢測與斷線重連操作
因為最近專案最近要用netty,服務端放在雲端,客戶端發在內網。那如何實現netty長連線和斷線重連呢(網路故障或者其他原因,客戶端要無限取重連服務端)。接下來我們看一下如何實現這個兩個功能呢。 服務端程式碼如下: package com.example.nettydem
mqtt協議 springboot2.0.4 mqttv3 釋出訂閱程式碼呼叫,mqtt斷線重連
mqttv3 釋出訂閱程式碼呼叫 我用的是springboot2.0.4 直接上程式碼: pom.xml <dependency> <groupId>org.eclipse.paho</groupId>
iOS MQTT使用案例 (斷線重連)
iOS MQTT使用案例 (斷線重連) 參考了 iOS MQTT—-MQTTClient實戰-看這篇的就夠了 大神寫的這篇 git: MQTT-Client-Framework 介紹啥的看百度,上面大神寫的就行了,直接上乾貨。 安裝: pod 'MQTTClient'