本文基於 IM Andriod 開發的各類常見問題,結合網易雲信即時通信技術的實踐,對 IM 開發作一個全面的總結。git
安全性是 IM 軟件的另外一個硬需求。消息傳遞時若是通訊數據若是被第三方截取,要能保證別人不能獲取到真實內容。安全鏈接的過程能夠參考 HTTPS 的方式,由服務器將證書下發給客戶端,客戶端產生一個對稱的密鑰,並經過服務器證書加密後交給服務器,以後的通訊就所有使用這個對稱的密鑰來加密。固然,這裏有兩點須要和 HTTPS 有所區別,第一是證書的獲取方式,HTTPS 中是由專門機構去驗證證書合法性的,IM 的客戶端確定不會這麼去作,爲了防止獲取證書的過程被人截獲,而後篡改證書,可行的方式是直接在客戶端安裝包中直接把證書打進去,該證書能夠隨着客戶端軟件升級一塊兒升級,也能夠在加密鏈接以後經過協議升級。第二個問題是對稱加密算法的選擇,由於密鑰的生命週期是跟隨一次鏈接的,時間並不長,而移動 App 對於電量消耗很是敏感,所以加密算法應儘可能選擇較爲簡單的類型,例如 RC4。github
心跳能夠分爲 TCP 的協議層心跳和 App 的應用層心跳。通常咱們都使用應用層心跳,一來便於服務器擴展(好比哪天咱們能夠換成 UDP 來傳),二則是能夠更靈活控制心跳間隔。
心跳協議僅僅是用來鏈接保活,其內容應當儘可能精簡,除了包頭中必要的部分,包體的可選包頭都不存在。
對於不一樣的網絡環境,心跳能夠採用不一樣的時間間隔。在不一樣網絡環境下,間隔的選擇能夠參考微信智能心跳方案。算法
客戶端掉線的緣由無非兩種,客戶端網絡掛了,服務器掛了。客戶端網絡掛了也分兩種,一種是本機就能感知到的網絡鏈接斷開,另外一種是本機網絡是好的,但互聯網鏈接是不一樣的,對應到 Android API上,就是 NetworkInfo 的 isAvailable 和 isConnected。固然這個地方的 isConnected 不必定可靠,由於它是靠連制定服務器來肯定的,那個服務器誰知道有沒有問題。
掉線後,根據不一樣的狀態須要選擇不一樣的重連間隔。若是是本地網絡出錯,並不須要定時去重連,這時只須要監聽網絡狀態,等到網絡恢復後重連便可。若是網絡變化很是頻繁,特別是 App 處在後臺運行時,對於重連也能夠加上必定的頻率控制,在保證必定消息實時性的同時,避免形成過多的電量消耗。
而若是掉線是由於本機網絡連不通互聯網,或者是服務器掛了,重連間隔的選擇就很是重要了。
首先,若是程序是在前臺,用戶正在使用咱們的 App,重連間隔應更加頻繁,使得用戶反饋更加及時,若是程序處於後臺運行,則爲了省電,能夠適當延長重連間隔。
其次,隨着重連次數的增長,說明服務器短期內恢復的可能性逐漸下降,重連間隔也應隨之延長(倍數增加)。但應該設置一個最大的重連間隔,當到達最大間隔時,再也不增長。
第三,重連間隔的增長不該當是固定的,而應該增長一個隨機退避策略。以避免若是是服務器宕機形成掉線,全部客戶端的重連時間點都是同樣的,當服務器恢復後,同一個時間點全部客戶端同時鏈接服務器,形成服務器不堪擁堵,再次宕機。活生生的例子請參考環信去年的宕機時間。
總結起來,重連間隔可表述以下:安全
IM 系統中另外一個重頭戲是多媒體數據。因爲移動網絡比較慢,流量又貴,在移動端針對這些問題必需要作一些處理。在上傳時,儘可能減小上傳時間,在下載時,能讓用戶儘快看到內容。同時,儘可能節省流量,減小沒必要要的流量消耗。
文本消息由於比較小,能夠直接經過長鏈接傳輸。但對於多媒體文件,經過長鏈接來傳輸則不合適,長鏈接服務器不會對大文件傳輸作針對性優化,大量的多媒體文件數據會直接搶佔其餘信令消息和文本消息的貸款資源。所以,多媒體消息會經過另外的通道,到專門的文件服務器存取。
在下載時,對於不一樣的網絡環境,能夠採用不一樣的預取策略。在 WiFi 環境下,因爲無需考慮流量問題,在收到消息後,咱們就能當即把包含的多媒體文件下載下來。而在移動網絡中,則應當等到用戶真正看到該多媒體消息時,纔去下載。服務器
上傳時,如今手機攝像頭的像素動輒上千萬,一張圖片隨隨便便就好幾 M,然而,經過 IM 軟件傳輸的圖片,一般對於質量要求並不會過高,若是咱們直接將好幾 M 的圖片直接上傳,每每費力又不討好。在上傳以前,將圖片像素下降,並進行壓縮,能夠明顯的減小上傳轉菊花的時間,減小用戶流量消耗。若是用戶確實要求圖片質量,則提供一個原圖選項。
若是是使用 http 上傳,大文件會被分紅多個數據塊上傳,前一個數據塊傳輸成功後,再傳輸下一個。斷線重傳時,也是以數據塊做爲最小重傳單元。針對不一樣的網絡類型,數據塊大小不一樣。在較好網絡下(wifi/4g/3g),數據塊能夠比較大,這樣能夠減小交互時間,加快傳輸熟讀,而在弱網環境,數據塊應當設置的比較小,以下降傳輸失敗機率,減小重傳流量消耗。
使用 http 上傳的另外一個優化技術是使用 pipeline。在不使用 pipeline 時,上傳一個數據塊須要等到前一個數據塊傳輸成功才行,數據通道是單工的。使用 pipeline 則能夠將數據通道變爲雙工的,一個數據塊傳輸完成後,沒必要等到回包,就能直接上傳下一個數據包,能節省一次數據回包延時。
下載時,在消息展現區顯示的一般只是一個很小的圖片,這時候只須要下載對應大小的縮略圖便可,無需下載原圖。甚至,這裏能夠將比縮略圖更小的圖片二進制數據直接放到消息體中下發,並展現給用戶一個高斯模糊後的效果圖,在保證最低可用的狀況下,減小用戶等待時間,提升用戶體驗。微信
對於不一樣的網絡環境,採起不一樣質量的語音編碼算法,在較好網絡時,使用高質量語音,而在弱網環境下,則使用較低質量,優先保證可用性。
爲了減小用戶等待時間,還能夠採起邊錄邊傳的策略。因爲錄音時間比較長,在錄製的過程當中,咱們就能夠將錄好的部分先傳到服務器,等到錄音完成,只須要上傳最後一個數據包,並告知服務器錄音完成便可,基本上能夠作到錄完即傳完,無需等待。
語音消息沒有縮略圖,所以語音下載基本就只能實打實的將原始文件下載下來。網絡
以上就是網易雲信對於 Android 即時通信開發的小結,歡迎各位積極提問,共同探討。性能
隨着即時通信以及音頻處理和壓縮技術的不斷髮展,效果更好、適用範圍更廣、性能更高的算法和新的技術必將不斷涌現,若是你有好的技術或者分享,歡迎關注網易雲信官方博客和 GitHub:優化
關注更多技術乾貨內容: 網易雲信博客
歡迎關注 網易雲信 GitHub
歡迎關注 網易雲信官網