CocosCreator 2.3.4 熱更新 + Docker Nginx FTP Server(遠端資源服務器)搭建
- 承鑫 郭
- 2020年8月19日
- 讀畢需時 4 分鐘
前言
由於使用CocosCreator來做App都會需要熱更新功能,經過Coocs版本翻新熱更新的功能也有一些寫法改變,最近剛好在優化專案順便順了一遍熱更新發現有很多地方有改進,也有新的坑點,藉此紀錄來方便以後查看,也希望可以對一些接觸到2.3.4版本的人有所幫助
熱更新原理
https://docs.cocos.com/creator/manual/zh/advanced-topics/hot-update.html https://docs.cocos.com/creator/manual/zh/advanced-topics/assets-manager.html 原理請參考官方文檔,上面有詳細解說,本次紀錄只有針對可能會遇到的坑點或是測試上會遇到的問題進行解說,基本上還是照著官方文檔操作,所以官方文件務必詳細看過
熱更新管理者
官方熱更新腳本 基本上可以按照自己專案的需求從官方的熱更新.js做修改, 如果沒有需求就不用修改,也可以先下載官方範例跑跑看 目前本專案架構是客戶端會寫死一個遠程的服務器資源地址 也方便以後擴充為從某個HTTP地址拿熱更新地址 那我修改的地方如下:
這邊會將本地的project.manifest文件的 1.packageurl 2.remoteManifestUrl 3.romoteVersionUrl 更新成this.HotUpdateUrl,也就是我們目前客戶端寫死的資源伺服器網址 此熱更新組件會讓本地和遠程的Manifest做版本的比對,如果版本不同才會做後續更新的動作,所以當有新的資源需要更新時,必須使用version_generator.js來產出Manifest檔案並部署到遠程服務器上,(PS.這邊不使用CocosCreator的熱更新插件 原因是因為使用插件來產出Manifest會造成手動上的麻煩(設定遠程服務器路徑,只能在cocos上產出等等) 使用官方的version_generator.js只需要NodeJs環境就可完成 未來也有機會可以讓他走自動化(CI/CD),下一個章節會詳細介紹如何快速部署一個可測試的遠程資源服務器
資源服務器搭建(Docker+Nginx)
熱更新需要一個遠程服務器來存放最新的資源(包含程式碼) 1.首先要配置一個類似FTP服務的nginx.conf
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 8080;
server_name CocosHotFixServer;
autoindex on;
autoindex_exact_size on;# 显示文件大小
autoindex_localtime on;# 显示文件时间
index index.php index.html;
charset utf-8;
access_log /var/log/nginx/access_log;
error_log /var/log/nginx/error_log;
root /etc/nginx/html;
location / {
root /etc/nginx/html/;
autoindex on;
autoindex_exact_size on;# 显示文件大小
autoindex_localtime on;# 显示文件时间
}
}
include servers/*;
}
2.建立Docker環境 https://www.docker.com/get-started 建立完後開啟終端機輸入
sudo docker run -v "YourResources":/etc/nginx/html/ -v "YourConfig":/etc/nginx/nginx.conf -v -p 7777:8080 --name hotfix-server-container -d nginx
他會自己抓取最新版本的nginx 並把Container Run起來 "YourResources"要改成你的資源路徑, "YourConfig"要改成你剛剛編寫的nginx.conf 位置Port和container名稱都可以自已定義,如果成功的話輸入docker ps會看到你的contianer已經開始運行
熱更新部署
1.專案除錯完畢後點選[項目] => [構建發布]
這邊需要注意的點是模板是link或是default需要記一下 等會會用到 2.開啟構建後的資料夾,找到main.js並在最上方新增程式碼,此步驟為優先設定熱更路徑為搜尋路徑,如果此步驟沒有做就會抓不到更新後的檔案
(function () {
if (typeof window.jsb === 'object') {
var hotUpdateSearchPaths = localStorage.getItem('HotUpdateSearchPaths');
if (hotUpdateSearchPaths) {
var paths = JSON.parse(hotUpdateSearchPaths);
jsb.fileUtils.setSearchPaths(paths);
var fileList = [];
var storagePath = paths[0] || '';
var tempPath = storagePath + '_temp/';
var baseOffset = tempPath.length;
if (jsb.fileUtils.isDirectoryExist(tempPath) && !jsb.fileUtils.isFileExist(tempPath + 'project.manifest.temp')) {
jsb.fileUtils.listFilesRecursively(tempPath, fileList);
fileList.forEach(srcPath => {
var relativePath = srcPath.substr(baseOffset);
var dstPath = storagePath + relativePath;
if (srcPath[srcPath.length] == '/') {
cc.fileUtils.createDirectory(dstPath)
}
else {
if (cc.fileUtils.isFileExist(dstPath)) {
cc.fileUtils.removeFile(dstPath)
}
cc.fileUtils.renameFile(srcPath, dstPath);
}
})
cc.fileUtils.removeDirectory(tempPath);
}
}
}
})();
這個步驟由於每次編譯後都會覆蓋成舊的main.js,所以建議建立一個build-templates來存放main.js,所以剛剛記住的模板是jsb-default就建立jsb-default的資料夾,反之就建立jsb-link,下面存放main.js,這樣他編譯後就會覆蓋成新的main.js擋囉,還有一點需要注意,就是這裡的main.js模擬器不會跑這,所以測試熱更新流程建議是使用實體手機測試,不然更新完換場景那邊可能會出現錯誤或是沒有辦法更新! build-templates參考官方文檔 https://docs.cocos.com/creator/manual/zh/publish/custom-project-build-template.html
我們有了[res][src]兩個資料夾後我們需要使用官方給的version-generater來產生.Manifest檔 3.Node環境建置 https://nodejs.org/en/download/ 這邊提供一個安裝的方式,如果要使用brew安裝也是可以的 安裝完後到專案的目錄下打上
node version_generator.js -v 1.0.0 -u http://your-server-address/tutorial-hot-update/remote-assets/ -s native/package/ -d assets/
- 參數說明:
-v 指定 Manifest 文件的主版本号。
-u 指定服务器远程包的地址,这个地址需要和最初发布版本中 Manifest 文件的远程包地址一致,否则无法检测到更新。
-s 本地原生打包版本的目录相对路径。
-d 保存 Manifest 文件的地址。此步驟會產生project.manifest和version.manifest
把這兩個Manifest檔案加上剛剛的src, res一起放到我們的遠程資料夾上,這時候手動看看是否訪問的到,如果可以部署這邊就大功告成啦
客戶端熱更新流程
1.在Loading場景製作資源更新介面並掛上你熱更新腳本
2.客戶端配置可正確連結的遠程服務器網址,這邊我是讓手機和電腦使用同一個網域(wifi),之後打包,使用Android Studio連結手機Debug 3.啟動Loading場景時,腳本會去偵測本地的版號和遠程資源服務器的版號是否相同,如果不同將會做檔案比對/更新,更新完畢後重啟遊戲,會看到新的版本已經開始運行 PS.如果要反覆測試,就把該App的快取資源刪除,就可以把新的資料刪掉囉
結語
熱更新是App不可或缺的機制之ㄧ,但由於之前Cocos官方那邊的Github有針對main.js,verison_generator.js做翻新,以適應新的coocs版本,目前針對2.3.4做一個簡單的Demo,也希望此框架也可以延續到新的版本中,未來希望可以想一套CI/CD的流程,例如建構後把src和res上傳到GitLab後,再使用GitLab Runner中的Nodejs環境產出Manifest檔,最後一併Scp到我們的遠程服務器上,讓一切都自動化起來~
Comments