由于转战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); }
其实就是一个简单的设置网址跟配置文件。其实呢这个地方应该吧配置也放到配置文件里边去,为何没放呢?由于我懒,哈哈哈。
客户端跑完了就关了,其实应该是跑完了运行某一个具体的文件,而后自动更新的逻辑就完成了,这部分我会以后继续完善。
这么样处理其实下载会变得很灵活。可是也会带来其余的问题。好比以前提到的打包的问题。由于服务器只是一个文件服务器,因此服务器并无计算出差别包的能力,因此全部的文件都是一个一个的下载的,这样就会出现不少小文件的下载。这样的下载实际上是比较蛋疼的。这是设计上的坑。为了灵活只能妥协了。
其实到目前为止我只是实现了最基础的功能。甚至还不全,好比以后的文件启动,不过大致的框架已经搭建起来了。至于后边有不少实现不是很合理的地方,我先简单列一列,方便以后维护。
虽然这个项目只是一个并不完善的框架。可是这种更新方式应该会让更新变得更有意思。让咱们一块来完善这个框架吧。比较但愿作一个成功的开源项目,不忘初心。