全面講解cocoscreator熱更新

環境相關

系統:Mac

當前版本是cocoscreator 2.4.x,

語言是typescript

構建模版:link

發佈路徑: ./build

發佈平臺: andoid

資源服務器: ftp 或 nodejs

本文用到demo:在公衆號 亮亮同學TT。發送 熱更 即可獲得 源碼和資源工程

目錄:

1,熱更效果展示

2,熱更流程介紹

3,熱更涉及到的文件介紹

4,以白話的形式解釋cocoscreator熱更新

5,基礎版實際操作

6,可版本回退版實際操作

7,動態地址熱更實際操作

首先看一下熱更新的效果

下面四張圖分別是:

1,初始界面是有一隻小飛機,版本是1.0.0

[圖片上傳失敗...(image-311a3c-1606894405964)]

2,點擊檢查版本發現有新版本
[圖片上傳失敗...(image-77f7cf-1606894405964)]

3,點擊熱更按鈕,更新爲遠程版本 小殭屍 替換掉了小飛機,版本號升到 1.0.2
[圖片上傳失敗...(image-ae9b96-1606894405964)]

4,再次點擊檢查熱更,提示我們 現在已經跟新到最新版本。
[圖片上傳失敗...(image-8a214f-1606894405964)]

然後我們在具體的瞭解一下cocoscreator的熱更原理

cocoscreator的熱更新仿照web網頁的更新模式,大致如下:

1,服務器端保存最新版本的完整資源

2,客戶端發送請求服務器端版本進行對比獲得差異列表

3,從服務器下載所有新版本中改動的資源文件

4,用新資源覆蓋舊緩存以及應用包內的文件

注意:
Cocos 的熱更新機制通過直接比較最新版本和本地版本的差異來生成差異列表並更新。這樣即可天然支持跨版本更新,比如本地版本爲 A,遠程版本是 C,則直接更新 A 和 C 之間的差異,並不需要生成 A 到 B 和 B 到 C 的更新包,依次更新。所以,在這種設計思路下,新版本的文件以離散的方式保存在服務端,更新時以文件爲單位下載。

接着詳細的瞭解cocoscreator熱更流程

下面這張圖 展示了cocoscreator的 熱更流程

[圖片上傳失敗...(image-92814c-1606894405964)]

那麼我們實現熱更需要哪些操作呢?要修改哪些文件?要寫哪些代碼,注意哪些問題呢?

熱更涉及到的文件介紹

(1)Manifest文件
Manifest格式文件是用來比較本地和遠程資源差異的一種json格式,其中保存了版本信息,引擎版本信息等等,我們通過Manifest文件進行對比版本 判斷是否需要熱更新。

Manifest文件有兩個 分別是 project.manifest 包含了所有的熱更需要的信息如下

{
    "packageUrl" :          遠程資源的本地緩存根路徑
    "remoteVersionUrl" :    [可選項] 遠程版本文件的路徑,用來判斷服務器端是否有新版本的資源
    "remoteManifestUrl" :   遠程資源 Manifest 文件的路徑,包含版本信息以及所有資源信息
    "version" :             資源的版本
    "engineVersion" :       引擎版本
    "assets" :              所有資源列表
        "key" :             資源的相對路徑(相對於資源根目錄)
        "md5" :             md5 值代表資源文件的版本信息
        "compressed" :      [可選項] 如果值爲 true,文件被下載後會自動被解壓,目前僅支持 zip 壓縮格式
        "size" :            [可選項] 文件的字節尺寸,用於快速獲取進度信息
    "searchPaths" :         需要添加到 FileUtils 中的搜索路徑列表
}

另一個是version.manifest文件 只包含了少量的熱更信息, 如版本信息等。結構如下:

{"packageUrl":遠程資源的本地緩存路徑,
"remoteManifestUrl":遠程資源 Manifest 文件的路徑,包含版本信息以及所有資源信息
"remoteVersionUrl":遠程版本文件的路徑,用來判斷服務器端是否有新版本的資源
"version":版本信息
}

這兩個文件由 version_generator.js生成。 安裝nodejs 修改相關參數 cd 到當前version_generator.js目錄。

運行node version_generator.js 即可生成

(2)assets 和 src 文件目錄
在項目構建之前我們可以看到 assets文件夾中包含了 遊戲的資源以及代碼,這是構建之前的工程資源目錄。當我們構建工程後。 我們會在biuld/jsb-link/下面看到 assets 和 src 兩個文件夾。
assets是保存了構建後的資源,src是保存了構建後的腳本。

[圖片上傳失敗...(image-57eb3a-1606894405964)]

白話的形式解釋cocoscreator熱更新

cocoscreator熱更新是對遠程版本和本地版本的 版本號進行對比 cocoscreator認爲 本地版本號小於遠程版本號就需要進行熱更,版本號如何而來呢? 是在 manifest文件裏獲取,我們把攜帶高版本號的 manifest文件和最新的構建資源放到遠程服務器 ,同時本地的包內留有版本較低和舊的資源,當在需要檢查熱更的時候 ,cocoscretor會先初始化本地包內的manifest文件,同時創建指定目錄的臨時文件夾和緩存文件夾 比如緩存文件夾是plane,臨時文件夾則爲plane.temp。下載遠程的version.manifest文件緩存到本地 ,獲取版本號,進行比較,遠程版本高,則下載 攜帶資源信息的project.manifest 文件到臨時文件夾plane.temp下。接着對比本地project.manifest與從遠程下載到臨時文件夾中的project.manifest 資源列表 即 當中的assets表,然後生成差異列表。然後通過downloader進行下載差異列表中的文件到本地,如果有壓縮文件解壓縮。文件下載成功後,對下載的文件進行校驗接着通知下載進度,保存下載進度,檢查是否有失敗的資源,如果沒有 則 拷貝臨時文件夾的所有內容到 設定的緩存目錄,如果更新失敗不拷貝臨時資源到緩存目錄,避免了污染原有的本地緩存資源。cocoscreator會使用manifest文件標示每個資源的狀態(未開始,下載中,下載完成)如果熱更中途網絡中斷,重新啓動熱更,cocoscreator會檢查臨時文件夾中是否有未完成的更新,校驗版本是否和遠程匹配之後,則使用臨時文件夾中的manifest作爲遠程manifest繼續更新(前提是臨時文件中已經下載了project.manifest。在臨時文件夾中的命名會有一個.temp後綴)此時對於下載狀態爲完成的不會重新下載,對於下載中的文件一般是從頭開始下載。更新完成後 cocoscreator將遠程的 版本文件project.manifest 作爲當前本地的 project.manifest,下次更新 即用最新的 manifest文件的版本號對比接着 保存本地project.manifest文件的搜索路徑,重啓遊戲,執行main.js。main.js中把緩存文件夾搜索路徑前置到搜索路徑, 進入遊戲即 用到的資源 爲最新的資源,達到熱更新效果。

注意:下載失敗瞭如何處理,當熱更過程中出現異常,下載失敗,解壓失敗,校驗失敗都會觸發UPDATE_FAILED回調事件,此時所有下載失敗的資源列表會記錄在熱更管理器中, 此時我們可以調用

assetsManager.downloadFailedAssets();

重新進入熱更流程,僅下載失敗的資源。

前面是理論介紹 後面是實操取證

在實操之前 先看一下工程目錄結構

[圖片上傳失敗...(image-aaefa5-1606894405964)]

製作舊版本

1,首先我們需要搭建一個資源服務器,以nodejs爲例

1)先創建一個nodejs目錄
cd到該目錄 創建一個hotUpdate目錄 這個用於存放遠程版本資源

2)搭建服務器之前先安裝 nodejs
接着安裝 Express

安裝exptress指導地址

3)編輯服務器腳本
創建一個js腳本命名爲server.js
將以下內容複製進去

var express = require('express');
var path = require('path');
var app = express();
app.use(express.static(path.join(__dirname, 'hotUpdate')));
app.listen(80);

最後的目錄結構是:

[圖片上傳失敗...(image-3ac627-1606894405964)]

4)測試訪問服務器資源

在hotUpdate內放入一個文件 比如server.js文件

cd到 服務器腳本目錄 運行命令行

node server.js 

開啓服務器。
然後在瀏覽器輸入 該服務器 內 文件的地址

http://127.0.0.1/server.js

可以查看到如下信息 說明能正常訪問服務器的資源

[圖片上傳失敗...(image-8f0912-1606894405964)]

其中127.0.0.1是訪問本機的ip地址 ,如果想讓任何人訪問遠程資源文件。可以把這個地址改成當前電腦的ip地址 .

命令行
ifconfig | grep "inet " | grep -v 127.0.0.1 查看本機ip

2,編寫熱更新的代碼

編寫hotupdate.ts文件

代碼結構:

1)onload內 初始化資源管理器,同時設置本地緩存目錄,設置版本對比回調和檢查文件回調

[圖片上傳失敗...(image-61eb6f-1606894405964)]

2)檢查版本函數,和檢查版本回調函數

[圖片上傳失敗...(image-3e6ad9-1606894405964)]

3),熱更函數和熱更函數回調

[圖片上傳失敗...(image-fc9e7a-1606894405964)]

3,編輯熱更界面,並將hotupdate.ts掛在 熱更界面

[圖片上傳失敗...(image-30f2-1606894405964)]

上圖中紅圈內的 文件如何來的上面已經說過 是用version_generator.js生成的,這個文件等看完教程 可以在我的公衆號(亮亮同學TT)裏拿到。

下面 修改version_generator.js

[圖片上傳失敗...(image-6f9ef0-1606894405964)]

上圖的地址是你的服務器的地址和對應版本資源的地址,version是版本號。修改成1.1.2

cd到version_generator.js同級目錄 運行node version_generator.js 生成兩個manifest文件如下圖

[圖片上傳失敗...(image-176e01-1606894405964)]

將project.manifest拖到熱更界面對應位置

[圖片上傳失敗...(image-1dbffa-1606894405964)]

此時版本號是1.1.2

進行構建,構建結束後需要檢查一下main.js的代碼
如圖

[圖片上傳失敗...(image-2c5552-1606894405964)]

有畫圈的代碼,在熱更完後才能讀取到最新的緩存資源。那麼這寫代碼時如何生成的呢?
我們可以看到 工程目錄下 有一個packages/hot-update目錄 裏面 main.js可以在 構建項目之後 把 這段緩存資源路徑前置的代碼加到main.js裏面去。

編譯打包。安裝到手機上(電腦上更新完看不到效果的)

製作新版本
將界面上的小飛機換成小骷髏,構建項目

然後修改version_generator.js中版本號爲1.1.3

運行node version_generator.js

生成 version.manifest,project.manifest

將構建後的assets,src文件,version.manifest,project.manifest 放到資源服務器中 如圖

[圖片上傳失敗...(image-4f9b1d-1606894405964)]

打開手機上的安裝的app 當前版本是1.1.2,顯示的是小飛機點擊檢查更新按鈕 會提示有新版本 然後點擊更新。更新成功版本號爲1.1.3 同時 小飛機變成了小骷髏

[圖片上傳失敗...(image-977442-1606894405964)]

[圖片上傳失敗...(image-8f9427-1606894405964)]
[圖片上傳失敗...(image-650a9d-1606894405964)]

到此 熱更基礎版就弄好了。

可版本回退版實際操作

在實際項目中更新版本可能不小心 攜帶了意外的bug 要想快速還原。那就需要回退到上個版本。實際上 cocoscreator的熱更新 默認 是 如果遠程版本大於本地版本 纔會進行熱更的,那麼如何實現回退?

這個問題可以修改 版本檢查函數的邏輯,即 只要版本不同就熱更,這樣可以通過服務器傳給客戶端要回退的版本就可以了 就可以更新到熱和版本了

代碼:

/**比較版本 版本不同則更新 返回小於0的即爲需要熱更*/
    versionCompareHanle( versionA : string , versionB : string ){
        console.log(`當前版本 :  ${versionA} , 遠程版本 : ${versionB}`);
        let vA = versionA.split('.');
        let vB = versionB.split('.');
        for( let i = 0 ; i < vA.length && i < vB.length ; ++I ){
            let a = parseInt(vA[I]);
            let b = parseInt(vB[I]);
            if ( a === b ){
                continue;
            }
            else{
                return  -1;//這裏直接返回-1 
            }
        }
        if ( vB.length > vA.length){
            return -1;
        }
        return 0;
    }

動態地址熱更實際操作

那麼,如果我想在遠程保存不同的版本 來應對不同渠道的遊戲內容和 發生意外 進行回退到其他版本呢?

針對這個問題,可以 用動態地址熱更的方式解決。

因爲cocoscreator認爲 如果緩存地址中有版本文件 就直接用該版本文件中的版本 和 地址作爲當前的 版本和 地址信息。
如果沒有則用包內的project.manifest的 版本和地址信息。

所以,我們只需要動態修改緩存目錄中的地址信息即可達到動態熱更

packageUrl

remoteManifestUrl

remoteVersionUrl

從服務器獲取最新版本的地址信息 然後判斷版本是否有變化,如果有,則將 packageUrl

remoteManifestUrl

remoteVersionUrl

的地址信息替換爲 最新版本的地址信息。然後在檢查熱更新 。
代碼如下:

[圖片上傳失敗...(image-e24dc9-1606894405964)]

[圖片上傳失敗...(image-648cd1-1606894405964)]

到目前爲止cocoscreator熱更新第一期基本上說完了,當中還有很多內容需要根據自己項目的需要進行修改。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章