背景css
接口格式前端
離線資源包格式web
離線資源下發json
離線資源緩存緩存
因爲線上樂刻客戶端 App
第一次打開平臺 H5
須要幾秒的加載時間,這個體驗對用戶來講並不友好,爲了讓用戶跳轉 H5
和跳轉到原生同樣的用戶體驗,就須要把 H5
相關的離線資源包下發給客戶端,客戶端就可使用離線資源來代替實際網絡請求,節省用戶等待時間和流量消耗。而且隨着業務的發展,不一樣的業務升級進度不同,就須要 App
支持模塊化升級。服務器
<!--more-->網絡
offlineResourceInfo
接口請求方法: POST
app
offlineResourceInfo
接口請求參數:模塊化
Json 形式:url
{ //"appVersion": "2.4.0", 能夠去掉,由於請求頭會包含 "resourceversionList": [{ "name": "m", "version": "1.0.0" },{ "name": "coach", "version": "1.0.0" },{ "name": "activity", "version": "1.0.0" }] }
Form 表單形式:
resourceNames=m,coach,activity&resourceVersions=1.0.0,1.0.0,1.0.0
offlineResourceInfo
接口返回結構體:
{ "data": { "resourceList": [{ "name": "m", "version": "1.0.1", "url": "http://cdn.xxx.com/resource/m/m_update_1.0.0_1.0.1.zip", "md5": "a4d7feecbcae8e2ccba3b5ba90aa8a83", "isfull": false },{ "name": "coach", "version": "1.0.1", "url": "http://cdn.xxx.com/resource/coach/coach_full_1.0.1.zip", "md5": "a4d7feecbcae8e2ccba3b5ba90aa8a83", "isfull": true } ] } }
參數說明:
"name": 模塊名 "version": 升級版本 "url": 資源包下載地址 "md5": 資源包 md5 "isfull": 是不是全量升級包
增量和全量升級包擁有一樣的結構,包含 config.json
文件和資源文件。
config.json
格式以下,version
記錄的是下發的資源版本號,validate
記錄的是全部文件的路勁和相應的 md5 hash
值。
{ "version": "1.0.1", "validate": [{ "path": "528/app.min.cs", "md5": "md5($cssFileContent)" },{ "path": "528/app.min.js", "md5": "md5($jsFileContent)" }] }
具體的資源與 config.json
平級。
--[528] ----app.min.css ----app.min.js
App
啓動時設置定時器定時器-> wifi
環境下 -> 請求服務器接口獲取 offlineResourceinfo
接口 response
,根據resourceList
的結果來決定是否須要更新,須要更新的模塊能夠下載 zip
文件
按模塊目錄存放資源包。其中目錄 moduleszip
用於存放資源壓縮包的路徑,目錄 modules
用於存放解壓後的壓縮包路徑。
因此每次請求 offlineResourceInfo
接口的時候,也須要遍歷全部模塊目錄下的 config.json
去獲取資源版本號。因此第一次請求的話,因爲本地目錄是空的,對於接口 offlineResourceInfo
的參數 resourceversionList
也是空的。
--[offlineResource] ----[moduleszip] ------[m] --------[zip] ----------m.update.1.0.0_1.0.1.zip ----------m.full.1.0.1.zip --------[temp] 解壓臨時目錄 --------[backup] 原有資源備份目錄 ------[coach] --------[zip] ----------coach.update.1.0.0_1.0.1.zip ----------coach.full.1.0.1.zip --------[temp] 解壓臨時目錄 --------[backup] 原有資源備份目錄 ----[modules] ------[m] --------config.json --------其餘資源文件 ------[coach] --------config.json --------其餘資源文件 ----[modulesflag] ------[m] --------flag.json ------[coach] --------flag.json
當下載完資源包,解壓以前須要根據接口返回的 md5
值來校驗資源包的合法性。
校驗子文件過程:須要結合 config.json
和資源來校驗每一個文件的合法性,若是不合法,就不添加該資源文件 就不保留整個資源包。
增量更新:文件的替換和增長。並且須要合併新老 config.json
。
全量更新:覆蓋模塊目錄。
模塊資源包更新以前,須要先備份以前的模塊資源。例如:拷貝目錄 offlineResource/modules/m
到目錄offlineResource/moduleszip/m/backup
來進行備份。
須要設置標誌位,並持久化到 flag.json
:
{ "doingUpgradeFlag": false, // false, 表示升級過程正常,不然升級過程有錯誤。 "doingBackupFlag": false // false, 表示備份過程正常,不然備份過程有錯誤。 }
正在升級標誌位 (總標誌位)
正在備份標誌位 (是正在升級標誌位的一個子集)
正在升級的過程包括, md5
校驗資源包,md5
校驗每一個資源文件,備份和更新過程。
若是整個升級過程當中發生普通錯誤,恢復全部標誌位,而後結束升級流程。
若是整個升級過程當中發生崩潰或者被殺掉進程,App 再次啓動後。此時 正在升級標誌位
沒有復位 (升級失敗),有如下幾種狀況須要作容錯處理:
若是 正在備份標誌位
也沒有復位 (備份失敗),此時並不會影響目標模塊資源,直接恢復全部標誌位。
若是 正在備份標誌位
已經復位 (備份成功),先清空目標模塊資源,而後作回滾操做:
回滾成功,直接復位全部標誌位。
回滾失敗,先清空目標模塊資源:
正常失敗,恢復全部標誌位。
App 崩潰或被殺掉進程,Nothing To Do.
當 正在升級標誌位
沒有復位時。此時 App webview
請求不走緩存系統。
不然 App webview
能夠繼續使用緩存系統。
只針對 webview
的以 xxx.com
爲主域名的請求進行攔截,而後根據請求連接,找到具體文件緩存。
找具體文件緩存的方式:
遍歷全部模塊下的
config.json
文件,看可否找到具體的資源文件。這樣效率會比較慢,可是更適合現有的場景。
根據連接的一級路徑找到對應模塊下的config.json
文件,看可否找到具體的資源文件。這樣效率會比較高,可是目前連接的一級路徑並不規範。直接根據請求
URL
的PATH
去本地查找是否存在具體的資源文件。PATH
的一級路徑表明模塊名,剩餘部分表明資源路徑。
App 這裏會使用第二種方式去找緩存文件,這樣的話就須要前端小夥伴規範連接路徑。
拿到緩存文件以後,須要再次校驗緩存文件的合法性,合法則使用緩存,不合法就須要下面的容錯處理。
若是找到的緩存文件已經損壞或者不存在(解壓過程被中斷,殺掉進程或者 crash
),此時須要繼續走網絡,而且把網絡結果進行 md5
校驗,若是合法,須要把該結果保存到緩存系統,若是不合法,不作處理。