通過上一節我們對MQTT協議已經有了初步的印象,這一節我們開始深入的理解一下MQTT協議,介紹常用的MQTT 3.1.1版本,5.0版本后面指介紹新增部分即可。這一節我們先介紹MQTT里常用的術語(非官方文檔直接復制)。
網絡連接(Network Connection):
MQTT 是一種連接協議,底層使用 TCP/IP (傳輸層協議)提供網絡連接,提供有序、可靠的、雙向字節流傳輸。這個連接需要互聯網通信的基礎設施支撐,客戶端使用它連接到服務端(MQTT代理服務的服務器或服務器集群)。
會話(Session):
客戶端與服務端通過網絡連接后的信息通道,服務端會有一個唯一的標志識別,也是狀態交互的反映。通常一個會話就是一個網絡連接,有些網絡環境也可能將一個會話會擴展幾個網絡連接為之服務。
應用消息(Application Message):
使用MQTT協議通過網絡連接傳輸的應用數據,也就是客戶端與服務端之間交互的應用數據。應用消息通過MQTT傳輸時, 會有攜帶服務質量(QoS)和主題(Topic)等信息內容的。
服務端(Server) / 代理(Broker):
一個服務程序或設備,為消息發送方和消息訂閱方提供中介服務,為發送方和訂閱方提供中轉分配處理,這個服務程序也稱之為代理(Broker)。要處理來自客戶端的網絡連接、發布的應用消息,處理保存客戶端的訂閱和取消訂閱,將應用消息轉發給符合訂閱條件的客戶端,關閉客戶端發出斷開連接請求的網絡連接等。
客戶端(Client):
是與服務端對應的,使用MQTT為客戶提供本地服務的程序或設備。客戶端總是先發起連接請求通過網絡連接到服務端。它可以:打開連接到服務端的網絡連接、通過服務端發布應用消息給其他相關的客戶端、訂閱並接收相關的應用消息、取消訂閱並不再接收相應消息、關閉與服務端的網絡連接等。
主題(Topic):
標注應用程序消息的標簽,訂閱者用它來確定接收到所關心的消息,服務端代理服務會將消息轉發給訂閱者所匹配標簽的每個客戶端。主題名是一個分層的結構,可以有多個級別,級別之間用斜杠分隔。例:area-a/building-6/floor-8 代表A區6棟5層的設備發出的主題。
訂閱者的主題名支持通配符#和+,可以通過通配符進行匹配過濾:
+為只匹配主題一個層級的通配符,例:area-a/+/floor-8 代表A區任何一個樓的8層的設備。
#為匹配主題該層級向后任意級別的通配符,例:area-a/# 代表A區的所用設備。
發布(Publish):
從MQTT客戶端向MQTT服務端主動發送主題消息,或MQTT服務端向MQTT客戶端主動發送主題消息(這種情況很少)。主題消息中包含着服務質量(QoS)等級。
訂閱(Subscription):
訂閱的過程與我們生活中向郵局訂閱雜志類似,只不過是客戶端向服務端訂閱,訂閱的是主題消息而不是雜志。當服務端的代理服務發現有客戶端發布了某客戶端訂閱的主題消息時,就會把該主題消息轉發給訂閱了該主題消息的那個客戶端。訂閱的主題會與某個單一會話(Session)關聯,一個會話可以關聯多個訂閱。每個訂閱都包含一個主題過濾器(Topic Filter)和一個最大的服務質量(QoS)等級。
主題過濾器(Topic Filter):
是一個針對主題名過濾的篩選器,在訂閱表達式中使用,表示訂閱所匹配到的一個或多個主題。
服務質量(QoS):
表示發布者發布的主題到達代理和目標客戶端的可靠性要求,MQTT服務質量分三個等級:
QoS =0,至多一次,有可能會丟包,一般用在對實時性要求不高並且會有新的數據覆蓋舊的數據的場景。例如,某個溫度傳感器的數據上報,間隔一定時間上報一次,每次都更新服務端數據庫中的記錄。這樣對於是否丟失某次上報的數據並不太重要,因為稍候還會上報新的數據上來更新到最新。
QoS =1,至少一次,確保到達目的地,但是有可能出現數據重復發送的現象,訂閱者可能會收到重復的數據包。
QoS =2, 剛好一次,確保到達目的地,並且不會出現數據重復發送的現象。
遺囑消息(Will Message):
遺囑消息一般是在客戶端 發起連接的時候指定的。是客戶端預先定義好的一個主題消息,代表在自己異常斷開的情況下,所留下的最后遺願(Last Will),也稱之為遺囑。在客戶端連接出現異常的情況下,由服務端代理服務主動發布此消息,訂閱此消息的其他客戶端就收到了這個客戶端離線的遺囑消息了。也就是你希望一個客戶端離線后,用什么信息內容通知關心這個客戶端離線的其他客戶端。
控制報文 (MQTT Control Packet):
在MQTT協議框架下通過網絡連接發送的信息數據包。MQTT規范定義了十四種不同類型的控制報文,其中PUBLISH報文是用於傳輸發布應用消息的。控制報文中最多包含三部分,依次分別是固定報頭、可變報頭、有效載荷。
固定報頭(Fixed header):
是控制報文的最開始部分,代表着這個報文的具體作用和其他一些控制配置信息等。固定報頭長度固定為2個字節起,后面會有詳解。
可變報頭(Variable header):
一個控制報文需要攜帶的控制信息量較多,就在固定報頭后面增加了可變報頭,一般也是2個字節長度,后面會有詳解。
有效載荷(Payload):
是控制報文的最后一部分,包含主題名和我們需要攜帶的自定義的應用消息。例如我們要通過MQTT協議發送一個字符串“hello”,那這個“hello”字符串就是在有效載荷部分。
心跳(PINGREQ):
是為了保證服務端知道客戶端的連接還在正常保持着,在沒有必要的應用消息發出的時候,會在一定時間間隔發出一個很短的特定數據包,用於通知服務端,這個客戶端連接正常。在沒有業務邏輯需要主動發布消息的時候,網絡連接就是靠這個有着固定時間間隔規律的數據包發送來維持連接正常的,這就像心臟跳動一樣,有心跳知道這個人還活着,因此而得名!
本節完,待續......
