关于客户端Launcher的设计和实现的一些思路

本文由@苍月未离 出品,转载请注明出处。
文章链接: http://blog.csdn.net/u014511876/article/details/78901370

近期因为公司的产品需要一个Launcher来实现更新版本,写了一段时间算是完工了,但是其中也发现了不少的问题,在此把实现思路和一些在开发过程中遇到的一些问题写出来,有需要的朋友可以用于参考。

PS:由于是公司的项目,此篇文章主要讲一个实现的思路和开发过程中遇到的问题,不会涉及到源代码。

大致流程

先大致的介绍一下更新的流程和实现思路,在后面会详细的进行讨论。

  1. 要实现更新客户端,首先需要一个下载最新客户端的地方,也就是首先需要把最新的客户端文件放在服务器上或者云储存上,并对外提供下载链接。

  2. 有了下载链接后,那么下一步就是确定哪些文件需要被更新,检索出新增文件,被改动的文件,被移除的文件,然后确定需要更新的文件列表。

  3. 确定了哪些文件需要更新后,就是下载的过程了,把需要更新文件下载覆盖原来的文件。

以上是更新的大致流程,虽然看起来流程十分简单,但是要实现起来还是有十分多的细节要注意。

提供客户端下载链接

关于最新客户端放在服务器或者云储存上的问题,如果公司本身有服务器的,可以放在公司服务器上,也可以选择现在市面上比较成熟的云储存提供商,如阿里云,腾讯云,七牛云等,在此不过多赘述。

检测版本

接下来为了检测是否需要被更新,需要获取最新的客户端版本号,和当前的版本号进行对比,若发现版本号不一致即为需要更新。

关于如何获取最新版本号的方法,不了解Socket通信的朋友,如果公司没有后端开发,这一步对你来可能就有些困难了,你或许需要从服务端的搭建开始了解,如果有后端的话,可以让后端提供获取数据的接口,通过相应的协议和URL调用API即可,虽然也需要了解一定的网络通信,但是无疑比从服务端开始搭建容易太多了,况且几乎每种语言都有相应的Socket库,只需要了解库的用法即可,本篇主要讲Launcher的实现,所以在此不专门讨论。

关于获取当前客户端的版本号,方法有很多,比如说创建一个专门用于储存版本号的version.ini文件,也可以修改客户端执行程序的版本号属性,具体采用哪种方法,可以根据你的喜好而定。

检测客户端进程

更新前,需要对客户端进程进行检测,因为客户端如果在启动中,会造成文件被占用无法更新的情况,所以需要先检测当前进程中是否存在客户端进程,提示用户关闭客户端后再进行更新。

检索需更新文件

确认了版本差异后,就需要检索出哪些文件需要更新,比较普遍的方法是每个版本都制作一份文件对照表,
文件对照表中记录着每个文件的相对路径和文件名,以及文件特征码等信息,文件特征码可以采用目前使用比较广泛MD5。

所以在此之前,需要先开发一个文件对照表的程序,遍历客户端的所有文件,生成对应相对文件名和文件特征码的表格,再把文件对照表数据上传到数据库中,每一个版本都需要生成一份对应的文件对照表。

由后端提供接口,通过查询版本号的方式获取当前和最新的文件对照表,进行相对路径和文件名以及特征码差异对比,检索出新增文件,被改动的文件,被移除的文件,其中新增文件和被改动文件就是需要更新下载的部分,被移除的文件直接删除即可。

PS:其中这里有些朋友可能会有些疑问,觉得获取当前文件对照表是否太过于麻烦了,直接获取当前客户端的路径,对文件进行遍历检索不行吗?虽然说这种方法的确是可行的,但是却有着很大的风险,如果用户把客户端目录放在了某个驱动器的根目录,那么如果使用这种方法,就会自动把整个驱动器的文件当做客户端文件进行检索,其结果就会是直接删除掉整个驱动器的其余文件,只留下客户端文件,不得不说这是相当可怕的事情。

下载需更新文件

首先下载的话需要获取到下载文件的URL,在文件对照表中,可以记录下载用服务器域名,整体文件的下载URL则为下载用服务器域名+文件相对路径及文件名。

下载文件的方法有很多,也有不少成熟且开源的文件下载库,下面简单介绍一下我的下载方式。

下载器主体采用HTTP协议请求传输文件,由于项目的客户端文件体积比较大,所以提高下载速度和实现断点续传是必要的,若想支持断点续传,首先需要服务器支持Range请求头,如果是使用其他平台的云储存服务一般都是支持的。

要提高下载速度,就需要使用多线程下载,这里我是同时下载5个文件,小于1M的文件使用单线程下载,大于1M的文件使用多线程,我这边是每个文件开辟了十个线程,每个线程请求<文件长度/总线程数>的范围 ,每个线程把请求到的数据缓存到一个大小为10240的Byte数组中,储存满了或者传输完毕后,就把文件指针Seek到相应位置,写入文件流数据。

PS:惭愧的是一开始对服务器的接受请求和防御IP攻击的机制并不熟悉,采用了不断开辟线程请求Range为10240范围的内容的方式,进行大量的请求,发生了服务器误认为是IP攻击的乌龙。

若要支持断点续传。那么就需要实时更新已下载并写入文件中的数据信息,记录哪些文件已经下载完毕,哪些文件是正在下载的,并且正在下载的文件哪些部分已经下载好了,下次重新下载的时候只需要从未下载完成的部分开始即可。

文件完整性校验

在整体更新完成后,一般需要进行一个文件完整性校验,即为根据文件对照表中的信息,遍历表中文件,校验文件特征码是否匹配,此项检测通过后即可启动客户端。

关于Launcher的自更新

根据需求的不同,有些Launcher除了用于更新外,还肩负着展示产品信息的任务,所以有的时候会有对Launcher进行更新的要求,让Launcher在程序内自更新是不大现实的,因为会有文件占用问题,所以会需要一个外置的更新程序。

Launcher的自更新方式用的比较多的是额外带有一个Update执行程序,这个执行程序的功能和Launcher有些相似,整体流程也可以参照Launcher的更新机制,只是一个的作用是用于更新客户端,Update的作用是用于更新Launcher,若Update程序需要更新,可以由Launcher完成。

需要注意的是,Launcher的更新方式和客户端还是有一些区别的,客户端一般整体比较大,而且由Launcher进行更新和启动,所以用户首先会启动Launcher再启动客户端,所以客户端的更新是可以直接删除和覆盖原有文件的,但是Launcher作为入口,如果采用直接删除覆盖的方式,如果Update在更新过程中因为意外关闭, 那么将会造成Launcher文件缺失无法打开的情况,所以Update对Launcher的更新可以先把需要更新的文件下载到一个Temp文件夹内,下载完毕后再把Temp文件夹中的文件覆盖原有文件,最后删除需要移除的文件,这样可以把意外发生率降到最低。

这里我采用了一个比较取巧的方法,由于Update程序本身的体积比较小,所以我在Launcher检测到自身版本需要更新后,直接从服务器下载最新的Update程序,完成自更新后删除。

更新的整体流程大约为:

  1. 检测版本需要更新。
  2. 下载最新的Update程序并关闭Launcher。
  3. Update程序完成更新后,打开Launcher并关闭自身。
  4. Launcher检测版本为最新版后,删除残留的Update程序。
整体的更新流程图

Launcher更新流程图

The end.

如有出错还望指正。
若有更好的建议,可以在评论里留言讨论。

黑暗之魂3
图片来自《黑暗之魂3》。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值