IM推送保障及網路優化詳解(二):如何做長連線加推送組合方案

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

相關閱讀推薦

網易雲信即時通訊推送保障及網路優化詳解(一):如何做長連線加推送組合方案

網易雲信即時通訊推送保障及網路優化詳解(三):如何在弱網環境下優化大資料傳輸

如何做長連線

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

這種模式比較簡單,不同的APP也是完全隔離的,不會互相影響。但他的缺點也非常明顯:

首先是做了很多重複的事情,造成了流量和電量的無謂消耗;

第二是要保證所有的程式都能在後臺執行很難。

優化的方向也就非常明顯了,那就是共享連線,現在絕大部分推送SDK也是這麼做的。從這些APP裡面選出一個當前正在執行的,或者是被殺概率最低的APP作為總代理,只由這個代理和伺服器建立連線,一個手機上的所有其他APP都通過這個代理中轉與伺服器通訊。

但是,IM有一個很基本的要求在這種模式下無法得到滿足:安全。所有APP的訊息都經過代理中轉,代理到伺服器的連線是加密的,安全的,但到了代理這裡,訊息都被解開了,因此代理理論上可以看到其他所有APP的來往訊息。因此,這種共享長連線的方式並不適用於IM。

雖然共享長連線方式不合適,但仍然提供了一個優化的思路。在此基礎上,有另一個可以脫敏共享連線的方式:安全長連線加推送連線模式。

每個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長連線優化怎麼做?

第一個是協議的選擇。前面說,長連線的使用量是最大,選擇一個合適的協議至關重要。如果是剛開始接觸IM開發,一般會選擇一些開源的協議,比如XMPP,SIP等。這是XMPP協議的一個請求樣例,可以看到是一段XML格式的文字資料。

IM推送保障及網路優化詳解(二):如何做長連線加推送組合方案

這是基於SIP的SIMPLE協議的一個請求樣例,可以看到是一段類似HTTP協議的文字資料。這些協議的優勢在於開源,有成熟的解決方案可以使用,擴充套件性好,甚至還可以和其他系統互聯互通,協議的可讀性也非常好。但是在普遍比較臃腫,冗餘欄位很多,在昂貴的行動網路裡面用起來會比較浪費。網易雲信採用的是私有的二進位制協議,這是一個請求的資料樣例,這裡是把二進位制資料轉為了16進位制顯示出來,每個位元組這裡顯示為兩個字元。可以看到二進位制協議的特點在於完全失去了可讀性,但是,卻帶來極高的表達效率,相對於文字協議,可以節省非常多的資料流量。

另一個例子是登入的優化。由於行動網路經常斷開,所以登入常常是心跳之外互動最多的協議了。使用量越大,優化就越有意義。一般而言,登入會經過這麼幾步。

IM推送保障及網路優化詳解(二):如何做長連線加推送組合方案

第一步是LBS。這裡的LBS不是經常說的基於地址位置的服務,在不同的廠商可能也有不同的叫法,反正作用都是獲取伺服器的IP地址。像雲信這種需要提供全球服務的系統,在世界各地都要部署伺服器,使用者登入時,肯定要選擇一臺最優的伺服器接入服務。通過lbs,客戶端可以獲取離自己最近,連通性最好的伺服器連線機IP地址,伺服器也可以據此做負載均衡。

拿到伺服器連線機IP後,客戶端就去連線該伺服器。

連線成功,需要有一次握手。這個握手不是TCP的三次握手,而是為了建立安全連線,同伺服器協商加密演算法和加密金鑰。

然後就傳送登入請求,這裡會帶上使用者認證資訊,本機裝置資訊等資料。

登入成功之後,就是同步資料,包括離線訊息,使用者資訊,群組資訊等。一般而言,這裡不會去做全量同步,而是採用基於時間戳的增量同步。

在行動網路上,每一次互動都需要比較長的時間,同時,每一次網路請求電量消耗也是很大的。所以,優化的方向就是儘量減少互動次數,而方法則是合併請求,並行操作以及省略請求。

LBS和連線這兩個步驟是可以並行完成的。如果前面已經獲取過LBS,這裡可以有之前的快取地址,如果沒有,可以先連一個預設地址。

其次是握手和登入也可以並行操作。在握手包中,就可以把加密後的登入包直接帶上去了。如果是斷線重連,網易還可以簡化登入,直接帶上上一次登入的會話ID,一來減少伺服器鑑權壓力,二則可以直接帶回在斷線期間是否有未讀訊息等資料,如果沒有,則能直接將同步這一步省略掉。如果有,同步也可以只做部分同步,只去拉去離線訊息即可。等到APP切換到前臺,才去同步其他的資訊。

通過這些優化,登入時間可以降為原來的1/2到1/3,登入的流量消耗也可以節省30%左右。


相關文章