XMPP 是老牌的即時聊天協(xié)議,像 Google Hangouts, WhatsApp Messenger 等即時聊天程序都是基于 XMPP 的。
而 MQTT 是最近幾年隨著物聯(lián)網(wǎng)行業(yè)的發(fā)展,才慢慢進入公眾視線的,像 Facebook Messenger App 使用了 MQTT 協(xié)議。
MQTT 的特點在于報文小邪狞,協(xié)議簡單,提供了三個 QoS 級別茅撞。這幾個特性是專門為網(wǎng)絡(luò)環(huán)境復(fù)雜的物聯(lián)網(wǎng)(IoT)場景設(shè)計的帆卓。
XMPP 特點在于協(xié)議和擴展協(xié)議成熟,功能完善米丘,專門為即時聊天(IM)場景設(shè)計剑令。
兩者無法直接比較優(yōu)劣。就像老虎和獅子其實無法比較真實實力蠕蚜,因為一個踞臥在長白山尚洽,一個奔跑在非洲大草原,要較量怎么也得放到同一個戰(zhàn)場靶累。但問題是戰(zhàn)場選在哪兒都不合適腺毫。放在草原是偏袒獅子癣疟,放在森林是偏袒老虎,放在動物園卻都沒了脾氣潮酒,怎么也打不起來了睛挚。
對于這兩個協(xié)議來說,首先 XMPP 依賴 XML 協(xié)議急黎,所以放在 IoT 場景里過重扎狱,基本不合適,很少有人用勃教。而另一方面雖然 MQTT 協(xié)議本身過于簡單淤击,放在實時聊天協(xié)議里的話,多數(shù)功能是要自己定制協(xié)議來實現(xiàn)的故源,但總歸可以用污抬。
按照這個道理,比較就只能放在 IM 領(lǐng)域才有真實意義绳军。
做技術(shù)選擇一直是程序員和設(shè)計者頭痛的事情印机,放在 IM App 設(shè)計的初期,大概就歸結(jié)為兩個問題:
- MQTT 被越來越多的用在 IM 應(yīng)用上门驾,XMPP 是要退出歷史舞臺了么射赛?
- 我的 IM App 到底該選用 MQTT 嗎?
為了回答上面的兩個問題奶是,我們需要逐一考慮使用 MQTT 實現(xiàn)常見 IM 需求的方式楣责,并分析其優(yōu)缺點。
(現(xiàn)在很多人的技術(shù)選擇已經(jīng)很簡單了 -- 什么流行用什么)
性能
對于移動設(shè)備上的 IM App 來說诫隅,電量損耗是一個需要認(rèn)真對待的問題腐魂,在這方面,固定頭部僅僅消耗 2 個字節(jié)的 MQTT 協(xié)議顯然有著巨大優(yōu)勢逐纬。當(dāng)然前提是設(shè)計良好的主題格式,消息體格式和長度削樊。
使用 MQTT 搭配合適的二進制格式的消息體豁生,讓聊天信息交換和處理非常輕量。
IM 功能
XMPP 在 IM 的各個功能上的定義非常完善漫贞,而 MQTT 需要在基礎(chǔ)協(xié)議之上自行實現(xiàn)甸箱。
認(rèn)證
- XMPP: 通過 SASL RFC4422
- MQTT: 協(xié)議未定義,通常的實現(xiàn)方式是定制 CONNECT 報文中的 username 和 password 字段迅脐,因為 MQTT 只提供了這兩個字段可以自行發(fā)揮芍殖。比如定義 username 為 {"uname": "Shawn", "dtype": "mobile"}, password 為 JWT。(MQTT 5.0 里添加了
AUTH
消息類型)谴蔑。然后在 MQTT 后臺處理 CONNECT 消息進行認(rèn)證豌骏。
在設(shè)計的時候是需要仔細(xì)考慮的部分龟梦。
多設(shè)備
- XMPP: 核心協(xié)議里有定義,通過
resource
實現(xiàn)窃躲。比如用戶 shawn@emqx.io 的兩個設(shè)備分別是: shawn@emqx.io/pc, shawn@emqx.io/mobile计贰。 - MQTT: 協(xié)議未定義。因為 MQTT 協(xié)議里蒂窒,唯一標(biāo)識設(shè)備使用的是
Client ID
躁倒,所以設(shè)計的難點在于,如何定義 Client ID 的格式洒琢,并且能夠跟 IM 需求里的 username 做對應(yīng)秧秉,并且實現(xiàn)多終端同步。常見的做法是:- 限制用戶名里不能有特殊字符
'@'
,'/'
; - 對于 ClientID 的格式為 'username@device', 比如用戶 "shawn" 的兩個 ClientID: "shawn@pc", "shawn@mobile"衰抑。
- 對于用戶 shawn 的這兩個終端象迎,通過訂閱相同的主題來同步所有別人發(fā)來的聊天消息。比如都訂閱主題:'p2p/talk/shawn'停士。并且向外發(fā)送消息時需要將消息復(fù)制到主題 'p2p/talk/shawn' 以同步發(fā)出的消息挖帘,這樣做時,還需要忽略自己發(fā)出的同步消息恋技。
- 限制用戶名里不能有特殊字符
狀態(tài)顯示
- XMPP: XMPP Presence RFC 3921.
- MQTT: 協(xié)議未定義拇舀,可以通過訂閱對方狀態(tài)來實現(xiàn):比如用戶
未完成 2018年07月23日00:54:15