<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>lujiajing1126 (小灰灰)</title>
    <link>https://ruby-china.org/lujiajing1126</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>HybridApp 增量更新方案附赠服务器 cli-gem 等干货</title>
      <description>&lt;p&gt;第一次发帖= =喵&lt;/p&gt;

&lt;p&gt;今年早些时候就想过做一些 HybridApp 方面的尝试，我认为 HybridApp 的优势有以下两点&lt;/p&gt;

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

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

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

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

&lt;ul&gt;
&lt;li&gt;缓存问题&lt;/li&gt;
&lt;li&gt;增量更新问题&lt;/li&gt;
&lt;li&gt;客户端 App 向 WebView/UIWebview 注入 JS 问题&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;这篇重点介绍我们在增量更新方面的解决方案，求轻喷 TAT（其他的大家有兴趣我再整理下= =）：&lt;/p&gt;
&lt;h2 id="首先是增量更新的方案"&gt;首先是增量更新的方案&lt;/h2&gt;
&lt;p&gt;我们看了 InfoQ 上面腾讯前端团队在 AndroidQQ 上的解决方案的介绍，发现他们的方案不太适合我们&lt;/p&gt;

&lt;p&gt;给出 Keynote 链接 &lt;code&gt;http://vdisk.weibo.com/s/A0GI9rXObukZ&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;跪谢 Rehorn 大神的 keynote，启发了我们&lt;/p&gt;

&lt;p&gt;腾讯：&lt;/p&gt;

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

&lt;p&gt;LCS 算法详见：&lt;code&gt;http://en.wikipedia.org/wiki/Longest_common_subsequence_problem&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;WHOSV：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;使用单个文件全量更新的方案，对文件列表中的单个文件比较&lt;code&gt;md5&lt;/code&gt;或者&lt;code&gt;sha1&lt;/code&gt;摘要进行比较&lt;/li&gt;
&lt;li&gt;利用 nginx 自带的 gzip 压缩，不需要改变之前的发布流程，可以混淆！可以压缩 JS！&lt;/li&gt;
&lt;/ul&gt;

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

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

&lt;p&gt;以上就是安全方面的整个信任链&lt;/p&gt;

&lt;p&gt;当然土豪公司完全可以利用 Https 证书来完成信任链的建立&lt;/p&gt;

&lt;p&gt;有一篇文章讲的比较好：除了翻译有些问题&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTTPS 连接的前几毫秒发生了什么&lt;/strong&gt;
&lt;code&gt;http://blog.jobbole.com/48369/&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="然后我们为服务器端发布写了一个Gem"&gt;然后我们为服务器端发布写了一个 Gem&lt;/h2&gt;
&lt;p&gt;用 Gli 写的一个命令行工具，目前还不是特别完善= =其实&lt;/p&gt;

&lt;p&gt;用于&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;创建 RSA 密钥对&lt;/li&gt;
&lt;li&gt;生成站点下某个模块站点的所有文件列表&lt;/li&gt;
&lt;li&gt;对文件列表进行生成摘要，并进行 RSA 签名&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;地址： &lt;code&gt;https://github.com/lujiajing1126/genRelease&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;具体用法&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// 目录结构
// &lt;span class="nt"&gt;-public&lt;/span&gt;
// n someModule
// n otherModule
&lt;span class="nb"&gt;cd &lt;/span&gt;public
gem &lt;span class="nb"&gt;install &lt;/span&gt;genRelease
// 在当前目录生成RSA密钥对
genRelease create
// 对当前目录下某个模块生成文件列表
genRelease &lt;span class="nt"&gt;--verbose&lt;/span&gt; build &lt;span class="nt"&gt;--host-name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;www.yoursite.com someModule
// 签名
genRelease sign
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其他的部分，比如说 Webview 注入之后，网页部分调用原生部分，我们写了一个框架，有点类似 Weixin 的 API 恩&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://github.com/lujiajing1126/WhosvBrowserJSBridge&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;就说这么多，感觉好弱。。= =写实验报告去了囧&lt;/p&gt;</description>
      <author>lujiajing1126</author>
      <pubDate>Wed, 17 Dec 2014 20:57:00 +0800</pubDate>
      <link>https://ruby-china.org/topics/23258</link>
      <guid>https://ruby-china.org/topics/23258</guid>
    </item>
  </channel>
</rss>
