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