MQTT vs. XMPP,哪一個才是IoT通訊協定的正解

2023-09-06 06:00:52

MQTT vs. XMPP,哪一個才是IoT通訊協定的正解

這是個有趣的話題!

先來聊幾個小故事。

關於我和MQTT

我在人生第一個IoT專案裡,第一次接觸到MQTT協定。

我很快就理解了這個協定。因為,它和企業開發用的MQ產品實在是太像了。

在我職業生涯早期,是的,20年前,當時做一個銀行的專案,就用過MQ這東西,那個專案使用了IBM MQ。隨著工作經驗的增加,在另外一些專案中,也會接觸使用到MQ產品。

後來,我在做國產中介軟體的公司裡開發中介軟體,當時我們有個團隊,專門在做MQ產品。

所以,當我第一次讀MQTT資料的時候,我心裡立馬浮現出了這樣的看法:這不就是一個輕量級的、給IoT應用使用的MQ嗎。

關於我和XMPP

我和XMPP之間的故事要複雜很多。

那是中國電信的一個專案,電信想在手機裡整合融合通訊軟體。運營商的思路也很直白,微信你不是牛逼嗎,你用網際網路簡訊來代替我的電信網簡訊、用網際網路音視訊來取代我的電信通話網路,奪取我的生意,搶奪我的通道。我們運營商必須反擊,我們必須要有應對的解決方案!

當時中國電信想到的解決方案之一,就是手機內建融合通訊軟體。

簡單點說,運營商每年要送出很多的手機,辦套餐送手機,這是運營商常用的行銷套路。運營商的思路,如果這個送的手機,使用者拿到手裡的時候,它就已經自帶了微信所有的功能了,那為啥還要另外再安裝一個微信呢?

在手機裡預置電信運營商開發的一個軟體,這個軟體具有微信所有的功能,功能被直接緊密整合在手機電話簿裡,用來和聯絡人來發資訊、聊天、語音和視訊了,走網際網路通道。

這個電信運營商想內建在手機裡替代微信的軟體,被叫做融合通訊軟體。

因為要做中國電信的這個專案,我第一次接觸到了XMPP協定。

後面的故事不出所料,融合通訊軟體並未能掀起風浪,微信依然被安裝在每一臺手機上。

是的,我和XMPP的情緣,從那時候開始了。

在這個電信的專案中,我使用了Openfire XMPP Server,這應該是Java界最出名的一個開源XMPP伺服器了。

Openfire作為一個標準的XMPP Server,其實它還挺可以的。在開發專案過程中,我當然會讀它的程式碼,我會時不時發出感慨:老外寫程式碼還真是挺認真的!

老外寫東西,真的是認真!但是Openfire開源XMPP伺服器,它並不能讓我滿意。

融合通訊軟體,當然會有不少需要客製化的功能。但是,看看下面這段摘自Openfire的原始碼,就應該會明白,為啥我並不是那麼的滿意。

以下程式碼,來自Openfire專案src/main/java/org/jivesoftware/openfire/XMPPServer.java檔案。

... ...
    private void loadModules() {
        // Load boot modules
        loadModule(RoutingTableImpl.class.getName());
        loadModule(AuditManagerImpl.class.getName());
        loadModule(RosterManager.class.getName());
        loadModule(PrivateStorage.class.getName());
        // Load core modules
        loadModule(PresenceManagerImpl.class.getName());
        loadModule(SessionManager.class.getName());
        loadModule(PacketRouterImpl.class.getName());
        loadModule(IQRouter.class.getName());
        loadModule(MessageRouter.class.getName());
        loadModule(PresenceRouter.class.getName());
        loadModule(MulticastRouter.class.getName());
        loadModule(PacketTransporterImpl.class.getName());
        loadModule(PacketDelivererImpl.class.getName());
        loadModule(TransportHandler.class.getName());
        loadModule(OfflineMessageStrategy.class.getName());
        loadModule(OfflineMessageStore.class.getName());
        loadModule(VCardManager.class.getName());
        // Load standard modules
        loadModule(IQBindHandler.class.getName());
        loadModule(IQSessionEstablishmentHandler.class.getName());
        loadModule(IQPingHandler.class.getName());
        loadModule(IQBlockingHandler.class.getName());
        loadModule(IQPrivateHandler.class.getName());
        loadModule(IQRegisterHandler.class.getName());
        loadModule(IQRosterHandler.class.getName());
        loadModule(IQEntityTimeHandler.class.getName());
        loadModule(IQvCardHandler.class.getName());
        loadModule(IQVersionHandler.class.getName());
        loadModule(IQLastActivityHandler.class.getName());
        loadModule(PresenceSubscribeHandler.class.getName());
        loadModule(PresenceUpdateHandler.class.getName());
        loadModule(IQOfflineMessagesHandler.class.getName());
        loadModule(IQPEPHandler.class.getName());
        loadModule(IQPEPOwnerHandler.class.getName());
        loadModule(MulticastDNSService.class.getName());
        loadModule(IQSharedGroupHandler.class.getName());
        loadModule(AdHocCommandHandler.class.getName());
        loadModule(IQPrivacyHandler.class.getName());
        loadModule(DefaultFileTransferManager.class.getName());
        loadModule(FileTransferProxy.class.getName());
        loadModule(MediaProxyService.class.getName());
        loadModule(PubSubModule.class.getName());
        loadModule(IQDiscoInfoHandler.class.getName());
        loadModule(IQDiscoItemsHandler.class.getName());
        loadModule(UpdateManager.class.getName());
        loadModule(InternalComponentManager.class.getName());
        loadModule(MultiUserChatManager.class.getName());
        loadModule(IQMessageCarbonsHandler.class.getName());
        loadModule(ArchiveManager.class.getName());
        loadModule(CertificateStoreManager.class.getName());
        loadModule(EntityCapabilitiesManager.class.getName());
        loadModule(SoftwareVersionManager.class.getName());
        loadModule(SoftwareServerVersionManager.class.getName());

        // Load this module always last since we don't want to start listening for clients
        // before the rest of the modules have been started
        loadModule(ConnectionManagerImpl.class.getName());
        loadModule(ClusterMonitor.class.getName());
        // Keep a reference to the internal component manager
        componentManager = getComponentManager();
    }
... ...

伺服器裝載的模組功能(Modules),居然是被寫死寫死的!!!

好吧,我承認,在那個專案中,我改過Openfire的原始碼,為了把專案客製化的功能加到伺服器中去。

幫客戶做專案嘛,能夠達到專案目標,能夠按期交付,把款收回來就可以了啊!你還想幹嘛?

我還想幹嘛,是的,我還想幹嘛?

在那個瘋狂的年月,我想說,這個行業裡,人人都會有個網際網路英雄夢!

我也有夢,我有個社交領域的創業夢,我想去試試做這件事,幹這事需要使用實時通訊技術。

於是,我開始開始讀XMPP規範,我讀RFC3920(XMPP Core)RFC3921(XMPP IM)XEP-045(Multi-User Chat)... ...

讀了一些規範之後,我得出這樣的結論,Openfire恐怕達不到我的創業要求,我最好是自己來寫一個XMPP Server。

當然,憑我的技術能力,只要我願意,我可以去改Openfire的程式碼,最終也可以實現創業專案的功能需求。

問題是,在那時,對,這時候說的那時,已經是在10年前。在那時,我還是如此的理想化,如此對未來充滿了憧憬,我覺得自己可以幹翻一切,何況只是需要去實現一個實時通訊協定標準和產品。

我可以搞定,我會做得很好!就這樣定了,自己動手寫一個。

於是,有了BasaltChalkGranite這一系列XMPP基礎架構專案。

2年後,我去嘗試了自己的夢,使用XMPP來做自己的社交App專案。

專案最終失敗了,這些XMPP的程式碼,也暫時被封存在了程式碼倉庫裡。

初識IoT

春去秋來,潮起潮落,時光飛逝。

2018年,我來到了一家做IoT的創業公司做CTO。我是第一次做IoT專案,我認真上網查資料,理解技術,設計系統。

由於是第一次做IoT專案,我非常謹慎的選擇了技術方案。在閘道器到網際網路伺服器之間的網際網路通訊協定選擇上,我選擇了使用MQTT,看上去這是一個大眾流行的,也比較安全的解決方案。

產品做出來了,我們開始做推廣,完善產品,繼續融資,擴大推廣。

其實那次,我們已經有點接近成功了。我們部署了3.5k智慧鎖節點,融了Pre-A輪1600w。機構方說,你們下一階段的工作,就是1w個節點,然後融A輪,公司A輪估值不低於2億,後續融資的事你們不用管,我們會搞定一切,你們就專心努力完成業績要求。

然而,在經歷一系列的決策錯誤後,創業最終失敗了... ...

我又在思索了,在自己做社交創業失敗後,我又呆了兩家創業公司,做技術合夥人。一家做到A輪,一家做到Pre-A輪。然而,這兩家公司最終都失敗了。

因為這兩家創業公司,我放棄了去阿里巴巴的工作機會,也放棄了到一家銀行工作的機會(給的offer總包年薪超100w)。

我在重新思考自己的方向,畢竟年齡也不小了,我應該尋求穩定不是嗎?

再遇IoT

我選擇了一家上市公司的中央研究院,他們的專案,又是IoT,做智慧城市裡的智慧路燈杆。

我和IoT之間,情緣未了!

MQTT vs. XMPP

我對MQTT還是非常熟悉的,我用它做過IoT應用,開發過IoT產品。

我對XMPP應該說算是精通了,我寫過XMPP基礎開發庫、XMPP伺服器、實現過XMPP的各種標準,並基於XMPP做了了IoT開發平臺。

我嘗試客觀的來評價這兩種協定,如果拋開我更擅長XMPP,以及Lithosphere基於XMPP技術開發的主觀立場,我如何評價這兩種協定呢?

以下兩種協定的對比,包括對兩種協定的優劣點評價,以及針對協定缺點的解決方案討論,都基於我個人觀點。受個人知識面和經驗的限制,如果有評價不準確,沒找對好的解決方案思路等問題,請網友們給予批評指正。

交流,就是想跟大家交流,分析問題,尋求答案,不在於爭論對錯,而是想找到對兩種協定客觀、正確的理解。

MQTT

優點
  • 輕量級,效能好

    MQTT協定被設計得輕巧且高效能,最小MQTT的協定包尺寸為2位元組。
  • 內建QoS支援

    MQTT協定內建3種QoS:
    • At Most Once
    • At Least Once
    • Exactly Once
  • 簡單、容易學習

    我大概看了一下午的資料後,就基本上理解清楚了MQTT協定,然後開始分析設計在IoT專案裡該怎樣用它了。
缺點
  • 缺少P2P通訊機制

    MQTT使用者端並沒有一個全域性的、永續性的唯一Client ID,MQTT使用者端的Client ID在每次連線到Broker時,由使用者端指定或由Broker來自動生成。

    那麼,當我們想想做特定使用者端的指令控制型別操作時,就會比較不方便了,因為:

    • 我們沒有一個穩定的裝置終端Client ID可用。
    • 即使我們拿到了Client ID,由於MQTT並沒有提供給特定Client直接推播訊息的通訊機制,我們需要通過其它繞彎的方法,來給特定Client傳送訊息。

    解決方案討論:

    比較常見的解決方案是,為每個使用者端,建立一個和使用者端Client ID相關的,私有專用的訊息接收Topic,用於接收傳送給這個使用者端的的訊息。

    例如,我們約定,當用戶端程式連線Broker成功後,使用者端程式會立即開始監聽名為Clients/<CLIENT_ID>的Topic,通過往這個專用Topic裡傳送訊息,我們就間接實現了P2P的訊息通訊。

    在這個約定下,一個使用者端連線成功後,如果它的Client ID是"1234567890",那麼使用者端連線成功後,這個使用者端就開始監聽名為"Clients/1234567890"的Topic。那麼往這個Topic裡publish的訊息,這個使用者端就可以收到。

    需要考慮的一個問題是安全性問題,因為我沒有在MQTT的規範裡,讀到有關於主題訂閱的許可權限制的內容。那麼,一個使用者端在理論上,是可以監聽到其它使用者端的私有專用訊息通道的。也許可以考慮給私有訊息都用私鑰加密,來提供更好的安全性。

  • 沒有應用層協定

    MQTT提供了一條通訊層的通道,你可以用這個通道來傳輸任何格式的資料。

    這個東西有利有弊吧,有利的地方在於靈活性,開發者可以自由的定義任何格式的應用層協定,不受任何規則限制。不利的地方在於,大部分應用開發者,其實並沒有足夠的知識和經驗,可以設計出足夠好的應用層協定。

  • 實時性差

    訊息實時性和資料可靠性,這兩個特性看上去是魚與熊掌,往往需要我們做出選擇與權衡。

    在MQTT中,設定了QoS.AT_LEAST_ONCE和QoS.EXACTLY_ONCE的訊息,實時性會比較差。

    我們在智慧鎖的專案裡,曾做過以下的測試。

    我們保持行動端和伺服器端之間的通訊暢通,斷開伺服器到鎖終端裝置之間的通訊通道。

    然後我們從App端傳送開鎖指令給鎖終端,由於通訊線路被斷開,這時鎖是不能被開啟的。

    2分鐘之後,我們將和伺服器端和鎖終端裝置之間的通訊線路恢復正常,這時候,鎖被開啟了。

    解決方案討論:

    • 在需要實時性的場合,儘量使用QoS.AT_MOST_ONCE。
    • 在應用層協定的控制指令中,包含一個指令過期時間戳。終端裝置收到指令後,檢查這個時間戳,如果指令已超時就放棄執行指令。

XMPP

優點
  • 提供P2P通訊機制

    在XMPP網路中,任何需要連線到XMPP伺服器的節點(Node),無論它是人(User)或者是物(Thing),都需要有一個全域性的XMPP賬號。在XMPP概念裡,這個賬號叫做Jabber ID。

    使用聯絡人/物的Jabber ID,就可以給它傳送直接訊息(前提為許可權允許,例如:聯絡人在好友列表中)。

    對於遠端控制型別的IoT應用來說,這簡直太方便了。

  • 實時性強

    XMPP就是一個實時通訊協定,實時性強是它的協定特徵。

    在一些IoT應用場合,我們就是需要更好的訊息實時性。

    我一條控制指令發過去,指令正確到達且正確執行了,你就返回正常執行確認;如果執行失敗,你就返回對應錯誤碼;如果不能確認執行結果,請告訴我超時了,讓程式來處理超時邏輯。

    無論啥情況,請立馬告訴我,而不是2分鐘後再突然執行指令。Ok,這就是我們需要的實時性。

    以下的程式碼來自Lithosphere的sand-demo,它示範了這種實時性需求。

    ... ...
    
    private static class RemotingActionCallback implements IRemoting.Callback {
    	... ...
    
    	@Override
    	public void executed(Object xep) {
    		// Code for action has executed correctly.
            activity.runOnUiThread(() -> Toast.makeText(activity,
    				"Action has executed.",
    				Toast.LENGTH_LONG).show());
    	}
    
    	@Override
    	public void occurred(StanzaError error) {
    		// Code for error occurred.
            String errorText = "Action execution error: " +
    				(error.getText() == null ? error.toString() : error.getText().getText());
    		remotingErrorOccurred(activity, error, errorText);
    	}
    
    	@Override
    	public void timeout() {
    		// Processing logic for timeout.
            activity.runOnUiThread(() -> Toast.makeText(activity,
    				"Action execution timeout.",
    				Toast.LENGTH_LONG).show());
    	}
    }
    
  • 協定擴充套件性強,內建應用層通訊協定基礎規則

    XMPP和MQTT的設計思路有些區別。

    MQTT協定的關注點,在於如何在網路層提供一條可信賴通道。然後吧,你願意在這個通道上做啥就做啥,我協定是不管你任何應用層的事情的。

    XMPP的協定特徵之一,是具有很強的可延伸性。XMPP全稱Extensible Message and Presence Protocol。XMPP裡的X,是Extensiable(可延伸)的意思,表達了XMPP協定的這個協定特徵。

    XMPP協定被分成兩部分,一部分是核心標準規範,包括XMPP Core(RFC3920)XMPP IM(RFC3921)

    另一部分是XMPP的擴充套件協定,XEPs(XMPP Extension Protocols)。XEPs協定族裡,包含了大概300多個協定,這些協定覆蓋的內容範圍,簡直包羅萬象。這當然證明了XMPP協定的超強擴充套件性特徵。



    XMPP協定族覆蓋的內容很多,既包含了網路層的協定,也包括應用層協定。

    例如,User Avatar(XEP-0084)。這個協定當然是一個應用層協定,這個規範定義了在實時通訊系統中,使用者虛擬身份使用的解決方案。

    在XMPP的標準規範XMPP Core(RFC3920)中,定義了XMPP協定的一堆基礎規則,包括:

    • XMPP協定的系統架構。
    • XMPP訊息的基本結構格式。
    • XMPP訊息的錯誤處理規則。
    • 伺服器端訊息處理原則。
    • ... ...

    好吧,你當然可以認為,這麼多規則,嚴重限制了開發者的想象力嘛!

    我會這樣認為,這是設計出色的應用層通訊協定的一個良好基礎。

缺點
  • 基於XML,通訊效率差

    這應該是XMPP協定受到最多攻擊的一個問題了。XMPP太重了,XMPP不適合行動網際網路,更不適合物聯網。

    解決方案討論:

    • 在通訊中,使用流壓縮協定

      可以考慮實現官方XEPs協定裡的Stream Compression(XEP-0138),或者實現自己的流壓縮私有協定。
    • 實現二進位制XMPP

      這是目前我能看到的最佳解決方案。

      一個公司給我們做出了最佳示範!是的,WhatsApp使用標準XMPP的二進位制變種(WhatsApp公司把這個二進位制變種協定叫做FunXMPP)來提供全球20億使用者的IM服務。

      好吧,就我知道的,還有另外一個公司,也使用了二進位制XMPP。Apple公司使用XMPP的二進位制變種協定來提供APNs(Apple Push Notification service),為全球IPhone手機提供伺服器端推播服務。

      請問開源二進位制XMPP實現?

      開源二進位制XMPP實現,請考慮使用Lithosphere平臺裡的BasaltChalkGranite

      好吧,我知道的就只有這麼多了,如果其他網友知道其它開源專案的二進位制XMPP協定支援,還請不吝賜教!
  • 缺少內建的QoS支援

    MQTT是一個輕量級的MQ,QoS基本上是MQ軟體的標配,MQTT也不例外。

    XMPP由RFC標準協定加上XEPs組成,在RFC標準協定中,並沒有要求提供QoS支援。

    對於資料上報型別的IoT應用,QoS是非常必要的。

    解決方案討論:

  • 實現QoS協定

    XMPP的XEPs裡,目前還缺少關於QoS的正式標準。

    可以看到有一個草稿標準Quality of Service(XEP-xxxx)。需要注意的是,這個標準目前的狀態,還是XEPs的草稿標準(ProtoXEP)狀態,這表示這個規範還未能通過XSF(XMPP Standards Foundation/XMPP標準基金會)的標準審批過程。

    我讀了一下這個XMPP的QoS草稿標準,這個規範裡的XMPP QoS實現,看上去和MQTT規範裡要求的QoS實現,幾乎沒有什麼區別。

    區別只在於,兩個協定的QoS控制指令的術語叫法不一樣。比如:

    • MQTT裡的PUBREC指令,在這個XMPP QoS規範裡,叫做qos:acknowledged
    • MQTT裡的PUBREL指令,在這個XMPP QoS規範裡,叫做qos:deliver。
    • ... ...

    雖然這只是一個草稿標準,但是由於這個XMPP標準對應的QoS處理邏輯,看上去和MQTT標準裡的QoS實現邏輯,幾乎沒有什麼區別。理論上,可以認為,實現這個XMPP草稿規範後,就可以為你的XMPP實現提供QoS支援了。

  • 缺少IoT相關規範和開源產品實現

    XMPP社群的夥計們,有在積極的探索XMPP在IoT領域的應用,我們可以看到社群在這個方向上的一些工作,比如:

    但是目前的狀況看上去,XMPP雖然在實時通訊領域取得了很大的成功,但是在IoT應用領域,XMPP還是小眾技術。

    IoT方向上相關的標準規範,都還是草稿狀態,並沒有進入正式的標準化過程。

    在開源產品實現上,做了IoT支援的開源產品還比較少,而且實現都還比較不完善。我能看到的,以下XMPP開源產品有提供IoT相關的功能:

  • 實現較為複雜,學習成本高

    XMPP和MQTT,在協定的設計思路上,有著比較大的差異。

    MQTT:Hi,朋友!我會給你一個速度快、簡單好用、安全可靠的通訊通道。Ok,我的工作做完了!你願意在上面幹嘛就幹嘛,我是不管的,請別再來找我了。

    XMPP:我們會提供一個靈活、強大的網路通訊協定,它的靈活性來自高擴充套件性,它的強大來自我們提供了幾百個實時通訊相關標準。我們希望這一把能徹底搞定實時通訊領域的各種問題!

    什麼,還缺少IoT相關標準?缺少IoT開源產品實現?目前就是這狀況哦!請你深刻理解XMPP技術,自行定義私有IoT通訊協定來解決問題。可以做到的!你放心,XMPP技術相當靈活!可以做到的!我們對你有信心!

    和MQTT的完全自由有所不同,如果你使用XMPP協定,你需要遵循協定標準中的一些規則和要求。由於XMPP協定較MQTT協定複雜,功能更多,正常來說,會需要更多的入門學習時間。

    從另外一個角度來看,如果是已有的XMPP協定規範,如果是第三方產品中已經實現了的XMPP擴充套件協定功能呢?那可是現成的東西直接拿來用起,爽不爽?

    解決方案討論:

    • 等待

      耐心等待XMPP開源專案為產品新增IoT相關的功能;期待XSF(XMPP Standards Foundation)能推動各種XMPP IoT協定的標準化。
    • 自己動手幹

      已經有一些商業公司在用XMPP來幹IoT了。例如,Google雲通過Firebase Cloud Messaging (FCM) 來提供IoT雲服務。它使用的就是XMPP協定。

      大家都急切期待著功能強大的開源產品實現?

      好吧,Lithosphere開源專案正在加油努力中... ...

哪一個在IoT中是更好的?

兩個協定都可以用於IoT應用。這兩個協定存在著明顯的差異,不能說哪個是更好的,需要結合應用需求,團隊技術能力和技術積累等各種因素,對技術選型進行綜合考慮。

MQTT

MQTT協定非常適合用在感測器網路為主,資料上報型別的應用中。MQTT的Public-Subscribe模式,以及QoS支援,似乎就是專門為這型別的應用來設計的。

所有的感測器裝置,在上報資料中,只需要帶上裝置身份標識,帶上資料採集時的時間戳,統一上報到資料處理的Topic通道去。

其它事,讓伺服器去幹。

夠用、簡單好用,很爽!

XMPP

XMPP的優勢在於它的靈活性以及實時性。

如果你的IoT應用,會有複雜的通訊控制邏輯,以及有很高的實時性通訊需求,值得考慮XMPP。

結論

  • MQTT最大優勢,應該是它的簡單易用性。能不能不要花那麼多時間來學習通訊技術了,能不能儘快開始編碼開搞應用需求?

    MQTT的短板,似乎是它的基礎架構只提供了較單一的通訊機制,當我們碰到一些通訊上的複雜需求時,我們需要做更多工作來解決問題。當然,我們可以:

    • 可以在上層應用層,做一些輔助工作,來幫助解決應用的通訊複雜性。
    • MQTT目前在IoT這個方向上,是一個主流的協定。

      各個使用MQTT協定的IoT服務廠商,會提供各種問題的設計模式、解決方案、甚至寫好的開發元件來幫助客戶。

      應用開發商可以尋求IoT服務廠商的商業解決方案支援。
  • XMPP的優勢在於它的靈活性。如果我有很複雜的通訊邏輯需要處理;如果我想在通訊層上面提供一個更易用的元件開發模型,XMPP可以幫你實現這些複雜需求。

    但是需要考慮問題是,你真正理解和學會XMPP了嗎,你能在自研的或者第三方XMPP基礎件上,自由的開發XMPP擴充套件協定了嗎?

  • 兩者都還不夠好!

    標準的MQTT,標準的XMPP,在IoT應用中都還不夠好!不夠用!不能夠覆蓋到IoT裡各種複雜應用需求。我們往往需要在標準協定之上,再做很多的工作來解決問題。

    連線萬物,哪有這麼簡單!

為何Lithosphere使用XMPP

  • 都不夠好,不夠用

    標準MQTT,標準XMPP,對於連線萬物的IoT來說,都還不夠好!不夠用!

    MQTT對於感測器資料上報型別的應用,把資料安全傳輸到伺服器端,然後伺服器端一步去做資料分析,去做巨量資料,搞AI。對於這種型別的應用來說,MQTT夠用的。

    對於一些更復雜的IoT通訊需求,MQTT的通訊機制太單一了,不夠用,舉兩例子吧:

    • IoT本地網通訊

      按照MQTT Specification裡的說法,目前MQTT協定只能跑在TCP/IP(可選WebScoket)網路上。在IoT本地網如LoRa,Bluetooth... ...這些協定上,MQTT跑不了。

      下圖截自MQTT 3.1.1 Specification
    • 音視訊串流媒體通訊

      由於在我做過的兩個IoT應用中,都有實時串流媒體的通訊需求。我會假設對實時串流媒體通訊的支援,是IoT應用的剛性需求。

      標準MQTT協定並不支援這個事,在MQTT協定上做這個事,也比較難做實現。

    標準XMPP,也不夠好!也不夠用!缺少IoT標準,市場上的開源產品普遍缺少IoT功能的支援。

  • XMPP擴充套件性更好,更容易在協定層去做擴充套件功能

    XMPP的協定特徵之一,就是高擴充套件性。如果要選其中一個協定來做協定層的擴充套件,XMPP看上去會方便很多。

  • 基於我自己寫的XMPP開源基礎件,我可以用XMPP做到任何事

    這個肯定是最重要的因素了,最終決定了Lithosphere的通訊協定技術選型。

    如果我當年不是因為想做社交App創業,去寫了XMPP庫,XMPP伺服器。如果當年因為機緣巧合,我寫了MQTT的開源專案,那我現在會怎麼選擇?

    人生沒有如果!

    假設一下嘛,哈哈。

    我想,我應該會選擇做基於MQTT的IoT解決方案。

    人生沒有如果!我現在就是寫了XMPP開源基礎件,我就用這些XMPP基礎件,寫了Lithosphere。

    • XMPP太重了,不適合物聯網?

      那我做二進位制XMPP支援。
    • XMPP標準中缺少QoS支援?

      那我實現QoS擴充套件協定,MQTT可以有,為啥XMPP不可以有?
    • XMPP裡缺少IoT的標準

      這不叫事,XMPP可以寫標準協定,也可以寫私有協定。

      Lithosphere目前已實現的部分IoT擴充套件通訊協定:
      • 裝置註冊

        TUXP:IBTR Protocol - 智慧物件線上註冊協定。
      • 事件通知

        TUXP:Notification Protocol - 智慧物件事件通知協定。
      • 遠端指令控制

        TUXP:Execution Protocol - 智慧物件遠端命令執行協定。
      • 資料上報

        TUXP:Report Protocol - 智慧物件資料上報協定。
      • LoRa動態地址分配

        TUXP:LoRa-DAC protocol - LoRa網路動態地址分配協定
      • 實時視訊監控

        LEPs:WebRTC:Signaling Protocol - 基於WebRTC的實時流訊號協定
      • ... ...
    • XMPP產品目前缺少對IoT本地網路協定的支援

      就是讓XMPP跑在LoRa上、跑在Bluetooth上、跑在Mudbus上,跑在... ...上嘛,是吧?

      沒問題,別的產品不支援,Lithosphere來支援。Mud庫就是用來幹這事的。

      Lithosphere是全棧的開發框架,不僅在網際網路閘道器端到伺服器端,Lithosphere還嘗試對IoT應用中所有端提供支援。

      基於統一的TUXP協定,Lithosphere可以覆蓋到IoT應用的通訊所有端。

      目前版本做了WiFi、LoRa協定實現,後續版本會陸續支援其它本地IoT網路協定。敬請期待!

      不是狂,我可以用XMPP做到任何事情!

使用XMPP的效果如何?

哈哈,可以看看我寫的Hello,Lithosphere系列教學,你來做評價。

如果是想要評估Lithosphere的功能和技術效果,建議看這兩篇教學。

Hello, LoRa!

這個教學裡覆蓋了IoT協定的整個通訊流程,包括IoT終端裝置整合(MCU板)、IoT LPWAN協定通訊(LoRa通訊協定)、IoT通訊閘道器、IoT通訊伺服器端處理。

Hello, WebRTC!

使用封裝好的WebRTC的Webcam外掛,做一個實時監控攝像頭,這事還挺簡單的。

關於MQTT vs. XMPP的話題,就聊這麼多了!