由於轉戰C#了,以前不少東西都丟了。如今從頭開始弄基礎服務,首先第一個就是客戶端的自動更新。以前簡單搜了一下相關功能的實現。有一個文章我沒有看懂,另外一片文章裏邊說的應該是提交本地數據,而後計算差別化包,讓服務器返回差別化數據包。固然這樣不是不行。確定是可行的,可是對於服務器來講這部分工做可能就有點麻煩了。由於你得讓服務器有這個計算能力。參考Cocos2dx 3.9的Lua增量更新模塊,簡單作了一個基礎框架模型出來。git
這個其實很簡單,就是從新下載一個完整的安裝包,而後從新安裝一遍,無論原來存不存在內容,若是原來存在內容那麼久替換掉,若是原來不存在內容那麼就添加上新內容就是了。其實這個提及來很簡單,可是可能會存在一些問題。程序員
- 流量問題 可能如今看來這個問題並非多麼大的問題,由於如今帶寬已經很是寬了。100M的內容按照10Mpbs的帶寬來算,也就一分多鐘就能下載完了。 - 渣子問題 這種覆蓋安裝通常會存在一個渣子的問題。好比說,我在安裝目錄裏邊生成了一個不在後續安裝包的文件,那麼這個文件就沒有辦法被清理掉。這就可能很尷尬了,好比說你的項目依賴系統提供的一個Dll,若是你的目錄中直接存在這個Dll那麼就會優先使用你對應目錄中的Dll(若是我沒記錯應該是這樣),若是是我做爲攻擊者的話,我頗有可能會給你放一個我種下病毒的Dll。這就很尷尬了
這個原理也比較簡單,其實就是咱們都以爲徹底安裝太費勁了,那麼個人軟件又須要比較頻繁的更新,好比說某些桌遊可能過個節日要上節日相關的功能,這樣就能夠添加新的Dll而後又不能出一個一個的完整安裝包。那麼我能夠在完整安裝包的基礎上打補丁嘛。好比說,我出了版本1.0,過了十天半個月過端午了,我出個龍舟皮膚一類的,那我就能夠直接在1.0的基礎上打個龍舟補丁,這樣他就變成了最新的客戶端1.1。若是未來要上別的功能了我就在1.1的基礎上打個補丁,讓客戶端變成1.2。不過這樣也會有他的問題。json
- 順序安裝 在安裝的過程當中只能以此遞增式安裝,我只能1.0 => 1.1 => 1.2;不能1.0 =》 1.2。由於中間是沒有對應的補丁的。 - 流量問題 其實這種解決方案可能會帶來一些問題,好比說,如今端午節,我須要把房子裝飾成龍舟的樣式;而後五一勞動節,我又須要把房子裝修成五一勞動節的樣子。那麼都是關於房子的皮膚,我是沒有辦法都保留的,由於來年的時候確定就不能這麼裝修了,由於過期了太Low了。那麼關於這部分的內容,若是你想一點一點的升級上來對於最後的版原本說是沒用的,你佔用的流量一點用都沒有。太尷尬了。 - 維護的複雜度 由於你不能直接出了一個1.0以後全都是使用補丁,若是當你的版本號遞增到必定程度之後,補丁的大小可能遠遠超過了你從新去下載一個最新的客戶端的大小。因此只能經過時間也好(好比半年或者一個季度)經過意義(好比說大版本號 2.0 3.0)來生成一個完整的客戶端。這樣用戶在下載的時候就能夠找一個最近的完整的客戶端版本號。而後再打補丁的方式來得到最新的客戶端,不過這種維護的複雜度應該也不小。
其實咱們的需求很簡單,獲取最新的客戶端。而後附加要求就是要省流量、下載方便、服務端發佈方便。c#
其實說到省流量,就是能用本地的就直接使用本地。本地實在是沒有的文件,那麼就從網絡上下載。這樣基本上就作到了省流量的效果。服務器
不須要作太多的操做,固然這個不少軟件都作到了這一點。上文中提到的其實也能夠作到自動化,好比說,完整安裝的那麼我就直接下載最新的完整安裝包就行了,若是是打補丁的這種,那麼就下載最新的完整安裝包以及後邊的補丁就行了。其實這個真的要作,對用戶來講應該是沒有感受得。都同樣,不過對於程序員來講。可能面臨的開發就不太同樣了。網絡
其實這個徹底是針對於程序員的了,通常來講,若是這個事情能夠程序來自動完成那麼就確定交給程序了。好比說完整晚裝包的這種,確定可以作到自動打包。打補丁的這種,無非也就是根據上一個版本生成一個補丁。或者再生成一個完整安裝包。上傳到合適的文件服務器就行了。其實打補丁也好,完整安裝包也好,都有一個顯著的優點就是能夠很方便的放到多個服務器上來進行文件的負載均衡。負載均衡
在考慮這個問題的時候,我想到了以前接觸的Cocos2dx 3.9 Lua 自動更新模塊,他是這麼作,經過一個配置文件,來講明最新的客戶端中都包含了那些文件,這些文件的MD5值是什麼,而後網絡路徑是什麼。這樣客戶端拿到這個配置清單的時候,就能夠輕鬆的判斷本地的那些文件是能夠繼續用的。那些文件是過期了的,這樣客戶端經過配置心中的網絡路徑位置獲取最新的對應文件就行了嘛。不過那也是好久以前的事情了,否則,我就不須要本身從新規劃了。直接抄一份代碼就行了嘛。仍是本身整理一套吧。這樣來的更完全一些,想改什麼就改什麼。框架
{ "VersionsCheckCode": "XC09VU4QCRD43LRF01BYOD26D45DWEEKX5KECUKIA7Q4160FKAWQBHXTKE63Z148", "TimeStamp": 1496649771, "ServerUrl": "http://or2dwwrsz.bkt.clouddn.com", "FileInfos": [ { "FilePath": "JumpKick.HttpLib\\packages\\Moq.4.2.1409.1722\\lib\\net40\\Moq.xml", "FileMD5": "c7e9c70a19b84f31e51eb65f4ee38803", "FileUrl": "LV4ZBB_c7e9c70a19b84f31e51eb65f4ee38803" }, { "FilePath": "JumpKick.HttpLib\\packages\\Moq.4.2.1409.1722\\lib\\sl4\\Moq.Silverlight.dll", "FileMD5": "0ee20e7ccba7d6667c48efebe41503ff", "FileUrl": "X057QT_0ee20e7ccba7d6667c48efebe41503ff" }, { "FilePath": "JumpKick.HttpLib\\packages\\Moq.4.2.1409.1722\\lib\\sl4\\Moq.Silverlight.xml", "FileMD5": "c25417228db2dd820f45e93112e8596c", "FileUrl": "S0LO6G_c25417228db2dd820f45e93112e8596c" } ] }
其實嘛整個項目最複雜的地方時這個更新的想法與這個文件的制定。剩下的內容其實就比較簡單了,就是具體的代碼的實現了。代碼方便我就懶得講了,直接把項目的地址扔上來了事。工具
http://git.oschina.net/anxin1225/autoupdateclient.net
http://git.oschina.net/anxin1225/autoupdateserver
省流量、跟其餘軟件結合方便、服務器發佈方便。省流量這個上邊提到了我就說了。
其實很容易理解,就是這個軟件跟被更新的軟件一毛錢關係沒有。因此我能夠直接跑起來就好了,不須要關係具體被更新的軟件是怎麼搞得。最多采用這個的項目。從新改一下咱們這邊的UI就好了。
其實最麻煩的事情就是服務器這邊。須要生成這個配置文件,我這邊服務器端其實並無在運行指的就是生成這個文件的工具。我能夠指定一個目錄。而後生成這個文件,將對應目錄的全部文件導出到一個輸出目錄。不過對於不少CDN不支持多級目錄(好比七牛),因此我將全部的文件都換掉了名字,讓他們儘可能的不重複,程序可讀就好了。
首先使用我寫好的服務端生成對應的配置文件和更名文件。
生成的目錄結構是這樣色的,配置文件放到一個固定的目錄裏邊去。UpLoad文件夾上傳到某一個文件服務器上,這裏我是用的七牛雲
而後把UpLoad目錄中的文件全都上傳上來
上傳完了就是這個樣子的。
致辭服務器就部署好了,等有了新版本重複一遍這個操做就行。其實上傳服務器的這部分工做能夠集成到服務端中。上傳內容就行了嘛,其實很簡單的。固然了,這個我懶。以前也沒有研究七牛的SDK這個能夠做爲一個功能上的擴展,反正項目我已經開源了,感興趣的人能夠本身擴展這部分功能。好吧咱們繼續來講客戶端怎麼弄吧。
AutoUpdateHelper helper = new AutoUpdateHelper(); helper.WebXmlUrl = "http://7xs9hw.com1.z0.glb.clouddn.com/VersionInfo.json"; helper.ConfigXmlPath = "SynchronizeVersions.xml"; helper.TempXmlPath = "SynchronizeVersions_Temp.xml"; helper.FilePath = "Client"; helper.CallBack = obj => { if (obj is Dictionary<UpdateDataType, object>) { var dic = obj as Dictionary<UpdateDataType, object>; foreach (var item in dic) { if (Name2Action.ContainsKey(item.Key)) Name2Action[item.Key](item.Value); } } }; try { helper.Start(); } catch (Exception ex) { MessageBox.Show(ex.Message); }
其實就是一個簡單的設置網址跟配置文件。其實呢這個地方應該吧配置也放到配置文件裏邊去,爲何沒放呢?由於我懶,哈哈哈。
客戶端跑完了就關了,其實應該是跑完了運行某一個具體的文件,而後自動更新的邏輯就完成了,這部分我會以後繼續完善。
這麼樣處理其實下載會變得很靈活。可是也會帶來其餘的問題。好比以前提到的打包的問題。由於服務器只是一個文件服務器,因此服務器並無計算出差別包的能力,因此全部的文件都是一個一個的下載的,這樣就會出現不少小文件的下載。這樣的下載實際上是比較蛋疼的。這是設計上的坑。爲了靈活只能妥協了。
其實到目前爲止我只是實現了最基礎的功能。甚至還不全,好比以後的文件啓動,不過大致的框架已經搭建起來了。至於後邊有不少實現不是很合理的地方,我先簡單列一列,方便以後維護。
雖然這個項目只是一個並不完善的框架。可是這種更新方式應該會讓更新變得更有意思。讓咱們一塊來完善這個框架吧。比較但願作一個成功的開源項目,不忘初心。