Gem HybridApp 增量更新方案附赠服务器 cli-gem 等干货

lujiajing1126 · 2014年12月17日 · 最后由 lujiajing1126 回复于 2014年12月18日 · 4487 次阅读

第一次发帖= =喵

今年早些时候就想过做一些 HybridApp 方面的尝试,我认为 HybridApp 的优势有以下两点

  • 对于初创公司,手机 Web,iOS,安卓可以使用统一的 H5 提供的界面,减少开发成本
  • 更新及时,服务器端更新,客户端不管新旧版本能够立即看到效果,尤其对于 iOS 漫长的审核周期,再也不用被老板天天盯着了

但是混合型的应用也往往因为工程师水平有限或者 H5/CSS3 兼容或者特效不流畅,以及最重要的浪费流量而饱受诟病

之前因为一些原因一直心里想着然后没时间去实现,最近在我们的应用( 奢圈WHOSV )里面用了 HybridApp 构架,发现还是非常爽的,打个广告大家可以搜一下我们的 APP 啦啦啦~

之所以称之为构架,因为我们在多方面做了很多联合的解决方案,在这过程中我们发现有几个问题是需要重点考虑

  • 缓存问题
  • 增量更新问题
  • 客户端 App 向 WebView/UIWebview 注入 JS 问题
  • ...

反正是各种坑= =。。所以感觉之前的决定也是对的。。没有时间精力千万不要去轻易尝试。。

这篇重点介绍我们在增量更新方面的解决方案,求轻喷 TAT(其他的大家有兴趣我再整理下= =):

首先是增量更新的方案

我们看了 InfoQ 上面腾讯前端团队在 AndroidQQ 上的解决方案的介绍,发现他们的方案不太适合我们

给出 Keynote 链接 http://vdisk.weibo.com/s/A0GI9rXObukZ

跪谢 Rehorn 大神的 keynote,启发了我们

腾讯:

  • 使用 bsdiff 和 bspatch 作为增量更新的比较和打包工具,需要在安卓,iOS 都加入 Native 支持,虽然就俩文件,但也比较烦
  • 使用 zip 需要每个版本做比较,在版本更新方面可能需要下载多个 zip 包覆盖才行,对于服务器端发布流程和构架需要做比较大的改动,不方便!
  • zip 包不能压缩,只能使用打包模式,这个是由于bsdiff使用LCS算法带来的问题,另外 js 文件 minify 也有可能带来增量包变大的问题

LCS 算法详见:http://en.wikipedia.org/wiki/Longest_common_subsequence_problem

WHOSV:

  • 使用单个文件全量更新的方案,对文件列表中的单个文件比较md5或者sha1摘要进行比较
  • 利用 nginx 自带的 gzip 压缩,不需要改变之前的发布流程,可以混淆!可以压缩 JS!

在安全方面我们参考 Debian 更新软件包时提出的 Secure Apt 方案,我们提出基于 HTTP 的方案 https://wiki.debian.org/SecureApt 当然 Debian 是基于Gnugpg的实现,我们换成只用 RSA

  1. 首先,客户端在发布时有一枚 RSA 的公钥,并且把网页的模块打包在 apk(ipa) 中
  2. 当触发更新时,客户端向服务器端请求 Release.rsa 文件和 Release 文件,其中 Release.rsa 文件是用 RSA 私钥加密的 Release 文件
  3. 客户端利用公钥解密 Release.rsa 并且与 Release 的文件内容验证,用于校验服务器的可信以及 Release 文件可信
  4. 客户端下载 Packages 文件,里面存了某个 site 下,某个 modules 的全部内容:www.site.com/module/Packages
  5. 利用得到的 Release 中对 Packages 文件的摘要,验证 Packages 文件的可信
  6. 与旧版本额 Packages 作比较,增量下载改动的文件,一般就是几个 JS,CSS,可能就几个 KB 大小,经过 Gzip 能更小,覆盖

以上就是安全方面的整个信任链

当然土豪公司完全可以利用 Https 证书来完成信任链的建立

有一篇文章讲的比较好:除了翻译有些问题

HTTPS 连接的前几毫秒发生了什么 http://blog.jobbole.com/48369/

然后我们为服务器端发布写了一个 Gem

用 Gli 写的一个命令行工具,目前还不是特别完善= =其实

用于

  • 创建 RSA 密钥对
  • 生成站点下某个模块站点的所有文件列表
  • 对文件列表进行生成摘要,并进行 RSA 签名

地址: https://github.com/lujiajing1126/genRelease

具体用法

// 目录结构
// -public
// n someModule
// n otherModule
cd public
gem install genRelease
// 在当前目录生成RSA密钥对
genRelease create
// 对当前目录下某个模块生成文件列表
genRelease --verbose build --host-name=www.yoursite.com someModule
// 签名
genRelease sign

其他的部分,比如说 Webview 注入之后,网页部分调用原生部分,我们写了一个框架,有点类似 Weixin 的 API 恩

https://github.com/lujiajing1126/WhosvBrowserJSBridge

就说这么多,感觉好弱。。= =写实验报告去了囧

不错。

“以及打包在 Apk 中网站”,貌似有 typo

#1 楼 @appell 谢谢~的确是写错了囧,已经改正了啦

  1. 递归 rsa 对很难么?
  2. Webview 注入很难么?

没有从根本上解决动态更新的问题

#3 楼 @i5ting 我从来没说这些很难啊?技术本来就没有什么很难很简单。。我只是说一种解决方案而已。。 那请教一下根本问题是什么? 还有不是递归 rsa,你可以仔细看一下 apt 的源

#4 楼 @lujiajing1126 增量更新,是本地缓存阿,现在你提供的只是同步校验,而且增量的增量没有表现出来的

增量更新,比如游戏关卡,lua,mruby,当然你说的这个 h5 也是一个

#5 楼 @i5ting 基于 Webview 的话用 Webview 的几个回调函数去拦截 Request,那一部分是没有提及的 我这边的增量是指基于文件列表的单个文件增量,安卓 QQ 的方式是某个网站模块打包增量,两种不同的方式 只是一种方案,不知道你说的增量是什么定义?

需要 登录 后方可回复, 如果你还没有账号请 注册新账号