即时通讯 IM 开发指南 1:如何进行技术选型
《移動IM開發指南》系列文章將會介紹一個IM APP的方方面面,包括技術選型、登陸優化等。此外,本文作者會結合他在網易云信多年 iOS IM SDK 開發的經驗,深度分析實際開發中的各種常見問題。
### 通訊方式選擇
IM通訊方式無非兩種選擇:設備直連(P2P)和通過服務器中轉。
1、 P2P
P2P 多見于局域網內聊天工具,典型的應用有:飛鴿傳書等。這類軟件在啟動后一般做兩件事情:
- 進行 UDP 廣播:發送自己信息和接受同局域網內其他端信息
- 開啟 TCP 監聽:等待其他端進行連接
詳細的流程可以參考飛鴿傳書源碼。但是這種方式在有種種限制和不便:一方面它只適合在線的點對點消息傳輸,對離線,群組等業務支持不夠。另一方面由于 NAT 的存在,使得不同局域網內機器互聯難度大大上升,在某些網絡類型(對稱 NAT)下無法建立連接。
2、 服務器中轉
幾乎所有互聯網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
歡迎關注網易云信官網 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的即时通讯 IM 开发指南 1:如何进行技术选型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 简单的无线桥接技术-无线桥接技术有哪些
- 下一篇: 2018世界杯8组32队积分和净胜球