H5游戲如何應對網絡不穩定[超時/重發/加載失敗]


H5游戲相比其他任何一種游戲而言,網絡不穩定所帶來的影響是最大的

一方面是玩游戲的場合,無論是3/4G還是wifi信號都不是很靠譜,如果再加上地鐵電梯等場景,就更糟了

另一方面是H5自身既要與游戲服通信又要與資源服務器通信,尤其在新玩家沒有緩存的情況下,網絡請求比原生手游多很多倍

因此,在玩家網絡不穩定的情況下,努力提升游戲體驗避免用戶流失,是十分必要的

 

然而,雖然生活中網絡不穩定是常態,但是在開發過程中卻非常難以模擬和重現(除非團隊里有真正資深的測試,每天跑到wifi一格的地方給你測試...)

今天就結合葫蘆娃H5上線3個月以來的經驗(各種毀天滅地大bug)來討論以下幾個需要注意的點

轉載注明http://www.cnblogs.com/billyrun/articles/8311765.html

 

1.http超時回調

短連接一般采用XMLHttpRequest

調用的時候一定要處理超時和錯誤

錯誤可以用http狀態碼判斷

超時需要手動設置XMLHttpRequest對象的timeout/ontimeout屬性

若不設置則timeout默認是-1,表示沒有超時時限

這顯然是不對的,長時間沒收到響應的時候頁面就傻了

 

以下引用文檔中的例子

注意timeout/ontimeout的設置位置應該在調用open之后,調用send之前

https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/timeout

var xhr = new XMLHttpRequest();
xhr.open('GET', '/server', true);
xhr.timeout = 2000; // 超時時間,單位是毫秒
xhr.onload = function () {
  // 請求完成。在此進行處理。
};
xhr.ontimeout = function (e) {
  // XMLHttpRequest 超時。在此做某事。
};
xhr.send(null);

  

2.http/websocket重發請求

剛寫了為XMLHttpRequest對象設置超時屬性

若是長連接,使用websocket的話,並沒有簡單的設置方法

可以自己寫一個輪詢來判斷某一次請求是否超時

大致思路如下:

設置過期時間,如5s

客戶端每次發包時在數據包插入唯一ID,並將ID與當前時刻一並記錄在客戶端

客戶端每秒輪詢,檢查所記錄的ID時刻是否到達過期時間,若過期則將ID清除

收到服務端返回數據包時,取出唯一ID

若客戶端仍記錄有該ID,解析該回包,並移除該記錄;

若客戶端沒有記錄此ID,說明已經超時,直接丟棄該回包

 

然而對於一些關鍵請求(無論http還是websocket)

僅僅預防超時還是不夠的,在超時的時候還需要做重發,以確保游戲邏輯通暢

重發的設計思路是

保存每次請求的全部參數(包括url/正確回調/錯誤回調/超時回調等)

當超時發生時重新調用一次,具體的場景可以結合彈框讓用戶選擇是否需要重發

 

3.資源加載失敗

對全體玩家而言,游戲中所有的動態加載其實都有很高的失敗可能性

然而在開發過程中幾乎不可能體會到!

以官方CCGame.js加載游戲腳本的代碼為例

// Load game scripts
var jsList = config[CONFIG_KEY.jsList];
if (jsList && jsList.length > 0) {
    cc.loader.load(jsList, function (err) {
        if (err) throw new Error(JSON.stringify(err));
        self._prepared = true;
        if (cb) cb();
        self.emit(self.EVENT_GAME_INITED);
    });
}

加載回調函數中第一個參數是err

這里err是一個空對象或數組

加載回調的處理原則如下

3.1判斷加載是否成功

若加載失敗,那么無論加載的是腳本還是資源,失敗了都是不可用的!

所以成功和失敗必然是兩套邏輯

如以上代碼if (err) throw new Error(JSON.stringify(err));

遇到錯誤拋出異常並停止腳本運行

3.2加載失敗如何處理

並不是所有加載都可以在失敗時throw error或return

若腳本或關鍵的資源加載失敗,一定要手動重新加載!一些場景還要提示用戶

當出錯時err數組中的數據就是未加載成功的資源url

因此可以這樣加載尚未成功的資源cc.loader.load(err , function(...){...})

理論上來講是一個遞歸調用,把必要的資源加載到成功為止

當然也可以做一些限制,比如連續失敗3次就告訴用戶當前網絡實在太差了...

3.3加載回調容易出現的錯誤

資源加載往往都會被封裝成更易用的方法

封裝過程中一般統一去處理加載錯誤的情況

而傳入的回調函數一般都是僅在加載成功時才執行的

若需要嚴格判斷加載的數量,比如預加載的進度條顯示

則一定要考慮加載失敗的情況,不然容易出現加載走不到100%這種事

 

 

http://www.sohu.com/a/216766512_229934

最后熱烈慶祝葫蘆娃H5被某媒體評為年度最佳

hiahiahia

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM