【原創】我所理解的自動更新-客戶端更新流程

建立更新線程,跟ui主線程經過message進行交互。
1,去http://version.mygame.com/check.php? channelid=%d&appver=%d&resver=%d獲取客戶端最新版本信息。用curl獲取,代碼以下,至於curl的具體參數,man或者搜索引擎會告訴你答案php

 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的方式進行更新。代碼以下html

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

AppStore:則打開AppStore的app進行更新,代碼以下git

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

此時會跳出當前應用,跳轉到appstore的應用詳情頁。
2:本地資源版本號爲0,下載初始包。3:本地資源版本>0,則下載差別包
判斷本地已下載的臨時文件大小和外網文件的大小是否相同,若是不相同,則斷點下載外網文件。Curl支持斷點下載,代碼以下github

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

另外,下載須要判斷3g環境的問題,若是在3g環境下,下載的文件超過必定大小(好比30M),則提示玩家是否下載,玩家自行選擇是否下載。由於咱們下載模塊是多線程的,主線程和多線程經過mutex進行通訊。
下載線程:web

 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發佈與後臺發佈
【原創】我所理解的自動更新-資源打包流程
【原創】我所理解的自動更新-客戶端更新流程
【原創】我所理解的自動更新-知識點講解app

相關文章
相關標籤/搜索