一、簡述
MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸協(xié)議),是一種基于發(fā)布/訂閱(publish/subscribe)模式的"輕量級"通訊協(xié)議,該協(xié)議構建于TCP/IP協(xié)議上。MQTT最大優(yōu)點在于,可以以極少的代碼和有限的帶寬,為連接遠程設備提供實時可靠的消息服務。作為一種低開銷、低帶寬占用的即時通訊協(xié)議,使其在物聯(lián)網(wǎng)、小型設備、移動應用等方面有較廣泛的應用。
發(fā)布訂閱模式:與請求/回答這種同步模式不同,發(fā)布/定義模式解耦了發(fā)布消息的客戶(發(fā)布者)與訂閱消息的客戶(訂閱者)之間的關系,這意味著發(fā)布者和訂閱者之間并不需要直接建立聯(lián)系。打個比方,我們要看雜志,如果沒有郵局的話,我們要看雜志,只能通過出版社將雜志發(fā)給消費者。如果有了郵局的話,只要告訴郵局我們所要訂的雜志名、投遞的地址,付了錢就OK。出版社定期會將出版的雜志交給郵局,郵局會根據(jù)訂閱的列表,將雜志送達消費者手中。這樣我們就可以看到每一期精彩的雜志了。

MQTT是一個基于客戶端-服務端的消息發(fā)布/訂閱傳輸協(xié)議。MQTT協(xié)議是輕量、簡單、開放和易于實現(xiàn)的,這些特點使它適用范圍非常廣泛。在很多情況下,包括受限的環(huán)境中,如:機器與機器(M2M)通信和物聯(lián)網(wǎng)(loT)。其在,通過衛(wèi)星鏈路通信傳感器、偶爾撥號的醫(yī)療設備、智能家居及一些小型化設備中已廣泛使用。

二、主要特性
MQTT協(xié)議工作在寬帶低、不可靠的網(wǎng)絡的遠程傳感器和控制設備通訊而設計的協(xié)議,它具有以下主要的幾項特性:
1、使用發(fā)布/訂閱消息模式,提供一對多的消息發(fā)布,解除應用程序的耦合。
2、對負載內容屏蔽的消息傳輸:
可以對消息訂閱者所接受到的內容有所屏蔽。(類似于屏蔽消息中的不良言論)
3、使用TCP/IP提供網(wǎng)絡連接:
MQTT 是一種連接協(xié)議,它指定了如何組織數(shù)據(jù)字節(jié)并通過 TCP/IP 網(wǎng)絡傳輸它們。設備聯(lián)網(wǎng),也需要連接到互聯(lián)網(wǎng)中,在大萬維的世界中,TCP 如同汽車,有輪子就能用來運輸數(shù)據(jù),MQTT 就像是交通規(guī)則。在網(wǎng)絡模型中,TCP是傳輸層協(xié)議,而 MQTT是在應用層,在 TCP 的上層,因此MQTT 也是基于這個而構建的,提高了可靠性。
4、有三種消息發(fā)布服務質量QOS:
“至多一次”,消息發(fā)布完全依賴底層TCP/IP網(wǎng)絡。會發(fā)生消息丟失或重復。這一級別可適用于如下情況,環(huán)境傳感器數(shù)據(jù),丟失一次讀記錄無所謂,因為不久后還會有第二次發(fā)送。這種方式發(fā)布消息,倘若你的智能設備在消息推送時未聯(lián)網(wǎng),推送過去沒收到,再次聯(lián)網(wǎng)也就收不到了。
“至少一次”,確保消息到達,但消息重復可能會發(fā)生。
“只有一次”,確保消息到達一次。在一些比較嚴格的計費系統(tǒng)種,可以使用此級別(錢包助手)。在計費系統(tǒng)中,消息重復或丟失會導致不正確的結果。這種最高質量的消息發(fā)布服務還可用于及時通訊類的APP的推送,確保用戶收到且只會收到一次。
5、小型傳輸,開銷很小,協(xié)議交換最小,以降低網(wǎng)絡流量。
整體上協(xié)議可拆分為:固定頭部+可變頭部+消息體,這就是為什么在介紹里說它非常適合"在物聯(lián)網(wǎng)領域,傳感器與服務器的通信,信息的收集"。
6、使用Last Will和Testament特性通知有關各方服務端異常中斷的機制。
Last Will:即遺言機制,用于通知同一主題下的其他設備發(fā)送遺言的設備已經斷開了連接。
Testament:遺囑機制,功能類似于Last Will。
注:上述兩種方式都是通過代理來完成通知。
三、MQTT協(xié)議原理
1、MQTT協(xié)議實現(xiàn)方式
實現(xiàn)MQTT協(xié)議需要客戶端和服務端通訊完成,在通訊過程中,MQTT協(xié)議中有三種身份:發(fā)布者(Publish)、代理(Broker)(服務器)、訂閱者(Subscribe)。其中,消息的發(fā)布者和訂閱者都是客戶端,消息代理是服務器,消息發(fā)布者可以同時是訂閱者。
MQTT傳輸?shù)南⒎譃椋褐黝}(Topic)和負載(payload)兩部分:
(1)Topic,可以理解為消息的類型,訂閱者訂閱后(Subscribe)后,就會收到該主題的消息內容(payload);
(2)payload,可以理解為消息的內容,是指訂閱者具體要使用的內容。
2、網(wǎng)絡傳輸于應用消息
MQTT會構建底層網(wǎng)絡傳輸:它將建立客戶端到服務器的連接,提供兩者之間的一個有序的、無損的、基于字節(jié)流的雙向傳輸。當應用數(shù)據(jù)通過MQTT網(wǎng)絡發(fā)送時,MQTT會把與之相關的服務質量(Qos)和主題名(Topic)相關連。
3、MQTT客戶端
一個使用MQTT協(xié)議的應用程序或者設備,它總是建立到服務器的網(wǎng)絡連接??蛻舳丝梢裕?/p>
(1)發(fā)布其他客戶端可能會訂閱的信息;
(2)訂閱其他客戶端發(fā)布的消息;
(3)退訂或者刪除應用程序的消息;
(4)斷開與服務器的連接
4、MQTT服務端
MQTT服務器以稱為“消息代理”(Broker),可以是一個應用程序或一臺設備。它是位于消息發(fā)布者和訂閱者之間,它可以:
(1)接受來自客戶端的網(wǎng)絡連接;
(2)接收客戶發(fā)布的應用信息;
(3)處理來自客戶端的訂閱和退訂請求;
(4)向訂閱的客戶轉發(fā)應用程序消息。
5、MQTT協(xié)議中的訂閱、主題、會話
(1)訂閱(Subscription)包含主題篩選器(Topic Filter)和最大服務質量(Qos)。訂閱會與一個會話(Session)關連。一個會話可以包含多個訂閱。每一個會話中的每個訂閱都有一個不同的主題篩選器。
客戶端在成功建立TCP連接之后,發(fā)送CONNECT消息,在得到服務器端授權允許建立彼此連接的CONNACK消息之后,客戶端會發(fā)送SUBSCRIBE消息,訂閱感興趣的Topic主題列表(至少一個主題),訂閱的主題名稱采用UTF-8編碼,然后緊跟著對應的QoS值
(2)會話(Session),每個客戶端與服務器建立連接后就是一個會話,客戶端和服務器之間有狀態(tài)交互。會話存在于一個網(wǎng)絡之間,也可能在客戶端和服務器之間跨越多個聯(lián)系的網(wǎng)絡連接。
(3)主題名(Topic Name),連接到一個應用程序消息的標簽,該標簽與服務器的訂閱相匹配。服務器會將消息發(fā)送給訂閱所匹配標簽的每個客戶端。
一個主題可以有多個級別,級別之間用斜杠字符分隔。例如:/message/medchart/default/2098230/android
訂閱者的Topic name支持通配符#(支持一個主題內任意級別話題)和+(只匹配一個主題級別的通配符),簡單來書就是#可以匹配多層主題,+只能匹配一層主題。
客戶端成功訂閱某個主題后,代理會返回一條 SUBACK 消息,其中包含一個或多個 returnCode 參數(shù)。
(4)主題篩選器(Topic Filter),一個對主題名稱通配符篩選器,在訂閱表達式中使用,表示訂閱所匹配到的多個主題。
(5)負載(payload),消息訂閱者所具體接收的內容。
6、MQTT協(xié)議中的方法
MQTT協(xié)議中定義了一些方法(也被稱為動作),來表示對確定資源所進行操作。這個資源可以代表預先存在的數(shù)據(jù)或動態(tài)生成數(shù)據(jù),這取決于服務器的實現(xiàn)。通常來說,資源指服務器上的文件或輸出。主要方法有:
(1)Connect,等待與服務器建立連接。
(2)Disconnect,等待MQTT客戶端完成所做的工作,并與服務器斷開TCP/IP會話。
(3)Subscribe,等待完成訂閱。
(4)UnSubscribe,等待服務器取消客戶端的一個或多個topics訂閱。
(5)Publish,MQTT客戶端發(fā)送消息請求,發(fā)送完成后返回應用程序線程。
四、EMQ
EMQ2.0,號稱百萬級開源MQTT消息服務器,基于高并發(fā)的Erlang/OTP語言平臺設計,支持百萬級連接和分布式集群,發(fā)布訂閱模式的開源MQTT消息服務器。完整支持MQTT V3.1/V3.1.1協(xié)議規(guī)范,擴展支持WebSocket、Stomp、CoAP、MQTT-SN或私有TCP協(xié)議。
EMQ?消息服務器啟動后,會默認加載 Dashboard 插件,啟動 Web 管理控制臺。用戶可通過 Web 控制臺,查看服務器運行狀態(tài)、統(tǒng)計數(shù)據(jù)、客戶端(Client)、會話(Session)、主題(Topic)、訂閱(Subscription)、插件(Plugin)
WebSocket工具,可以連接MQTT服務,填寫服務的Host、port、path、Client ID、Username、Password、Keep Alive時間

Subscribe中可以填寫訂閱主題并選擇消息質量QoS

Message里面可以給自定義主題發(fā)送消息,也可以查看訂閱者接受到的消息(訂閱者是在connect中建立連接的用戶)

從上邊的這個消息你會發(fā)現(xiàn),同一條消息的QoS等級不一樣,這是為什么呢?
QoS 向下兼容
QoS流,在發(fā)送端和接收端是兩件不同的事情,當然發(fā)送端與接收端QoS的等級也可以不一樣。在發(fā)送端與broker之間,發(fā)送端定義了QoS等級。當broker發(fā)送消息到接收端是,接收端決定了QoS的等級
參考文獻:
1、MQTT入門介紹:https://www.runoob.com/w3cnote/mqtt-intro.html
2、MQTT協(xié)議基本介紹:http://www.itdecent.cn/p/ecde412d2eeb