*** 序: ***
IM 中的數據通信協議指的是 IM 系統中應用層所使用的通信協議,該通信協議的設計效果會對 IM 系統的流量消耗、電量消耗、通信速度、兼容性、可擴展性等方面均會造成一定的影響,所以一般的 IM 系統均需要根據自身的業務場景和需求選擇恰當的通信協議或制定最優性能的通信協議。
影響數據通信協議選擇的因素
**網絡數據大小 **:占用帶寬,傳輸效率。盡量不要有冗余數據,這樣才能夠少占用帶寬,少占用資源,少網絡 IO,提高傳輸效率。
** 網絡數據安全性 **:敏感數據的網絡安全。必須考慮對部分有安全性要求的傳輸數據進行加密。在銀行等數據安全性要求很高的應用行業和場景里尤為重要,當然傳統的即時通訊應用里基于用戶隱私考慮,數據加密也同樣是個必須考慮的問題。安全性是應用的基礎條件,需求是一樣的,只是加密程度、安全性級別要求有不同而已。
** 編碼復雜度 **:編碼復雜度包括序列化和反序列化復雜度、效率、數據結構的可擴展性和可維護性。對于平臺相關業務的代碼實現也需要考慮到數據發送方和數據接收方數據處理的復雜度和數據結構的可擴展性,可維護性,人力成本和實施復雜度等。
** 協議通用性、大眾規范 **:數據類型必須是跨平臺的,數據格式是通用的;
** 可擴展性 **:方便覆蓋各類業務;
** 節省電量和流量消耗 **:移動端業務尤為重要。
** 總結 **:一個好的數據通信協議一般需要具備如下條件:高效,簡潔,可讀性好,節約流量,節省電量,易于拓展,同時又能夠匹配當前團隊的技術堆棧。
數據通信協議類型
應用層通信協議主要有文本協議和二進制協議。
-
** 文本協議:**
文本協議即采用最符合人類表達習慣的文本語言進行數據傳輸的協議,如 Http 1.x 采用的便是文本協議。IM中,MSN使用的是文本協議。特點:
- 可讀性比較好,調試方便;
- 可通過 key:value 鍵值對進行擴展,擴展性比較好;
- 需要一行一行對鍵值對進行解析,所以解析效率比較低;
- 對語音、視頻等二進制格式的支持不是很好;
** 二進制協議:**
二進制協議即數據傳輸通過二進制流進行傳輸的協議,如 Http/2、IP 協議等。二進制協議一般由定長包頭和可擴展變長包體組成,協議規范中對每個字段的含義進行了相應的規定。QQ 使用的是二進制協議。
特點:
- 可讀性差,調試不太方便;
- 可擴展性差,擴展字段時,新舊版本兼容性差;
- 解析效率高;
常見通信協議分析
- ** XMPP:**
XMPP(Extensible Messaging and Presence Protocol,可擴展通訊和表示協議),是一個基于 XML 的協議,主要用于即時消息以及在線現場探測。
優點:協議成熟,強大,可擴展性強,基于 XML 語言,可讀性好,在各個端(包括服務器) 有各種語言的實現,開發者接入方便,目前主要應用于許多聊天系統中,且已有開源的Java 版的開發實例 androidpn。
缺點:協議較復雜,冗余(基于XML),流量和電量消耗不容小覷,部署硬件成本高,XML 解析代價高。
-
** SIP:**
SIP(Session Initiation Protocol,會話初始協議),是一個基于文本的應用層控制協議,用于創建、修改和釋放一個或多個參與者的會話,多用于 VoIP(Voice Over Internet Protocol)相關的模塊。優點:
- SIP 電話基于現在的因特網系統,接入方便、覆蓋面廣,需要的設備也非常簡單;
- IP 電信業能夠提供多樣化的通信服務,如:電話到電話、電腦到電話、傳真到傳真等。SIP 是一 種 IP 電信業務,應用方式靈活,功能豐富;
- VoIP的通話質量比較好。傳統語音通話采用的是模擬信號技術,模擬信號容易受到干擾,且傳統電話一般采用的是高失真壓縮技術,很難避免信號失真,而VoIP采用的是數字傳輸技術,在網絡上傳輸的是包含語音信息的數據包,可以進行低失真壓縮,這些數據包只要被對方收到并按約定的規則還原為語音信號,失真度一般都比較小。
-
** Protobuf:**
Protobuf 是 Google 開源的一個序列化框架,類似于 XML、JSON等,該框架在易用性、數據大小及效率方面進行了良好的平衡處理。一條消息經 Protobuf 序列化后的數據只有二進制數據的 1/10、XML格式的1/20、JSON的1/10,數據量大幅縮小。優點:
- 靈活:方便接口更新;
- 高效:效率經過 Google 優化,傳輸效率比普通 XML 等高許多;
非常小、非常快、非常簡單,一條消息數據用Protobuf序列化后的大小是JSON的1/10、XML格式的1/20、是二進制序列化的1/10。 - 易于使用:開發人員通過按照一定的語法定義結構化的消息格式,然后送給命令行工具,工具將自動生成相關的類,可以支持java、c++、python等語言環境。通過將這些類包含在項目中,可以很輕松的調用相關方法來完成業務消息的序列化與反序列化工作;
- 支持的語言豐富:原生支持c++、java、python等多達10余種語言。
缺點:不能表示復雜的數據結構,但是對于IM來講,已經足夠。
適用場景:
- 需要和其它系統進行消息交換的場景;
- 對消息 Size 很敏感的場景;
- 小數據場景,大數據場景下不是很適合;
- 項目語言是 C++、Java、Python 等,這幾類語言可以使用 Google 的源生類庫,序列化和反序列化效率非常高。其它的語言需要第三方或者自己寫,序列化和反序列化的效率不保證。
-
** MQTT:**
MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)是IBM開發的一個即時通訊協議,是一個基于代理的發布/訂閱模式的輕量級消息傳輸協議,它可以通過很少的代碼和帶寬與遠程設備連接。特點:
- 使用發布/訂閱消息模式,提供一對多的消息發布,解除應用程序耦合;
- 對負載內容屏蔽的消息傳輸;
- 使用 TCP/IP 提供網絡連接;
- 有三種消息發布服務質量:至少一次、至多一次、只有一次;
- 小型傳輸,開銷很小(固定長度的頭部是2字節),協議交換最小化,以降低網絡流量;
優點:協議簡潔輕巧,數據冗余量低,流量消耗小,電量消耗小,可擴展性好,支持的設備從智能硬件到智能手機無所不包;
缺點:它并不是一個專門為 IM 設計的協議,多使用于推送;服務器端實現難度大,雖然已經有了 C++ 版本的服務端組件,但是并不開源;數據量較大時的并發處理難度大。
-
** 私有協議 :**
市面上幾乎所有主流 IM APP 都是是使用私有協議,一個被良好設計的私有協議優勢非常明顯。優點:高效,節約流量(一般使用二進制協議),安全性高,難以破解;
缺點:工作量大,在開發初期沒有現有樣列可以參考,需要考慮全面,容易出錯,對于設計者的要求比較高;編碼復雜度高(自己定義消息格式,自己編寫序列化和反序列化方法,自己進行容錯處理等),可擴展性不強(比如添加個字段,就必須改兩端的邏輯處理)。
私有協議的設計
- ** 序列化與反序列化 **
移動互聯網相對于有線網絡最大特點是:** 帶寬低、延遲高、丟包率高、穩定性差、流量費用高 **。所以在私有協議的序列化上一般使用二進制協議,而不是文本協議。常見的二進制序列化庫有 Protobuf 和 MessagePack,也可以自己定制私有的二進制協議序列化和反序列的過程,比如蘑菇街的TeamTalk。一般,Protobuf 和 MessagePack 的可擴展性和可讀性較自定義的序列化過程要好很多,所以大部分情況下不推薦自己實現二進制協議的序列化和反序列化過程。
- ** 協議格式設計 **
基于 TCP 的應用層協議一般都分為包頭和包體(如 HTTP),IM 協議也不例外。包頭一般用于表示每個請求/反饋的公共部分,如包長、請求類型、返回碼等。 而包體則填充不同請求/反饋對應的信息。