Cocos2dx-lua中資源熱更新

  項目選擇C++ 和 lua 混合, 看中的就是lua代碼的熱更新優點,想一想以前客戶端出現了bug,須要玩家從新下載安裝包,這帶來的流失率是挺高的; 而隨着如今app體積日益增大,動輒幾十兆、上百兆的安裝包重複下載,對用戶體驗是很是不友好的;另外appstore的審覈也是嚴格、標準可變的,很容易審覈被拒,致使應用的問題沒法及時修復。而選擇lua作爲開發語言,就能作到幾乎無感知的修復、增長應用的新功能,對於開發者能夠及時修復問題,而對於玩家來講則能得到更好的遊戲體驗。從某狐剛推出某耀客戶端項目,客戶端購買、諮詢量激增來看,這個功能仍是頗有吸引力的。服務器

  熱更新方案,一開始的設計是單文件更新,思路是:網絡

  一、打包的時候利用腳本對所有的資源文件:包含lua腳本、遊戲的圖片、音頻資源生成一份版本文件app

  二、客戶端啓動的時候從服務器下載版本文件,跟本地的版本文件進行對比,生成更新列表,而後進行更新curl

  上述方案的優點在於:lua

  一、資源服務器只須要存一套資源文件、url

  二、不用考慮客戶端版本與服務器版本之間差別過大,致使數據不對等的問題spa

  三、方案實現簡單,使用的成本也低,能夠實現一些取巧操做(資源服務器直接改某個文件的差別值,讓客戶端直接更新等)設計

  可是在實際的使用過程當中也發現了該方案存在不足:若是待更新的資源過多,那麼就會產生大量的http請求,嚴重的影響了下載體驗,並且單個文件的更新失敗,須要一個很是複雜的斷點續傳的方案來控制總體更新。code

  在這裏提一下通常客戶端實現的文件下載功能:利用curl庫,發起請求進行文件下載。這就會引起兩個問題:請求量及請求響應。上述方案的核心點是根據版本文件生成差別列表,而後再單獨下載差別列表中的每一個文件,因此每下載一個文件,就會發起一次請求,若是某次更新有上千個文件,那麼單個客戶端更新所發起的請求量將是巨大的。上千次請求,引起上千次的響應等待,對帶寬及玩家的等待時間都將產生巨大的影響!blog

  所以咱們須要新的更新方案:更新是對差別文件進行更新,以前將差別對比放在了客戶端處理階段,那麼能夠將差別對比放在更新包生成的階段,將版本間的差別文件提取出來,合併成一個壓縮包,客戶端直接下載這一個壓縮包再解壓,實現功能的更新。咱們將這個方案稱爲差別包更新

  實現這個方案,須要考慮到:

  一、客戶端每次只下載一個文件,須要嚴格保證下載到正確的資源

  二、客戶端更新存在版本延時的問題,須要有跨版本的差別包

一、嚴格保證資源的正確下載

  (1)網絡不穩定的處理:

  手機客戶端考慮到移動網絡的不穩定,容易致使斷網、超時的問題。前面提到的單文件更新方案,在更新的過程當中單個文件下載失敗,須要一套很是複雜的斷點續傳方案,才能控制好總體的功能更新,咱們是很是粗魯的直接從新下載。。。調整到下載壓縮包以後,就能夠很方便的利用curl庫提供的功能,來實現斷點續傳功能:

curl_easy_setopt(_curl, CURLOPT_RESUME_FROM, localLen)

  核心就是上述代碼,CURLOPT_RESUME_FROM, 表示從參數3的位置來寫入本地文件,而參數3的值也很容易獲取,直接使用引擎的getDataFromFile方法getSize就能拿到當前階段本地文件的大小。

  (2)差別包更新失敗的處理:

  以前的單文件更新方案,假如存在錯誤,可能也只是單個文件或單獨幾個文件出現問題,修復比較方便。可是在差別包更新方案中,每次的更新是單個壓縮包的更新,就會存在:

  a.壓縮包下載失敗致使客戶端出現重大功能異常

  b.版本與版本之間生成了錯誤的差別列表致使更新異常

  c.客戶端資源版本不統一,如何下載到統一的更新包

  咱們的應對方案是:保留單文件更新功能,在壓縮包下載失敗時進行單文件更新;採用更可靠的生成文件差別值的方案,由一臺設備統一輩子成更新包,針對不一樣版本生成不一樣的差別包。

二、更可靠的差別生成方案:

  在上面有提到,差別列表生成錯誤、客戶端版本有差別兩個問題,在這裏具體談一下采用一套更可靠的差別生成方案:

  (1)差別值的生成:

  在單文件更新方案裏,咱們是簡單的對文件大小進行MD5處理,獲得一個差別值,而後更新對比中對md5值進行對比,生成差別列表。這個方案就有很大的機率出現md5值一致,可是實際卻須要更新的狀況,所以咱們改用獲取文件的修改時間,這樣就大大下降了上述狀況出現的機率了。

  (2)差別包的生成:

  差別值的獲取,差別包的生成, 在這裏講一下思路。這裏舉個例子說明客戶端版本差別:客戶端A的當前版本爲1, 客戶端B的當前版本號爲2,此時發佈版本3的更新,這個時候客戶端A和客戶端B的更新列表是存在差別的,該如何處理?在單文件更新方案下,這不存在問題,A和B都是以3的版本文件,在客戶端本地直接生成差別列表,去下載對應的文件便可。可是在差別包更新方案中,就須要生成如1-3,2-3這樣的版本差別包。並且遊戲客戶端的更新是比較頻繁的,就表示每次更新,所須要的差別包是很是多的,所以考慮到沒必要要的工做複雜度提高,須要提出一個基準包的概念。每次進行了底包(玩家從新安裝了客戶端)更新,底包對應的資源版本就是一個基準的,不管玩家多久不更新,他都有一個基準的包,所以生成差別包的時候,能夠針對這個基準包生成一份差別包,這樣就能保證功能的正常更新了。所以咱們的差別包就包含了:版本間的差別包,與基準版本的基準差別包。

  咱們控制一個版本跨度,好比5,設定一個基準版本0,假如客戶端A的版本號是6,資源服務器的版本號是7,版本跨度是1,在咱們設定的跨度之間,客戶端A更新的時候就下載6-7之間的差別包;客戶端B的版本號是5,與資源服務器的版本跨度是2,下載5-7的包;客戶端C的版本號是1,與資源服務器的版本跨度是6,大於咱們設定的限值了,這個時候就下載0-7的基準差別包。 這樣就能保證不一樣版本的客戶端,也能下載到統一的更新資源。

  解決了上述問題,咱們實現的差別包更新方案,在實際的體驗中,就是一個字:快!在帶寬一致的狀況下,大概算了一下,以前須要10s才能完成的更新,如今只要1s不到的時間就能下載好,再根據設備配置的差別存在必定的解壓時間,可是總時間是小於以前那個方案的。這個方案不涉及到引擎相關(最多就是用引擎的接口拿獲取文件大小),所以能夠加入到使用到了熱更新方案的不一樣開發項目中去。

相關文章
相關標籤/搜索