多終端數據同步機制設計(二) Intro 如果您沒有看上一篇文章,建議您先移步到這裡查看第一部分 上一次主要解決了基本的數據增量同步的問題,但仍然存在一些問題。 可能存在的主要問題: 針對以上可能出現的這兩個問題,需要對數據進行校驗並且數據量超過一定量時進行分批量傳輸, 本文將著手解決 數據校驗 和 ...
多終端數據同步機制設計(二)
Intro
如果您沒有看上一篇文章,建議您先移步到這裡查看第一部分 上一次主要解決了基本的數據增量同步的問題,但仍然存在一些問題。 可能存在的主要問題:
- 大數據量傳輸時,數據在傳輸過程出現部分丟失,數據不完整
- 超大數據量需要同步,導致響應時間過長而導致連接超時
針對以上可能出現的這兩個問題,需要對數據進行校驗並且數據量超過一定量時進行分批量傳輸, 本文將著手解決 數據校驗 和 數據分批次傳輸 這兩個問題。
同步流程概覽
結合之前的同步流程,加上數據校驗和分批次傳輸數據,大概流程如下: 客戶端調用伺服器端的 Pull
介面從伺服器端拉取數據, 如果本地版本號等於伺服器端最新版本號,則已更新的最新版本, 如果本地版本小於伺服器端最新的版本號,則拉取需要更新的數據,伺服器端返回數據的同時會返回本地傳輸的數據的一個校驗值, 客戶端獲取到伺服器端響應時先根據接收到的數據計算校驗值,計算出來之後與伺服器端返回的校驗值進行比較, 如果本地計算的校驗值與伺服器端返回的校驗值一致則進行更新客戶端本地數據,不一致則視為無效數據,重新請求 Pull
介面。
更新到最新版本之後,判斷本地是否存在未提交的版本,如果本地不存在修改則本次數據同步完成,如果本地存在修改,則提交本地修改,提交本地數據的之前要先計算傳輸數據的校驗值,校驗值和本地數據一起傳給伺服器端 Push
介面。 伺服器端 Push
接收到客戶端請求之後需要進行數據校驗,根據傳輸的數據計算校驗值並與客戶端傳的校驗值比較, 如果兩個值不一致,則視為數據在傳輸過程中發生丟失或是異常數據,則不處理並返回客戶端,本次請求屬於異常請求。 如果兩個值一致,再進行數據處理,處理結束之後,數據會有一個返回狀態和其他必要的屬性,根據數據計算校驗值,與從伺服器拉取數據時類似,不再贅述, 客戶端數據校驗通過之後,根據伺服器端處理狀態進行本地數據的更新。
下麵展示添加數據校驗後的主要流程圖:
伺服器端獲取數據:
客戶端拉取數據:
伺服器端更新數據:
客戶端推送更新數據:
數據校驗
數據校驗,我們用的是MD5進行校驗,取傳輸數據的MD5,使用MD5有兩方面的考慮: 一方面因為MD5生成的字元串不算太長,不會影響傳輸的數據量, 另一方面也是因為MD5比較通用一些,APP端實現起來也比較方便。
數據分批傳輸
數據分批次傳輸,自己感覺這裡實現的比較 LOW ,這裡類似於網站上的分頁,沒想到更好的解決方案,期待大神分享更好的解決方案。 返回客戶端 當前請求數據頁碼索引 和 本次數據傳輸總頁數,如果頁碼索引小於總頁數,則頁碼索引+1,再請求一次介面知道返回的頁碼索引等於總頁數。
Summary
數據轉MD5踩到的坑
數據轉MD5的時候,再次踩了一個坑, 開始是這樣做的,用MD5演算法計算出位元組數組,然後使用 System.Text.Encoding.UTF8.GetString()
方法轉換成字元串,結果在調試的時候就傻逼了,獲取到的字元串是亂碼、亂碼、亂碼。。。【No zuo no die】
下麵祭出我鮮血淌過的代碼【笑Cry】
1 /// <summary> 2 /// 對象轉換為MD5字元串 3 /// </summary> 4 /// <param name="obj">對象</param> 5 /// <param name="isLowwer">是否是小寫</param> 6 /// <returns></returns> 7 public static string ToMD5String(this object obj, bool isLowwer = false) 8 { 9 if (obj == null) 10 { 11 return ""; 12 } 13 //創建MD5對象 14 MD5 md5 = new MD5CryptoServiceProvider(); 15 byte[] byteArray = null; 16 using (MemoryStream ms = new MemoryStream()) 17 { 18 new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Serialize(ms, obj); 19 byteArray = ms.ToArray(); 20 } 21 //計算指定位元組數組的哈希值 22 byte[] bMD5 = md5.ComputeHash(byteArray); 23 //釋放加密服務提供類的所有資源 24 md5.Clear(); 25 System.Text.StringBuilder sbMD5Pwd = new System.Text.StringBuilder(); 26 if (isLowwer) 27 { 28 for (int i = 0; i < bMD5.Length; i++) 29 { 30 //將每個位元組數據轉換為2位小寫的16進位的字元 31 sbMD5Pwd.Append(bMD5[i].ToString("x2")); 32 } 33 } 34 else 35 { 36 for (int i = 0; i < bMD5.Length; i++) 37 { 38 //將每個位元組數據轉換為2位大寫的16進位的字元 39 sbMD5Pwd.Append(bMD5[i].ToString("X2")); 40 } 41 } 42 return sbMD5Pwd.ToString(); 43 }
End
最後提供整個同步流程設計的流程圖,點我下載
另如果你有別的方案歡迎共同討論,希望大神看到能給出自己的看法和意見,有不正確的地方還希望能夠告知。