一種簡單的客戶端更新方案


在c/s結構的程序中,客戶端自動更新是簡化部署的一個常見需求.更新實際上做的操作是:

  • 與服務器當前的文件做diff,找出所有變動的文件
  • 下載變動的文件,替換掉本地的文件

從這兩個操作來看,服務器起碼要向客戶端提供兩個功能:

  • 當前有那些文件
  • 下載文件

其實第一個功能也可以轉為下載文件,只要提供描述當前文件列表信息的文件就行了。通常有兩種更新模式,增量更新與直接更新。增量更新是指低版本向高版本逐版本更新,這種方式的好處在於,服務器發布新版本時可以直接預生成diff補丁包,客戶端直接按照補丁包進行替換,但壞處是:

  • 跨版本比較多時,會進行重復操作
  • 管理起來麻煩,要保存所有歷史版本

直接升級則不會有重復操作,且服務器只要保存一個最新版本即可.本文描述的方案就是直接升級的.

服務端

基於文件服務器工作,FTP或者HTTP.用兩個json文件來管理版本,app.json和appflist.json.文件服務器上的結構為:

  • 文件服務器根目錄
  • app1
  • app2

app就表示客戶端的根目錄,每個app里都會有app.json和appflist.json.服務器的開發工作就是生成這兩個文件,以及更新app目錄.

app.json

{"version":"1.0.0","info":"版本信息"}

用於描述版本號與版本信息,主要給客戶端進行快速判斷是否要升級.客戶端可以簡單的判斷版本號是否相等來決定要不要升級.

appflist.json

[{"path":"foo.dll","md5":"","ctime":147989119}]

用於描述文件列表信息,包含當前版本所有文件信息(除app.json,appflist.json),用於給客戶端做diff.

path 為客戶端根目錄的相對路徑

客戶端

客戶端通過本地的app.json和appflist.json與服務器上的同名文件來決定更新操作。更新時會用ftp://127.0.0.1/app1/foo.dll這樣的url去下載文件,url的格式為協議://host:port/app目錄/文件路徑

更新分為五個步驟:

  1. 判斷是否要更新 通過比對app.json的version來決定是否要更新
  2. diff 下載appflist.json,然后通過md5篩選出增刪改的文件
  3. 下載變動的文件 用path和app名下載增改的文件
  4. 本地替換 進行增刪改操作
  5. 刪除下載的文件

在更新時要注意用獨立的進程操作,因為要替換主程序的文件.

還有如何處理更新失敗的情況,更新失敗有兩種情況:

  • 更新時程序被強制結束
  • 文件操作時失敗

第一種情況發生時,如果正在替換文件,可能會損壞文件,導致主程序不能正常打開,這個問題不在於文件損壞,而是主程序無法運行,也就不能再次進入更新流程了,如果能進來則把流程重來一次就好了,不能進來時只能讓用戶手動打開更新程序了.因此這種情況是不需要在客戶端寫特定代碼處理的.
第二種情況發生時,也直接重試流程,如果一直錯,那可能是無操作文件的權限,此時並不會損壞舊文件,因此也不需要特殊處理.


最后我寫了一個shupd實現了這些功能,放在github上,shupd的server部分為一個用來生成app.json,appflist.json,拷貝變動文件的工具;client部分為c實現的動態庫。目前基於ftp工作,有興趣的朋友可以看看.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM