IM 推送保障及網絡優化詳解(二):如何作長鏈接加推送組合方案

對於移動 APP 來講,IM 功能正變得愈來愈重要,它可以建立起人與人之間的鏈接。社交類產品中,用戶與用戶之間的溝通能夠產生出更好的用戶粘性。
在複雜的 Android 生態環境下,多種因素都會形成消息推送不能及時達到客戶端。另外,不穩定的移動網絡也給數據傳輸的速率和可靠性增長了障礙。
本文詳解了網易雲信 IM SDK 在應對弱網環境、移動端硬件限制以及Android複雜的生態現狀時的探索與心得.如何實現不影響用戶體驗的後臺保活,改善的長鏈接加推送組合方案,以及在弱網環境大數據傳輸的優化實踐。git

相關閱讀推薦:github

網易雲信即時通信推送保障及網絡優化詳解(一)如何作長鏈接加推送組合方案

如何作長鏈接

對於 IM 來講,及時的消息推送和較低的電量消耗也並不是不可兼得。在傳統上,每一個 IM 客戶端都會各自維護一條與服務器的長鏈接,本身的消息和信令都在這條長鏈接上傳遞,每一個APP也獨自去心跳,斷線重連等事情。算法

這種模式比較簡單,不一樣的 App 也是徹底隔離的,不會互相影響。但他的缺點也很是明顯,首先是作了不少重複的事情,形成了流量和電量的無謂消耗;第二是要保證全部的進程都能在後臺運行很難。優化的方向也就很是明顯了,那就是共享鏈接,如今絕大部分推送 SDK 也是這麼作的。從這些 App 裏面選出一個當前正在運行的,或者是被殺機率最低的 App 做爲總代理,只由這個代理和服務器創建鏈接,一個手機上的全部其餘 App 都經過這個代理中轉與服務器通訊。可是,IM 有一個很基本的要求在這種模式下沒法獲得知足:安全。全部 App 的消息都通過代理中轉,代理到服務器的鏈接是加密的,安全的,但到了代理這裏,消息都被解開了,所以代理理論上能夠看到其餘全部 App 的來往消息。所以,這種共享長鏈接的方式並不適用於 IM。segmentfault

雖然共享長鏈接方式不合適,但仍然提供了一個優化的思路。在此基礎上,有另外一個能夠脫敏共享鏈接的方式:安全長鏈接加推送鏈接模式。緩存

每一個 App 在使用和真正傳遞數據時,仍然獨立使用本身的安全長鏈接。而當 App 退到後臺一段時間以後,則斷開長鏈接,而後每一個 App 開啓一個推送代理,並選擇其中一個和網易雲信的推送服務器創建鏈接,以後當 App 有新消息時,就經過這個推送鏈接傳遞。App 能夠本身控制發出的推送消息的安全級別,能夠是包含說話人和消息內容,能夠只包含說話人,或者只是一條簡單的有新消息到達的提醒文案。推送到達後,若是是代理 App 本身的消息,直接傳遞給代理 App 便可。若是是其餘 App 消息,前面說到過,直接喚醒可能會失敗,並且會致使無謂的電量消耗,因此這裏並不直接將提醒傳遞給目標 App,而是由帶來發出一條通知欄提醒。等用戶去點擊通知欄提醒後,纔會把目標 App 喚醒。安全

如今國內的 ROM 中,華爲和小米的系統原本是帶有推送系統,且開放給了第三方 App 的。在這兩個系統上,使用系統的推送通道明顯會更加穩定,也更加節省資源。所以在 MIUI 上,從長鏈接到推送通道的切換流程仍然和前面的同樣,只是再也不使用本身的推送鏈接,而是將消息轉發到 MIUI 的推送服務器,而後轉給 MIUI 系統的推送代理,而後傳遞給網易雲信的 App。華爲的推送系統流程也是同樣。不過如今華爲和 MIUI 在推送實現上有一些區別,例如 MIUI 的通知欄提醒是在本身的推送代理裏完成的,而華爲倒是將提醒通知交給 App 本身去完成的,另外,他們的通知欄提醒的管理接口也有不少區別。在 App 沒有被禁用的狀況下,二者均可以收到推送,而若是 App 已經被禁用了,MIUI 的通知欄提醒方式還能夠將推送送達,而其餘的推送方式則不能送達了。服務器

以上就是在保障消息推送方面所可以作的全部事情了。若是之後有更多的系統開放本身的推送系統也能夠選擇逐步接入,以提升推送到達即時性,減小資源消耗。不過相應的,也要承受不斷加入各類系統的推送 SDK,增大發布包體積的缺點。微信

移動通訊網絡的三個特色

第一個是慢,尤爲是 2G,3G 網絡,慢的使人髮指。
第二個是斷,手機跟着人不停的移動,網絡也不停的在切換,從 wifi 到移動網絡,從一個基站到另外一個基站,從有信號到沒信號,均可能致使網絡中斷。有些制式的網絡,接打電話也會致使數據網絡斷開。另外,移動基站還有 NAT 超時,到一個鏈接上長時間空閒後,基站就會默默的將鏈接斷開,沒有任何通知。
第三個是貴,這個就不用多說。

三種長鏈接類型

網易雲信整個通訊系統中有3種類型的鏈接:TCP,UDP,HTTP。雖然說這三個並非同一層的協議,不過畢竟都在應用的更下層,所以這麼劃分也無妨。3 種類型的協議對應了不一樣的業務應用。TCP 主要是用戶長鏈接,也就是普通 IM 消息和信令的傳輸,UDP 用於傳輸實時音視頻數據流,而 HTTP 則主要用在音頻,圖片等文件的上傳下載上。對於不一樣的業務,SDK 優化的關注點會有一些不相同。網絡

圖片描述

IM 長鏈接優化怎麼作?

第一個是協議的選擇。前面說,長鏈接的使用量是最大,選擇一個合適的協議相當重要。若是是剛開始接觸IM 開發,通常會選擇一些開源的協議,好比 XMPP,SIP 等。這是 XMPP 協議的一個請求樣例,能夠看到是一段 XML 格式的文本數據。負載均衡

圖片描述

這是基於 SIP 的 SIMPLE 協議的一個請求樣例,能夠看到是一段相似 HTTP 協議的文本數據。這些協議的優點在於開源,有成熟的解決方案可使用,擴展性好,甚至還能夠和其餘系統互聯互通,協議的可讀性也很是好。可是在廣泛比較臃腫,冗餘字段不少,在昂貴的移動網絡裏面用起來會比較浪費。網易雲信採用的是私有的二進制協議,這是一個請求的數據樣例,這裏是把二進制數據轉爲了 16 進制顯示出來,每一個字節這裏顯示爲兩個字符。能夠看到二進制協議的特色在於徹底失去了可讀性,可是,卻帶來極高的表達效率,相對於文本協議,能夠節省很是多的數據流量。

另外一個例子是登陸的優化。因爲移動網絡常常斷開,因此登陸經常是心跳以外交互最多的協議了。使用量越大,優化就越有意義。通常而言,登陸會通過這麼幾步。

圖片描述

  • 第一步是 LBS。

這裏的 LBS 不是常常說的基於地址位置的服務,在不一樣的廠商可能也有不一樣的叫法,反正做用都是獲取服務器的IP地址。像雲信這種須要提供全球服務的系統,在世界各地都要部署服務器,用戶登陸時,確定要選擇一臺最優的服務器接入服務。經過lbs,客戶端能夠獲取離本身最近,連通性最好的服務器鏈接機IP地址,服務器也能夠據此作負載均衡。

  • 拿到服務器鏈接機IP後,客戶端就去鏈接該服務器。

鏈接成功,須要有一次握手。這個握手不是TCP的三次握手,而是爲了創建安全鏈接,同服務器協商加密算法和加密密鑰。
而後就發送登陸請求,這裏會帶上用戶認證信息,本機設備信息等數據。
登陸成功以後,就是同步數據,包括離線消息,用戶信息,羣組信息等。通常而言,這裏不會去作全量同步,而是採用基於時間戳的增量同步。

在移動網絡上,每一次交互都須要比較長的時間,同時,每一次網絡請求電量消耗也是很大的。因此,優化的方向就是儘可能減小交互次數,而方法則是合併請求,並行操做以及省略請求。
LBS 和鏈接這兩個步驟是能夠並行完成的。若是前面已經獲取過 LBS,這裏能夠有以前的緩存地址,若是沒有,能夠先連一個默認地址。

  • 其次是握手和登陸也能夠並行操做。

在握手包中,就能夠把加密後的登陸包直接帶上去了。若是是斷線重連,網易還能夠簡化登陸,直接帶上上一次登陸的會話 ID,一來減小服務器鑑權壓力,二則能夠直接帶回在斷線期間是否有未讀消息等數據,若是沒有,則能直接將同步這一步省略掉。若是有,同步也能夠只作部分同步,只去拉去離線消息便可。等到 App 切換到前臺,纔去同步其餘的信息。
經過這些優化,登陸時間能夠降爲原來的 1/2 到 1/3,登陸的流量消耗也能夠節省 30% 左右。


隨着音頻處理和壓縮技術的不斷髮展,效果更好、適用範圍更廣、性能更高的算法和新的技術必將不斷涌現,若是你有好的技術或者分享,歡迎關注網易 MC 官方博客以及微信公衆號:**

關注更多技術乾貨內容: 網易雲信博客
歡迎關注 網易雲信 GitHub
歡迎關注 網易雲信官網
相關文章
相關標籤/搜索