即時通信 IM 開發指南 1:如何進行技術選型

《移動IM開發指南》系列文章將會介紹一個IM APP的方方面面,包括技術選型、登錄優化等。此外,本文做者會結合他在網易雲信多年 iOS IM SDK 開發的經驗,深度分析實際開發中的各類常見問題。git

### 通信方式選擇github

IM通信方式無非兩種選擇:設備直連(P2P)和經過服務器中轉。算法

一、 P2P
P2P 多見於局域網內聊天工具,典型的應用有:飛鴿傳書等。這類軟件在啓動後通常作兩件事情:安全

  • 進行 UDP 廣播:發送本身信息和接受同局域網內其餘端信息
  • 開啓 TCP 監聽:等待其餘端進行鏈接

詳細的流程能夠參考飛鴿傳書源碼。可是這種方式在有種種限制和不便:一方面它只適合在線的點對點消息傳輸,對離線,羣組等業務支持不夠。另外一方面因爲 NAT 的存在,使得不一樣局域網內機器互聯難度大大上升,在某些網絡類型(對稱 NAT)下沒法創建鏈接。服務器

二、 服務器中轉
幾乎全部互聯網IM產品都採用服務器中轉這種方式進行消息傳輸,相對於P2P的方式,它有以下的優勢:網絡

  • 可以支持更多P2P沒法支持或支持很差的業務,如離線消息,羣組,聊天室服務
  • 方便業務邏輯的拓展和新舊版本的兼容

固然它也有本身的問題:服務器架構複雜,併發要求高。架構

網絡鏈接方式

IM 主流網絡鏈接方式有兩種:併發

  • 基於 TCP 的長鏈接
  • 基於 HTTP 短鏈接 PULL 的方式

後者常見於 Web IM 系統(固然如今不少 Web IM 都是基於 WebSocket 實現),它的優勢是實現簡單,方便開發上手,問題是流量大,服務器負載較大,消息及時性沒法很好地保證,對大規模的用戶量支持不夠,比較適合小型的 IM 系統,如小網站的客戶系統。
基於 TCP 長鏈接則可以更好地支持大批量用戶,問題是客戶端和服務器的實現比較複雜。固然也還有一些變種,以下行使用 MQTT 進行服務器通知/消息的下發,上行使用 HTTP 短鏈接進行指令和消息的上傳。這種方式可以保證下行消息/指令的及時性,可是在弱網絡下上行慢的問題仍是比較嚴重。早期的來往就是基於這種方式。負載均衡

協議選擇

IM 協議選擇原則通常是:易於拓展,方便覆蓋各類業務邏輯,同時又比較節約流量。後一點的需求在移動端 IM 上尤爲重要。
常見的協議有:XMPP;SIP;MQTT;私有協議。工具

  • XMPP 協議的優勢在於:協議開源,可拓展性強,在各個端(包括服務器)有各類語言的實現,開發者接入方便。

可是缺點也是很多:XML 表現力弱,有太多冗餘信息,流量大,實際使用時有大量天坑。

  • SIP 協議多用於 VOIP 相關的模塊,是一種文本協議,因爲我並無實際用過,因此不作評論,但從它是文本協議這一點幾乎能夠判定它的流量不會小。
  • MQTT 的優勢是協議簡單,流量少,可是它並非一個專門爲 IM 設計的協議,多使用於推送。
  • 市面上幾乎全部主流 IM APP 都是使用私有協議,一個被良好設計的私有協議通常有以下優勢:高效,節約流量(通常使用二進制協議),安全性高,難以破解。缺點則是在開發初期沒有現有樣列能夠參考,對於設計者的要求比較高。

一個好的協議須要知足以下條件:高效,簡潔,可讀性好,節約流量,易於拓展,同時又可以匹配當前團隊的技術堆棧。基於如上原則,咱們能夠推出: 若是團隊小,團隊技術在 IM 上積累不夠能夠考慮使用 XMPP 或者 MQTT+HTTP 短鏈接的實現。反之能夠考慮本身設計和實現私有協議。

私有協議的設計

  • 序列化選擇移動互聯網相對於有線網絡最大特色是:帶寬低,延遲高,丟包率高和穩定性差,流量費用高。因此在私有協議的序列化上通常使用二進制協議,而不是文本協議。常見的二進制序列化庫有 protobuf 和 MessagePack,固然你也能夠本身實現本身的二進制協議序列化和反序列的過程,好比蘑菇街的 TeamTalk。可是前面兩者不管是可拓展性仍是可讀性都完爆 TeamTalk(TeamTalk 連 Variant 都不支持,一個 int 傳輸時固定佔用 4 個字節),因此大部分狀況下仍是不推薦本身去實現二進制協議的序列化和反序列化過程。
  • 協議格式設計基於 TCP 的應用層協議通常都分爲包頭和包體(如 HTTP),IM 協議也不例外。包頭通常用於表示每一個請求/反饋的公共部分,如包長,請求類型,返回碼等。 而包頭則填充不一樣請求/反饋對應的信息。

一個最簡單的包頭能夠定義爲
圖片描述

以心跳包爲例,假設當前的 serial 爲 1,心跳包的 command 爲 10,那麼使用 MessagePack 作序列化時:length=4,serial=1,command=10,code=0,每一個字段各佔一個字節,包體爲空,僅須要 4 個字節。
固然這是最簡單的一個例子,面對真正的業務邏輯時,包體裏面會須要塞入更多地信息,這個須要開發根據本身的業務邏輯總結公共部分,如爲了兼容加入的協議版本號,爲了負載均衡加入的模塊 id 等。

上面就是 IM 系統大體的選型過程,包含了通信方式,鏈接方式,協議選擇,協議設計。可是實際開發過程當中還有大量的問題須要處理。《移動IM開發指南》系列文章第二篇將會爲你們解答實際開發中的常見問題。


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

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