MQTT-主題基礎

木子七發表於2023-04-27
MQTT主題
  • MQTT的主題是一個utf-8編碼的字串,最大長度65535位元組,嚴格區分大小寫

  • MQTT主題支援分層結構,主題分隔符用'/'表示,主題的層級長度可以為0

    # 將主題劃分為3個層級
    'level1/level2/level3'
    # 第二層級長度為0
    'level1//level3	'
    # 下面三個level 實際屬於三個不同的主題 , /前後如果沒有內容視為一個長度為0的層級
    '/level' 
    'level' 
    'level/'
    
  • 主題層級的一個作用是和萬用字元配合使用訊息分發和主題訂閱,可以使用萬用字元實現一次訂閱多個主題的效果

主題萬用字元
  • 單層萬用字元: 用 '+'表示,可以匹配當前層級主題下的任意內容,不能同時匹配多個層級,單層萬用字元可以在一個主題中多次使用

  • # 三個主題,樓層下有三個房間,房間裡面有對應的資訊,第三個房間區分大房間標識
    topic1 = 'floor/room1/info'
    topic2 = 'floor/room2/info'
    topic3 = 'floor/room3/big/info'
    # 使用#匹配 樓下下 任意房間 的info
    # 單層萬用字元每次只匹配一個層級,所有無法匹配到topic3的主題
    'floor/+/info' # 匹配主題1和主題2
    
    # 同一主題中使用多個單層萬用字元
    'floor/+/+/info' #匹配主題3,每個萬用字元匹配一個層級
    
    
    # 特殊主題
    # 這種主題需要視為/前有長度為0的層級
    topic = '/floor'
    #匹配模式
    '+/floow' 
    '+/+'
    
  • 多層萬用字元: 用'#'表示,如果主題層級數量不固定,那麼單層萬用字元想做某一模式的通用匹配就失去了效果,可以使用多層萬用字元,多層萬用字元可以匹配任意數量個層級,包括0個層級,因為多層萬用字元匹配層級的不確定性,多層萬用字元必須是主題的最後一個字元

  • topic1 = 'home/'
    topic2 = 'home/floor'
    topic3 = 'home/floor/room'
    
    # 匹配home下的所有層級
    'home/#'
    
    
  • 單層和多層萬用字元可以同時使用,主題萬用字元必須完全的佔用一個層級

  • '''
    home/+/#
    +/+/#
    +/#
    '''
    
  • 只有在訂閱和取消訂閱的時候,才支援使用主題萬用字元,達到一次訂閱/取消訂閱多個主題的目的,在釋出訊息的時候,不支援使用主題萬用字元,必須要明確傳送訊息的主題,所以在訂閱和取消訂閱時候的主題稱為主題過濾器,釋出的時候的主題稱為主題名

特殊主題
  • 特殊主題概述

mqtt對主題沒有過多限制,可以任意命名,但是在主題中有一種特殊主題,是以$開頭的主題,被保留為僅供服務端使用,客戶端被禁止使用,不能釋出訊息,如果設定允許訂閱的話,可以訂閱$系統主題接收系統訊息,比如客戶端上線、下線等

  • 訂閱$開頭的主題

    訂閱$開頭的主題,$所在層級不能使用萬用字元匹配,但是$之後的層級可以使用萬用字元匹配

    topic = '$SYS/'
    
    '$SYS/+'
    '$SYS/#'
    #不能直接使用萬用字元匹配$所在層級
    
主題使用的一些建議
  • 主題可以視為釋出訂閱的核心,所以設計主題是重中之重

  • 不建議以/開頭或者結尾

    以/開頭或者結尾是協議允許的用法,但是並沒有什麼實際意義,還容易造成混淆,所以不建議主題以/開頭或者結尾

    比如 /a 和a/ ,在前後有對應的長度為0的層級,需要額外匹配,也沒有實際意義

  • 建議使用ASCLL字元

    mqtt主題定義只要是utf8字串即可,但是在實際應用中,非ascll字元可能會遇到無法列印或者列印錯誤的問題,對於一些問題定位不太友好

  • 不在主題中使用空格

    如果主題中在層級中包含空格,但是使用過程中,我們肉眼很難區分是否有空格,所有也不建議使用空格

  • 儘量使用簡潔的主題

    主題存在於我們訂閱和收發訊息的所有場景,使用不會引起歧義的縮寫,簡潔明瞭,縮短主題長度,對單個訊息影響不大,如果訊息量級特別大,帶來的收益就比較可觀了,簡短的主題都有助於我們減少頻寬消耗和提升處理效率

  • 不建議使用#訂閱所有主題

    單獨用#訂閱所有主題,會訂閱所有訊息,很可能訊息量龐大或者接收一些意外的訊息,影響效能和實際效果,最好是配合前置層使用#匹配

  • 在主題中包含標識資訊

    在主題中包含一些標識資訊,比如客戶端ID 、所屬組、位置等,可以實現更靈活和精確的控制

相關文章