網絡上搜索MQTT協議,會出現太多的解釋,這裏就不作官方標準釋義的複製了。這一節咱們從實戰理解角度,通俗的將MQTT協議的做用及實現原理說一下,旨在能夠快速理解MQTT協議。因此可能會出現不少看似不標準的解釋,可是更容易理解MQTT的內涵,對MQTT十分精通者請忽略此文。服務器
在物聯網項目中,常常出現的要求是「有限環境」。什麼意思呢,通俗說就是網絡可能不太穩定,帶寬也可能很小,網速也比較低,硬件MCU性能也很低,要求在這種狀況下也能可靠聯網傳輸信息。看到這裏你們就會想到我前面提到的短指令中說到的問題了,不是咱們認爲開發容易好維護就能夠的,首先要知足工做環境的須要,項目才能夠成功落地,不然都是無用功。網絡
在N年前最初嘗試作物聯網項目的時候,不少用HTTP協議作硬件設備信息的上報,利用返回結果控制硬件設備執行的項目(其實如今也有人還在使用)。這樣硬件設備信息上報的即時性沒有問題,但通過服務端發送控制指令去操控硬件設備的時候,及時性就很難知足。由於HTTP是單方向主動請求服務器,有請求才有返回,返回後就斷開了。要想服務端與硬件設備再有聯繫,只能等硬件設備經過HTTP的下一個請求上來才能夠,也就是服務端不能主動推送消息給硬件設備。看到這裏可能會有不少人會說出N多種基於HTTP服務端推送的方案,可是很抱歉,在物聯網環境中都不適合。由於不管是輪詢仍是長鏈接,用HTTP維持所消耗的網絡資源和硬件性能要求對項目來講都是高昂的,必須考慮項目落地要求的「有限環境」。對於網絡不穩定和帶寬低(好比移動網絡、信號弱的區域等)的環境,極大可能形成項目運行失敗,這是不能接受的結果。異步
那麼爲何推薦MQTT協議呢?由於MQTT協議具有如下幾點特徵:
一、網絡開銷小,消息頭最小隻有2字節,這相比HTTP大大下降了網絡流量。
二、是可保持的會話,爲實現服務端及時推消息提供了條件。
三、是異步消息機制,不會阻塞佔用資源。
四、具有異常中斷通知機制,能夠得到硬件在線信息變化,及時獲得掉線消息。
五、使用發佈/訂閱消息模式,一對多或多對一的消息傳輸,實現與應用程序的解耦。
六、傳輸可靠性可控,及三種服務質量,分別是至多一次、至少一次、只有一次。指的是發佈者發出的信息,代理服務和訂閱者是否收到的狀況。
七、客戶端程序夠輕量,可在不少嵌入式設備中運行。
八、可知足低帶寬、高延遲、不穩定的網絡環境。性能
MQTT協議中,須要兩個端,分別是服務端和客戶端;有三個身份,分別是發佈者(Publish),代理(Broker)、訂閱者(Subscribe)。
在MQTT協議中,客戶端不能直接對客戶端實行端到端的收發消息,必須通過服務端管理分配,因此服務端要運行一個代理服務,也就是三個身份之一的代理身份。消息的發送方稱爲發佈者,該消息的須要接收者稱之爲訂閱者。發佈者把消息發送給代理,代理負責檢查都誰須要接收這個消息(這個就是訂閱),須要的就轉發給它。由於要識別不一樣的消息,因此MQTT協議制定了主題標準,也就是給消息加上了標籤。發佈者發送的消息老是要帶上標籤的,代理根據誰訂閱了這個標籤來決定轉發給誰,這個標籤就稱之爲主題(Topic),標籤攜帶咱們須要傳輸的信息內容稱之爲負載(Payload)。設計
爲了實現異常中斷通知機制,因此在客戶端與服務端首次鏈接的時候,就要攜帶一條相對特殊的主題,主題內容是若是本身掉線了,但願告知須要知道本身掉線一方一些信息,這就是遺囑消息(Will Message)。這個主題本身在線時,代理不會作任何轉發,當本身掉線達到必定時間(即心跳間隔Keep Alive timer),代理會檢查誰訂閱了這個主題,就轉發給誰(固然能夠多人訂閱),這就實現了異常中斷(掉線)通知。代理
下面繼續深刻理解一下MQTT協議的工做過程。blog
發佈者、訂閱者、代理與主題發佈與訂閱間的關係:
經過上圖,咱們能夠看出,同一個客戶端既能夠是發佈者,也能夠是訂閱者。一個主題只有一個發佈者,可是能夠有不少個訂閱者。一個客戶端也能夠訂閱多個主題。資源
客戶端鏈接到代理:
工做的第一步是創建鏈接,MQTT協議也是創建在TCP/IP基礎上的通訊協議,首先要在客戶端與代理服務端創建一個TCP鏈接。創建鏈接的過程是由客戶端主動發起的,代理服務一直是處於指定端口的監聽狀態,當監聽到有客戶端要接入的時候,就會馬上去處理。客戶端在發起鏈接請求時,攜帶客戶端ID、帳號、密碼(無帳號密碼使用除外,正式項目不會容許這樣)、心跳間隔時間等數據。代理服務收到後檢查本身的鏈接權限配置中是否容許該帳號密碼鏈接,若是容許則創建會話標識並保存,綁定客戶端ID與會話,並記錄心跳間隔時間(判斷是否掉線和啓動遺囑時用)和遺囑消息等,而後回發鏈接成功確認消息給客戶端,客戶端收到鏈接成功的確認消息後,進入下一步(一般是開始訂閱主題,若是不須要訂閱則跳過)。上圖只作了鏈接成功的示意圖,鏈接失敗和拒絕先腦補一下便可,後面會設計到更具體的。開發
客戶端訂閱主題:
客戶端將須要訂閱的主題通過SUBSCRIBE報文發送給代理服務,代理服務則將這個主題記錄到該客戶端ID下(之後有這個主題發佈就會發送給該客戶端),而後回覆確認消息SUBACK報文,客戶端接到SUBACK報文後知道已經訂閱成功,則處於等待監聽代理服務推送的消息,也能夠繼續訂閱其餘主題或發佈主題。基礎
客戶端發佈主題:
當某一客戶端發佈一個主題到代理服務後,代理服務先回復該客戶端收到主題的確認消息,該客戶端收到確認後就能夠繼續本身的邏輯了。但這時主題消息尚未發給訂閱了這個主題的客戶端,代理要根據質量級別(QoS)來決定怎樣處理這個主題。因此這裏充分體現了是MQTT協議是異步通訊模式,不是當即端到端反應的。
若是發佈和訂閱時的質量級別QoS都是至多一次,那代理服務則檢查當前訂閱這個主題的客戶端是否在線,在線則轉發一次,收到與否再也不作任何處理。這種質量對系統壓力最小。
若是發佈和訂閱時的質量級別QoS都是至少一次,那要保證代理服務和訂閱的客戶端都有成功收到才能夠,不然會嘗試補充發送(具體機制後面討論)。這也可能會出現同一主題屢次重複發送的狀況。這種質量對系統壓力較大。
若是發佈和訂閱時的質量級別QoS都是隻有一次,那要保證代理服務和訂閱的客戶端都有成功收到,並只收到一次不會重複發送(具體機制後面討論)。這種質量對系統壓力最大。
代理最終將主題消息轉發給訂閱者,至少是作了轉發操做,成功與否決定質量等級。更詳細的消息質量等級控制後面會有專門詳細敘述。
關於MQTT協議的實現原理通俗解釋就到這裏,但願能讓剛剛接觸MQTT的開發者有個總體流程的印象和理解,後面會詳細討論MQTT協議的定義、配置等。
本節完,待續......