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