【原创】我所理解的自动更新-客户端更新流程

创建更新线程,跟ui主线程通过message进行交互。
1,去http://version.mygame.com/check.php? channelid=%d&appver=%d&resver=%d获取客户端最新版本信息。用curl获取,代码如下,至于curl的具体参数,man或者搜索引擎会告诉你答案

 1 static size_t funcGetHttpText(void *ptr, size_t size, size_t nmemb, void *userdata) {
 2     size_t retSize = size*nmemb;
 3     string* pContent = (string*)userdata;
 4     if (pContent) {
 5         pContent->append((char*)ptr, retSize);
 6     }    return retSize;
 7 }
 8 CURLcode getHttpText(const string& strUrl, string& strHttpText) {
 9     CURL* pCurl = curl_easy_init();
10     if (!pCurl) {
11         return CURL_LAST;
12     }
13     strHttpText.clear();
14     curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, 30);
15     curl_easy_setopt(pCurl, CURLOPT_NOSIGNAL, 1);
16     curl_easy_setopt(pCurl, CURLOPT_FORBID_REUSE, 1);
17     curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0L);
18     curl_easy_setopt(pCurl, CURLOPT_URL, strUrl.c_str());
19     curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, funcGetHttpText);
20     curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, &strHttpText);
21     CURLcode err = curl_easy_perform(pCurl);
22     if (err == CURLE_OK) {
23         int sz = 0;
24         curl_easy_getinfo(pCurl, CURLINFO_HTTP_CODE, &sz);
25         if ((sz != 200) && (sz != 206)) {
26             //ok or not modify
27             err = CURL_LAST;
28         }
29     }
30     curl_easy_cleanup(pCurl);
31     return err;
32 }

解析返回的字符串。
1:大版本更新,弹出对话框,提示需要进行大版本更新,用户可以选择”更新”,”取消”。取消后就退出app,点击更新,进入下面流程。
Android:通过返回的url下载相应的apk,并进行重装(重装只针对app,不会重置资源),
Ios: AdHoc,通过代码打开url的方式进行更新。代码如下

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms-services://?action=download-manifest&url==https://raw.githubusercontent.com/xxxxxhttp.plist"]];

AppStore:则打开AppStore的app进行更新,代码如下

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@" http://itunes.apple.com/gb/app/yin/idxxxxxxxx?mt=8 "]];

此时会跳出当前应用,跳转到appstore的应用详情页。
2:本地资源版本号为0,下载初始包。3:本地资源版本>0,则下载差异包
判断本地已下载的临时文件大小和外网文件的大小是否相同,如果不相同,则断点下载外网文件。Curl支持断点下载,代码如下

1 char rangBuf[32] = { 0 };
2 sprintf(rangBuf, "%d-", nRangeFrom);
3 curl_easy_setopt(pCurl, CURLOPT_RANGE, rangBuf);

另外,下载需要判断3g环境的问题,如果在3g环境下,下载的文件超过一定大小(比如30M),则提示玩家是否下载,玩家自行选择是否下载。因为我们下载模块是多线程的,主线程和多线程通过mutex进行通信。
下载线程:

 1 while (1) {
 2    this_thread::sleep_for(chrono::milliseconds(50));
 3    std::unique_lock<std::mutex> locker(m_mtxConfirm);
 4    if (m_eUpdateConfirm == UpdateImplConfirm::UPDATE_UNKNOW) {
 5        this_thread::yield();
 6    } else {
 7       break;
 8    }
 9 }
10 if (m_eUpdateConfirm == UpdateImplConfirm::UPDATE_REJECT) { //拒绝更新
11     postMessage(new UserRejectMessage(UpdateState::eUpdateStateDownloadFile));
12     m_eUpdateConfirm = UpdateImplConfirm::UPDATE_UNKNOW;
13     return CURL_LAST;
14  }

UI:

1 void ConfirmContinue() {
2     std::lock_guard<std::mutex> autoLock(m_mtxConfirm);
3     m_eUpdateConfirm = UpdateImplConfirm::UPDATE_CONTINUE;
4 }
5 void ConfirmReject() {
6     std::lock_guard<std::mutex> autoLock(m_mtxConfirm);
7     m_eUpdateConfirm = UpdateImplConfirm::UPDATE_REJECT;
8 }

下载完成后,文件大小和md5进行比较,如果不同。。。则删除文件,重新下载。
比较成功后,解压文件到writable目录,读取index文件进行数据解析,将追加的文件,覆盖的文件拷贝到资源目录进行覆盖,删除文件的,则把资源目录的相应文件进行删除。检查资源,遍历本地资源文件进行md5对比,如果不相同,则去外网下载散文件进行覆盖。清理临时目录,删除index文件。资源更新完成。
4. 资源版本大于0,并且跟服务器资源版本匹配,无需更新。
Other,出错【服务器timeout,返回错误,==】,显示“重试”按钮可重试。

【原创】我所理解的自动更新-概要
【原创】我所理解的自动更新-环境搭建和协议制定
【原创】我所理解的自动更新-外网web服务器配置
【原创】我所理解的自动更新-APP发布与后台发布
【原创】我所理解的自动更新-资源打包流程
【原创】我所理解的自动更新-客户端更新流程
【原创】我所理解的自动更新-知识点讲解

本文中的服务器用的是linode,linode是啥就不需要过多介绍了吧。
有兴趣的童鞋可以通过https://www.linode.com/?r=000161937771838e320f2bda5fef0dbad54ad86c注册服务器,
r后面的数字是我的推荐码,如果你用了以上我推荐的推荐码,并且保持3个月是在线帐号,那么我将在三个月后得到20美元的信用,
这样也就是可以多用一个月最低档19.95美元的linode vps。
Referrals reward you when you refer people to Linode.
If someone signs up using your referral code,
you‘ll receive a credit of $20.00, so long as the person you referred remains an active customer for 90 days。

时间: 2024-10-18 17:39:21

【原创】我所理解的自动更新-客户端更新流程的相关文章

【原创】我所理解的自动更新-APP发布与后台发布

发布后台 创建渠道:添加新的渠道,设置渠道名称,自动生成渠道id.    查看渠道:查看渠道基本信息,渠道app版本号,资源版本号,是否开启更新.    创建/更新APP:选择打包ios,android版本,设置渠道所属,设置版本日志,发送消息到APP Publish并等待反馈.    创建/更新资源:设置渠道所属,设置版本日志,发送消息到ResPackageTool并等待反馈. APP打包发布 从VersionServer里获取相应渠道的代码,保存到目录[channel-渠道号-版本号]. 

【原创】我所理解的自动更新-资源打包流程

参数提供资源号(资源版本号),渠道号,目标目录(存放新资源包和差异包)    预处理:从VersionServer里获取相应渠道的资源,保存到目录[channel-渠道号-资源版本号]标记为NEW,遍历NEW目录里的文件并计算文件校验码(MD5之类)标记为NEWTAG_MAP,生成index文件保存文件和校验码的组合,压缩新资源+index文件并保存到目标目录.    差异包生成:从版本号1开始遍历直到新版本号-1.标记为目录OLDVER,遍历OLDVER目录里的文件并计算文件校验码标记为OLD

【原创】我所理解的自动更新-知识点讲解

itms-services协议可以通过safari,chrome等浏览器直接在IOS设备上安装应用程序.适用于安装企业签名或者已绑定设备id的测试签名的IPA.itms-services协议需要的文件有:一个ipa文件,一个plist文件,一个html文件和一个图片文件.其中,最主要的,就是plist文件. 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE plist PUBLIC "

【原创】我所理解的自动更新-外网web服务器配置

ClientDownload和ClientUpdate共享渠道配置信息: channel-0.php //以appstore的渠道为例 1 <?php 2 define('APPNAME', 'TOKENAPPNAME');//应用版本号 3 define('SERVER_MAJOR_VERSION', 'TOKENMAJORVER');//最新应用版本号 4 define('SERVER_MAJOR_VERSION_TXT', 'TOKENMAJORTXT');//最新应用版本描述 5 def

【原创】我所理解的自动更新-概要

概述    一般来说,游戏在开发完成后会通过渠道分发至玩家的手机上.这也就涉及到游戏的下载,安装.但是游戏还有一个重要的步骤,更新.对于手游而言,更新分为大版本更新和当前内容更新(大版本更新也会包含当前内容更新).大版本更新需要开发商重新提交游戏安装包,玩家重新下载安装包安装.而当前内容更新更多的是指更新脚本/资源等.那么问题来了,就技术而言,游戏通过什么方式下载安装?内容通过什么方式更新?恰好刚完成某手游的下载更新模块,就自己的理解,和大家聊聊游戏更新的那些事儿. 本文适用人群 本文档适用于自

【原创】我所理解的自动更新-环境搭建和协议制定

环境搭建: Linux:ubuntu安装,我用的是linode的vps,可选择ubuntu14.04 LTS创建.自建服务器的,自行安装. Linux:安装LNMP,从http://lnmp.org/download.html页面下载最新的安装包,参考http://lnmp.org/install.html进行安装.之所以使用lnmp一键安装包是因为我们的重点是搭建一套可行的linux-nginx,mysql-php的运行环境,对于咱们的更新流程中,这部分的性能,并没那么重要. Linux:安装

Microsoft Update客户端更新

?? 大家好, 微软Microsoft Update产品组官方博客于昨天宣布了有关最新的Windows Update客户端更新的消息.根据这则博客,微软从当日开始逐渐向所有Windows 7, Windows Server 2008, Windows 8, Windows RT和Windows Server 2012用户推送新的Microsoft Update和Windows Update客户端.此项客户端更新的主要目的是加强MU/WU客户端的安全性,以及使MU/WU客户端与服务器的通讯更为安全

winform_使用ClickOnce生成安装程序包页面&amp;程序发布新版本通知客户端更新

好久不用winform了,一用就遇到一些问题,不过好在咱有知识沉淀的好习惯,这里做下记录,网上也有很多关于clickonce的这方面的文章,我这里仅仅只是为了加深印象,做下记录. 对于安装程序包,本人已经写过几篇文章: VS2017中使用组合项目_windows服务+winform管理_项目发布_测试服务器部署 VS2017.VS2019没有Setup安装项目(Visual Studio Installer)_解决方案 这里主要对通知客户端自动更新做下介绍,其实关于该需求还是老大提出的要求,个人

通过总线机制实现自动刷新客户端配置(Consul,Spring Cloud Config,Spring Cloud Bus)

通过总线机制实现自动刷新客户端配置 方案示意图 利用Git服务的webhook通知功能,在每次更新配置之后,Git服务器会用POST方式调用配置中心的/actuator/bus-refresh接口,配置中心的总线服务会将此事件广播给加入总线的所有客户端,客户端收到事件后会从新读取配置中心的内容. 增加POM依赖 配置中心的服务端(spring-cloud-config-server)和客户端(spring-cloud-config-client)都加入Spring Cloud Bus引用包: <