摘 要:针对桌面应用程序在发布之后版本难以维护的问题, 提出了基于http协议的解决方案,并对该解决方案进行了深入研究。提取出通用的自动更新平台,对解决版本维护难题有一定的参考意义。
关键词:自动升级;更新平台;网络更新
1 问题的提出
随着桌面应用程序新版本的不断发布,客户端运行的版本也越来越杂,版本、数据结构的兼容也成为后续开发必须考虑的问题,而且兼容性方面的问题越来越多,开发及维护成本越来越高。
2 问题的分析
随着因特网的普及,通过网络来实现桌面应用程序的更新升级已经成为可能。在程序中加入在线更新的功能将能有效地解决前面讨论的版本维护难题。
关于通信协议,可以编写程序实现socket通信,也可以采用比较成熟的http协议。考虑到诸多因素,笔者选择了http协议。
3 http协议特点
http协议(超文本传输协议)的主要特点可概括如下:
(1)简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有get、head、post。每种方法规定了客户与服务器联系的类型不同。
(2)由于http协议简单,使得http服务器的程序规模小,因而通信速度很快。
(3)灵活:http允许传输任意类型的数据对象。正在传输的类型由content-type加以标记。
(4)无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
(5)无状态:http协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
另外,笔者在实验中发现很多网络都设置了防火墙,考虑到安全问题,网络管理员会屏蔽很多端口。而对于http最常用的80端口通常是开放的,这也是笔者选择http协议的一个重要因素。
4 数据流程及数据结构
实际应用中可以对流程进行扩展,例如自动程序线程定时启动、开始更新前检查上次留下的缓存、断点续传等。
该平台中有多个软件产品,存储在u_products表中。每个软件产品有多个用于客户端验证的序列号,存储在u_clients。序列号是客户端的凭证,只有授权了的序列号才能访问平台。而且序列号表还标出了该序列号允许升级的版本范围。同时,每个软件产品对应的多个文件,通过服务端脚本输出一个文件列表。客户端连接上服务器后首先要做的就是下载属于它的文件列表。
文件列表用于比较客户端文件与服务器上的各个文件的新旧。其中的时间戳是主要比较字段,文件名用于记录定位。
5 客户端工作流程
需要指出的是表1列出的是基本的流程。实际中客户端工作流程会比表1复杂的多。
主程序启动之后,创建自动升级程序的线程。该线程在后台运行,首先读出产品的序列号,通过url参数传值的形式传到web端。此处传值可以更加灵活,可以在用户允许的前提下,将更多的信息传给服务器。例如当前软件版本,客户端操作系统版本,客户端计算机硬件信息等等。
运行在web端的脚本响应请求,判断序列号是否合法,即序列号是否正确,是否过期。通过之后输出与该序列号对应的软件的所有文件列表。
自动升级程序开始通过http协议下载这个列表。下载完毕后读出上一次升级之后,保存下来的文件列表,并与下载下来的列表进行对比,通过时间戳对比找出新文件。通常只要时间戳不一样就将文件加入的需要下载的文件列表中,也可以采用时间戳转成浮点数后大小对比的策略。例如平台中放的是稳定的正式版,而有些客户端已经通过其他途径得到新版本更高的测试版。第二种策略就可以避免高版本文件通过升级之后版本降低。这也是为什么采用时间戳,而不是文件md5唯一哈希值的原因。
得到新文件列表之后,再次通过http协议逐一下载新文件到缓存目录中。下载新文件的url由文件编号和序列号共同确定。每下载一个文件,更新一次本地的文件列表。这样如果出现网络中断,用户退出等异常,下次启动可以跳过已经下载过的文件。虽然这不是严格意义上的断点续传,但在一定程度上提高了程序的容错能力。
数据全部下载完毕之后询问用户是否立即应用更新。如果是则退出主程序,将缓存文件夹中的文件移动到主程序所在的目录中,并覆盖。否则保持缓存中的文件,供下次升级使用。
6 改进及结束语
网络状况很差的时候更新所需要的时间很长。对于该问题,可以对文件进行逐个zip压缩,通过http协议传输压缩流,而不是文件本身的数据流。客户端下载之后进行解压缩。此处是对文件逐个压缩,而不是整体打包。因为整体打包之后会出现客户端只需要更新一个文件而不得不下载整个压缩包的情况。而且整体打包也对断点续传提出了更高的要求。
另外出于某种原因的考虑,有时需要更多考虑数据安全。例如未授权的序列号不能获得新版本的文件,且一个序列号只能对应一个客户端。对此可以采用动态序列号的方式,即下载完文件列表时或更新结束时,都将原有的序列号作废,动态创建一个新的值。
另外对于重大缺陷的修复更新,更希望能强制更新。对此可以在自动更新程序发现更新时,强制停止主程序的响应。通过这一策略甚至可以做到所有的新版本发布之后,客户端迅速跟进,并全部更新到最新版本。
笔者使用微软的c#语言来实现,经过反复测试,发现zip压缩之后,对网络要求低了很多,更新效率提高很多。通过动态序列号及强制更新策略也基本能保证客户端版本可控。
参考文献
[1].数据库系统导论[m].北京:机械工业出版社,2000.
[2]殷人昆.数据结构(用面向对象方法与c++描述)[m].北京:清华大学出版社,1999.
[3]莫勇腾.深入浅出设计模式(c#/java版)[m].北京:清华大学出版社,2006.
本文链接:http://www.qk112.com/lwfw/jsjlw/xinxiguanli/259690.html