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 、所屬組、位置等,可以實現更靈活和精確的控制