Cocos2dx-lua中资源热更新

  项目选择C++ 和 lua 混合, 看中的就是lua代码的热更新优点,想一想以前客户端出现了bug,须要玩家从新下载安装包,这带来的流失率是挺高的; 而随着如今app体积日益增大,动辄几十兆、上百兆的安装包重复下载,对用户体验是很是不友好的;另外appstore的审核也是严格、标准可变的,很容易审核被拒,致使应用的问题没法及时修复。而选择lua作为开发语言,就能作到几乎无感知的修复、增长应用的新功能,对于开发者能够及时修复问题,而对于玩家来讲则能得到更好的游戏体验。从某狐刚推出某耀客户端项目,客户端购买、咨询量激增来看,这个功能仍是颇有吸引力的。服务器

  热更新方案,一开始的设计是单文件更新,思路是:网络

  一、打包的时候利用脚本对所有的资源文件:包含lua脚本、游戏的图片、音频资源生成一份版本文件app

  二、客户端启动的时候从服务器下载版本文件,跟本地的版本文件进行对比,生成更新列表,而后进行更新curl

  上述方案的优点在于:lua

  一、资源服务器只须要存一套资源文件、url

  二、不用考虑客户端版本与服务器版本之间差别过大,致使数据不对等的问题spa

  三、方案实现简单,使用的成本也低,能够实现一些取巧操做(资源服务器直接改某个文件的差别值,让客户端直接更新等)设计

  可是在实际的使用过程当中也发现了该方案存在不足:若是待更新的资源过多,那么就会产生大量的http请求,严重的影响了下载体验,并且单个文件的更新失败,须要一个很是复杂的断点续传的方案来控制总体更新。code

  在这里提一下通常客户端实现的文件下载功能:利用curl库,发起请求进行文件下载。这就会引起两个问题:请求量及请求响应。上述方案的核心点是根据版本文件生成差别列表,而后再单独下载差别列表中的每一个文件,因此每下载一个文件,就会发起一次请求,若是某次更新有上千个文件,那么单个客户端更新所发起的请求量将是巨大的。上千次请求,引起上千次的响应等待,对带宽及玩家的等待时间都将产生巨大的影响!blog

  所以咱们须要新的更新方案:更新是对差别文件进行更新,以前将差别对比放在了客户端处理阶段,那么能够将差别对比放在更新包生成的阶段,将版本间的差别文件提取出来,合并成一个压缩包,客户端直接下载这一个压缩包再解压,实现功能的更新。咱们将这个方案称为差别包更新

  实现这个方案,须要考虑到:

  一、客户端每次只下载一个文件,须要严格保证下载到正确的资源

  二、客户端更新存在版本延时的问题,须要有跨版本的差别包

一、严格保证资源的正确下载

  (1)网络不稳定的处理:

  手机客户端考虑到移动网络的不稳定,容易致使断网、超时的问题。前面提到的单文件更新方案,在更新的过程当中单个文件下载失败,须要一套很是复杂的断点续传方案,才能控制好总体的功能更新,咱们是很是粗鲁的直接从新下载。。。调整到下载压缩包以后,就能够很方便的利用curl库提供的功能,来实现断点续传功能:

curl_easy_setopt(_curl, CURLOPT_RESUME_FROM, localLen)

  核心就是上述代码,CURLOPT_RESUME_FROM, 表示从参数3的位置来写入本地文件,而参数3的值也很容易获取,直接使用引擎的getDataFromFile方法getSize就能拿到当前阶段本地文件的大小。

  (2)差别包更新失败的处理:

  以前的单文件更新方案,假如存在错误,可能也只是单个文件或单独几个文件出现问题,修复比较方便。可是在差别包更新方案中,每次的更新是单个压缩包的更新,就会存在:

  a.压缩包下载失败致使客户端出现重大功能异常

  b.版本与版本之间生成了错误的差别列表致使更新异常

  c.客户端资源版本不统一,如何下载到统一的更新包

  咱们的应对方案是:保留单文件更新功能,在压缩包下载失败时进行单文件更新;采用更可靠的生成文件差别值的方案,由一台设备统一辈子成更新包,针对不一样版本生成不一样的差别包。

二、更可靠的差别生成方案:

  在上面有提到,差别列表生成错误、客户端版本有差别两个问题,在这里具体谈一下采用一套更可靠的差别生成方案:

  (1)差别值的生成:

  在单文件更新方案里,咱们是简单的对文件大小进行MD5处理,获得一个差别值,而后更新对比中对md5值进行对比,生成差别列表。这个方案就有很大的几率出现md5值一致,可是实际却须要更新的状况,所以咱们改用获取文件的修改时间,这样就大大下降了上述状况出现的几率了。

  (2)差别包的生成:

  差别值的获取,差别包的生成, 在这里讲一下思路。这里举个例子说明客户端版本差别:客户端A的当前版本为1, 客户端B的当前版本号为2,此时发布版本3的更新,这个时候客户端A和客户端B的更新列表是存在差别的,该如何处理?在单文件更新方案下,这不存在问题,A和B都是以3的版本文件,在客户端本地直接生成差别列表,去下载对应的文件便可。可是在差别包更新方案中,就须要生成如1-3,2-3这样的版本差别包。并且游戏客户端的更新是比较频繁的,就表示每次更新,所须要的差别包是很是多的,所以考虑到没必要要的工做复杂度提高,须要提出一个基准包的概念。每次进行了底包(玩家从新安装了客户端)更新,底包对应的资源版本就是一个基准的,不管玩家多久不更新,他都有一个基准的包,所以生成差别包的时候,能够针对这个基准包生成一份差别包,这样就能保证功能的正常更新了。所以咱们的差别包就包含了:版本间的差别包,与基准版本的基准差别包。

  咱们控制一个版本跨度,好比5,设定一个基准版本0,假如客户端A的版本号是6,资源服务器的版本号是7,版本跨度是1,在咱们设定的跨度之间,客户端A更新的时候就下载6-7之间的差别包;客户端B的版本号是5,与资源服务器的版本跨度是2,下载5-7的包;客户端C的版本号是1,与资源服务器的版本跨度是6,大于咱们设定的限值了,这个时候就下载0-7的基准差别包。 这样就能保证不一样版本的客户端,也能下载到统一的更新资源。

  解决了上述问题,咱们实现的差别包更新方案,在实际的体验中,就是一个字:快!在带宽一致的状况下,大概算了一下,以前须要10s才能完成的更新,如今只要1s不到的时间就能下载好,再根据设备配置的差别存在必定的解压时间,可是总时间是小于以前那个方案的。这个方案不涉及到引擎相关(最多就是用引擎的接口拿获取文件大小),所以能够加入到使用到了热更新方案的不一样开发项目中去。

相关文章
相关标签/搜索