MQTT協議從服務端到客戶端詳解
12018.03.09 13:54:32字數 8543閱讀 19139java
一:前言
最近在瞭解MQTT協議相關的內容,內容有點多,特此把MQTT協議,以及其從服務端到客戶端的流程整理出來,記錄以下。git
二:MQTT協議介紹
MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)是IBM開發的一個即時通信協議,它是一種輕量級的、基於代理的「發佈/訂閱」模式的消息傳輸協議。其具備協議簡潔、小巧、可擴展性強、省流量、省電等優勢,並且已經有PHP,JAVA,Python,C,C#,Go等多個語言版本,基本可使用在任何平臺上,幾乎能夠把全部聯網物品和外部鏈接起來,因此特別適合用來當作物聯網的通訊協議,實用的場景有遙感數據、汽車、智能家居、智慧城市、醫療醫護等等。github
MQTT特色
MQTT協議是爲大量計算能力有限,且工做在低帶寬、不可靠的網絡的遠程傳感器和控制設備通信而設計的協議,它具備如下主要的幾項特性:web
一、使用發佈/訂閱消息模式,提供一對多的消息發佈,解除應用程序耦合;算法
二、對負載內容屏蔽的消息傳輸;apache
三、使用 TCP/IP 提供網絡鏈接;ubuntu
四、有三種消息發佈服務質量:瀏覽器
「至多一次」,消息發佈徹底依賴底層 TCP/IP 網絡。會發生消息丟失或重複。這一級別可用於以下狀況,環境傳感器數據,丟失一次讀記錄無所謂,由於不久後還會有第二次發送。緩存
「至少一次」,確保消息到達,但消息重複可能會發生。安全
「只有一次」,確保消息到達一次。這一級別可用於以下狀況,在計費系統中,消息重複或丟失會致使不正確的結果。
五、小型傳輸,開銷很小(固定長度的頭部是 2 字節),協議交換最小化,以下降網絡流量;
六、使用 Last Will (遺囑)和 Testament 特性通知有關各方客戶端異常中斷的機制;
MQTT協議內容
1 :消息模型
MQTT是一種基於代理的發佈/訂閱的消息協議。與請求/回答這種同步模式不一樣,發佈/訂閱模式解耦了發佈消息的客戶(發佈者)與訂閱消息的客戶(訂閱者)之間的關係,這意味着發佈者和訂閱者之間並不須要直接創建聯繫。一個發佈者能夠對應多個訂閱者,當發佈者發生變化的時候,他能夠將消息一一通知給全部的訂閱者。這種模式提供了更大的網絡擴展性和更動態的網絡拓撲
此外運用MQTT協議,設備能夠很方便地鏈接到物聯網雲服務,管理設備並處理數據,最後應用到各類業務場景,以下圖所示
2 服務質量
MQTT提供三種質量的服務:
至多一次(qos = 0),可能會出現丟包的現象。使用在對實時性要求不高的狀況。這一級別可應用於以下情景,如環境傳感器數據,丟失一次讀記錄無所謂,由於很快下一次讀記錄就會產生。
至少一次(qos = 1),保證包會到達目的地,可是可能出現重包。
正好一次(qos = 2),保證包會到達目的地,且不會出現重包的現象。這一級別可用於如計費系統等場景,在計費系統中,消息丟失或重複可能會致使生成錯誤的費用。
服務質量
3 主題與通配符
主題名稱(Topic name)用來標識已發佈消息的信息的渠道。訂閱者用它來肯定接收到所關心的信息。它是一個分層的結構,用斜線「/」做爲分隔符(這個有點相似於restful風格)。主題還能夠經過通配符進行過濾。其中,+能夠過濾一個層級,而#只能出如今主題最後表示過濾任意級別的層級。值得注意的是MQTT容許使用通配符訂閱主題,可是並不容許使用通配符廣播。
舉個例子:
building-b/floor-5:表明B樓5層的設備。
+/floor-5:表明任何一個樓的5層的設備。
building-b/#:表明B樓全部的設備。
4 遺囑
當一個客戶端斷開鏈接的時候,它但願客戶端能夠發送它指定的消息。該消息和普通消息的結構相同。經過設置該位並填入和信息相關的內容便可(後面會有介紹)。
5 消息類型
消息類型 類型 編碼說明
reserved 0 保留
connect 1 客戶端到服務端的鏈接請求
connACK 2 服務端對鏈接請求的響應
publish 3 發佈消息
puback 4 新發布消息確認,是QoS 1給PUBLISH消息的回覆
pubRec 5 QoS 2消息流的第一部分,表示消息發佈已記錄
pubRel 6 QoS 2消息流的第二部分,表示消息發佈已釋放
pubComp 7 QoS 2消息流的第三部分,表示消息發佈完
subscribe 8 客戶端訂閱某個主題
subBack 9 對於SUBSCRIBE消息的確認
unsubscribe 10 客戶端終止訂閱的消息
unsubBack 11 對於UNSUBSCRIBE消息的確認
pingReq 12 心跳
pingResp 13 確認心跳
disconnect 14 客戶端終止鏈接前通知MQTT代理
reserved 15 保留
MQTT協議頭部信息詳細介紹
客戶端發佈消息經由服務器分發到全部對應的訂閱者那裏。一個訂閱者能夠訂閱若干個主題(Topic name),但一個PUBLISH消息只能擁有一個主題。其消息架構以下:
1 固定頭部
固定頭部,使用兩個字節,共16位:
Byte 1 消息類型和標誌字段,消息類型(4-7),使用4位二進制表示,可表明16種消息類型。
Byte 2 剩餘長度字段(至少1個字節,最多4個字節),採用big-endian模式存儲。
消息類型前面已有介紹 此處附上一張圖:
DUP flag(打開標誌)
保證消息可靠傳輸,默認爲0,只佔用一個字節,表示第一次發送。不能用於檢測消息重複發送等。只適用於客戶端或服務器端嘗試重發PUBLISH(發送消息), PUBREL(QoS 2消息流的第二部分,表示消息發佈已釋放), SUBSCRIBE(客戶端訂閱某個主題) 或 UNSUBSCRIBE(客戶端終止訂閱的消息)消息,注意須要知足如下條件:當 QoS > 0時消息須要回覆確認,此時,在可變頭部須要包含消息ID。當值爲1時,表示當前消息先前已經被傳送過。
QoS(Quality of Service,服務質量)
使用兩個二進制表示PUBLISH類型消息:
RETAIN(保持)
僅針對PUBLISH消息。不一樣值,不一樣含義:
0:僅僅爲當前訂閱者推送此消息。
1:表示發送的消息須要一直持久保存(不受服務器重啓影響),不但要發送給當前的訂閱者,而且之後新來的訂閱了此Topic name的訂閱者會立刻獲得推送。
另外對於新加入的訂閱者,只會取出最新的一個RETAIN flag = 1的消息推送。
Remaining Length(剩餘長度)
在當前消息中剩餘的byte(字節)數,包含可變頭部和負荷(稱之爲內容/body,更爲合適)。單個字節最大值:01111111,16進制:0x7F,10進製爲127。單個字節爲何不能是11111111(0xFF)呢?由於MQTT協議規定,第八位(最高位)若爲1,則表示還有後續字節存在。
同時MQTT協議最多容許4個字節表示剩餘長度。那麼最大長度爲:0xFF,0xFF,0xFF,0x7F。
二進制表示爲:11111111,11111111,11111111,01111111
十進制:268435455 byte=261120KB=256MB=0.25GB
四個字節之間值的範圍:
2 可變頭部
固定頭部僅定義了消息類型和一些標誌位,一些消息的元數據,須要放入可變頭部中。可變頭部內容字節長度 + Payload/負荷字節長度 = 剩餘長度,這個是須要牢記的。可變頭部,包含了協議名稱,版本號,鏈接標誌,用戶受權,心跳時間等內容,這些在後面會講到。
3 Payload/消息體/負荷
消息體主要是爲配合固定/可變頭部命令(好比CONNECT可變頭部User name標記若爲1則須要在消息體中附加用戶名稱字符串)而存在。
CONNECT/SUBSCRIBE/SUBACK/PUBLISH等消息有消息體。PUBLISH的消息體以二進制形式對待。
請記住MQTT協議只容許在PUBLISH類型消息體中使用自定義特性,在固定/可變頭部想加入自定義私有特性,就免了吧。這也是爲了協議免於流於形式,變得很分裂也爲了兼顧現有客戶端等。好比支持壓縮等,那就能夠在Payload中定義數據支持,在應用中進行讀取處理
4 消息標識符/消息ID
一個16位無符號位的short類型值(值不能爲 0,0作保留做爲無效的消息ID),僅僅要求在一個特定方向(服務器發往客戶端爲一個方向,客戶端發送到服務器端爲另外一個方向)的通訊消息中必須惟一。好比客戶端發往服務器,有可能存在服務器發往客戶端會同時存在重複,但不礙事。
可變頭部中,須要兩個字節的順序是MSB(Most Significant Bit) LSB(Last/Least Significant Bit),翻譯成中文就是,最高有效位,最低有效位。最高有效位在最低有效位左邊/上面,表示這是一個大端字節/網絡字節序,符合人的閱讀習慣,高位在最左邊。
MQTT協議鏈接和心跳介紹
CONNECT
TCP鏈接創建完畢後,Client向Server發出一個Request。
若是一段時間內接收不到Server的Response,則關閉socket,從新創建一個session鏈接。
若是一個ClientID已經與服務器鏈接,則持有一樣ClientID的舊有鏈接必須由服務器關閉後,新創建才能創建。下面是一個較爲完整的CONNECT消息結構:
下面介紹Connect Flags相關的參數
1 鏈接標誌(Connect Flags)
一個字節表示,除了第1位是保留未使用,其它7位都具備不一樣含義。業務上很重要,對消息整體流程影響很大,須要牢記。
2 Clean Session
0,表示若是訂閱的客戶機斷線了,要保存爲其要推送的消息(QoS爲1和QoS爲2),若其從新鏈接時,需將這些消息推送(若客戶端長時間不鏈接,須要設置一個過時值)。 1,斷線服務器即清理相關信息,從新鏈接上來以後,會再次訂閱。
3 Will Flag
定義了客戶端(沒有主動發送DISCONNECT消息)出現網絡異常致使鏈接中斷的狀況下,服務器須要作的一些措施。
簡而言之,就是客戶端預先定義好,在本身異常斷開的狀況下,所留下的最後遺願(Last Will),也稱之爲遺囑(Testament)。 這個遺囑就是一個由客戶端預先定義好的主題和對應消息,附加在CONNECT的可變頭部中,在客戶端鏈接出現異常的狀況下,由服務器主動發佈此消息。
只有在Will Flag位爲1時,Will Qos和Will Retain纔會被讀取,此時消息體payload中要出現Will Topic和Will Message具體內容,不然,Will QoS和Will Retain值會被忽略掉。
4 Will Qos
兩位表示,和PUBLISH消息固定頭部的QoS level含義同樣。這裏先略過,到PUBLISH消息再回過頭來看看,會更明白些。若標識了Will Flag值爲1,那麼Will QoS就會生效,不然會被忽略掉。
5 Will Retain
若是設置Will Flag,Will Retain標誌就是有效的,不然它將被忽略。當客戶端意外斷開服務器發佈其Will Message以後,服務器是否應該繼續保存。這個屬性和PUBLISH固定頭部的RETAIN標誌含義同樣,這裏先略過。
6 User name 和 password Flag
用於受權,二者要麼爲0要麼爲1,不然都是無效。都爲0,表示客戶端可自由鏈接/訂閱,都爲1,表示鏈接/訂閱須要受權。
CONNACK
收到CONNECT消息以後,服務器應該返回一個CONNACK消息做爲響應:
若客戶端繞過CONNECT消息直接發送其它類型消息,服務器應關閉此非法鏈接 若客戶端發送CONNECT以後未收到CONNACT,須要關閉當前鏈接,而後從新鏈接
相同Client ID客戶端已鏈接到服務器,先前客戶端必須斷開鏈接後,服務器才能完成新的客戶端CONNECT鏈接 客戶端發送無效非法CONNECT消息,服務器須要關閉。
一個完整的CONNACK消息大體以下:
PUBLISH 發佈消息
Client/Servier都可以進行PUBLISH。(這裏的server指的是MQTT的中間件服務,例如:下面會講到的Apollo,Mosquitto 等服務器)
publish message 應該包含一個TopicName(Subject/Channel),即訂閱關鍵詞。
具體的交互下面這張圖就描述的很清晰了:
PUBACK 發佈消息後的確認
QoS=1時,Server向Client發佈該確認(Client收到確認後刪除),訂閱者向Server發佈確認。PUBREC / PUBREL / PUBCOMP
QoS=2時
1. Server->Client發佈PUBREC(已收到);
2. Client->Server發佈PUBREL(已釋放);
3. Server->Client發佈PUBCOMP(已完成),Client刪除msg;訂閱者也會向Server發佈相似過程確認。
PUBREC字面意思爲Assured publish received,做爲訂閱者/服務器對QoS level = 2的發佈PUBLISH消息的發送方的響應,確認已經收到,爲QoS level = 2消息流的第二個消息。 和PUBACK相比,除了消息類型不一樣外,其它都是同樣。
PUBREL Qos level = 2的協議流的第三個消息,有PUBLISH消息的發佈者發送,參與方接收。完整示範以下
PUBCOMP 做爲QoS level = 2消息流第四個,也是最後一個消息,由收到PUBREL的一方向另外一方作出的響應消息。完整的消息一覽,和PUBREL一致,除了消息類型。
PINGREQ / PINGRES 心跳
Client有責任發送KeepAliveTime時長告訴給Server(代表當前client處於活動狀態)。在一個時長內,發送PINGREQ,Server發送PINGRES確認。
Server在1.5個時長內未收到PINGREQ,就斷開鏈接。
Client在1個時長內未收到PINGRES,斷開鏈接。
通常來講,時長設置爲幾個分鐘。最大18小時,0表示一直未斷開。
心跳時間(Keep Alive timer)
以秒爲單位,定義服務器端從客戶端接收消息的最大時間間隔。通常應用服務會在業務層次檢測客戶端網絡是否鏈接,不是TCP/IP協議層面的心跳機制(好比開啓SOCKET的SO_KEEPALIVE選項)。 通常來說,在一個心跳間隔內,客戶端發送一個PINGREQ消息到服務器,服務器返回PINGRESP消息,完成一次心跳交互,繼而等待下一輪。若客戶端沒有收到心跳反饋,會關閉掉TCP/IP端口鏈接,離線。 16位兩個字節,可看作一個無符號的short類型值。最大值,2^16-1 = 65535秒 = 18小時。最小值能夠爲0,表示客戶端不斷開。通常設爲幾分鐘,好比微信心跳週期爲300秒
鏈接異常中斷通知機制
CONNECT消息一旦設置在可變頭部設置了Will flag標記,那就啓用了Last-Will-And-Testament特性,此特性很贊。
一旦客戶端出現異常中斷,便會觸發服務器發佈Will Message消息到Will Topic主題上去,通知Will Topic訂閱者,對方因異常退出。
抓包分析頭部數據
前面說了這麼多都是概念性的東西,下面我來點實際性的操做,用wireshark抓包看看具體的MQTT協議數據到底長成什麼樣,加深對前面概念的理解
我這裏用的是wireshark+paho(gui)這兩個工具,borker使用的是mosquitto。順便提下paho是eclipse下的一個子項目,它只是一個庫,官網貌似並不提供gui版本(圖形界面),我這裏是從github上下載的源碼進行編譯獲得的界面版本,這個界面對於MQTT的消息調試仍是蠻好用的,有興趣的也能夠試下,項目的github地址:https://github.com/eclipse/paho.mqtt.java
最新版的wireshark已經支持mqtt協議了,因此在過濾其裏面直接填入 mqtt 就能夠過濾到mqtt協議的請求了
能夠看到上面圖中已經抓到我在paho中發起創建鏈接的請求了,而且在info那一欄能夠清楚的看到 connect command,咱們再看下下面的具體數據包,它顯示的是原始是16進制的,10 1e 00 04 4d 51 54 54 04 02 00 3c 00 12 70 61 68 6f 31 31 31 35 37 37 32 31 39 34 33 36 30 33 這麼一大串,下面這張圖就解釋的比較清楚了
咱們來分析下這個數據包,前面兩個字節是10和1e
第一個字節:0x10對應的2進制是 10000,用8位bit來顯示就是 0001 0000 ,上圖詳細的顯示了這8位的四個部分都是幹什麼用的,這裏就再也不詳細介紹了
第二個字節:0x1e 表示剩餘長度,也就是說本次請求數據包中第二個字節後面全部的字節總數,0x1e換算成十進制就是1*16+14=30字節, 「00 04 4d 51 54 54 04 02 00 3c 00 12 70 61 68 6f 31 31 31 35 37 37 32 31 39 34 33 36 30 33」
可變頭部,再次放圖以下:
三 :MQTT 服務端(實現MQTT協議的中間件)
MQTT協議服務端:https://github.com/mqtt/mqtt.github.io/wiki/servers
MQTT協議類庫(Client):https://github.com/mqtt/mqtt.github.io/wiki/libraries
MQTT協議官網:http://mqtt.org/
MQTT協議有不少開源的broker能夠用,這裏我整理了兩個,分別是Apollo和mosquito;詳細的服務端選擇能夠去上面的服務端連接中選。如下所講的環境配置和服務器搭建都是在MAC環境上,其餘平臺的能夠參見選用broker的詳細文檔。
一:Apollo-Broker搭建
Apache Apollo是一個代理服務器,其是在ActiveMQ基礎上發展而來的,能夠支持多種協議,如:STOMP、AMQP、MQTT、SSL等。其搭建流程以下:
1 配置JAVA_HOME,Apollo是java語言編寫的,所以搭建Apollo-Broker須要java環境,MAC下如何配置JAVA_HOME可自行查閱網上資料。
2下載Apollo
此處因爲之針對本身macbook而言選擇OS X版本下載
將下載好的文件解壓到適當的目錄(最好單獨新建一個方便後續整理)。解壓後會有apache-apollo-xxx文件夾,該文件夾默認爲環境變量${APOLLO_HOME};
3 建立broker,有兩種方式
cd放置broker路徑(建議就放在2建立的文件夾中方便之後查看或整理)
方法一:經過環境變量 (相對路徑)建立${APOLLO_HOME}/bin/apollo create MyBroker //上面是經過環境變量直接建立,若是失敗說明以前操做有些問題致使環境變量配置失敗。
方法二:將apollo拖入終端用絕對地址 建立 xxx/bin/apollo create MyBroker#在當前目錄下生成一個mqtt_test目錄,其下面包含:*****運行結果******* Creating apollo instance at: MyBroker Generating ssl keystore... You can now start the broker by executing:"/Users/lqx/Desktop/未命名文件夾/MyBroker/bin/apollo-broker"run Or you can run the brokerinthe background using:"/Users/lqx/Desktop/未命名文件夾/MyBroker/bin/apollo-broker-service"start
成功後文件目錄大體應該是這個樣子:
bin 運行腳本
etc 環境配置
data 存儲持久化數據
log 運行日誌
tmp 臨時文件
4 運行broker
cd MyBroker(3建立的文件夾)
apollo-broker run
因爲apollo提供了可視化web界面(這也就是我選擇他的緣由),咱們在瀏覽器中輸入
http://127.0.0.1:61680/(http訪問) 或者https://127.0.0.1:61681/(https訪問,可用於研究mqtt+ssl)輸入用戶名密碼便可登陸(默認用戶名:admin 密碼:password)
關於服務器與客戶端的聯調 ,我會在客戶端篇講到。
值得注意的是 默認配置的tcp的port是61613,我以前寫demo 的時候客戶端一直連不上broker,緣由就是服務器所在主機的端口號61613沒打開,因此你們在搭建完服務器後必定要檢查相應的端口是否打開了,相應端口截圖以下
再說一下Mac的端口狀況,目前OSX 10.10以前版本能夠用如下指令開放端口
sudo ipfw add 61613 allow tcp from any to any dst-port 61613;
osx10.10以後的版本目前還沒找到開放端口的方法,有知道的能夠告訴我一下,查閱資料獲得的處理方式都是用Nginx服務器作端口轉發,不過比較麻煩,因此我用了一個簡單的方法替換了,方法以下:
Mac端默認的tcp端口開放了1883,這個你們能夠在網絡實用工具中看,因此咱們得去吧Apollobroker的配置文件中的tcpport 由61613改爲1883,
在你上面建立好的broker文件夾中找到apollo.xml,這個就是配置文件
將tcp 配置port改爲1883
而後重啓服務就能夠了。其餘系統可直接開放61613端口號,方便快捷。
apollo 除了提供了可視化Web界面外,還提供了測試網頁,
打開頁面以下
在鏈接後 能夠去Apollo監控頁面(http://127.0.0.1:61680/(http訪問) 或者https://127.0.0.1:61681/(https訪問,可用於研究mqtt+ssl))查看,會發現有你鏈接的主題和消費者。
至此,Apollo 相關的服務器須要講得已經講完了。
二:mosquito 服務器搭建
Mosquitto是一款實現了 MQTT v3.1 協議的開源消息代理軟件,提供輕量級的,支持發佈/訂閱的的消息推送模式,使設備對設備之間的短消息通訊簡單易用
Mosquitto是C語言實現的,不須要配置什麼環境,咱們直接用homebrew安裝,簡單快捷。
1 打開終端 輸入brew install mosquitto直接安裝
Linux(ubuntu)環境下的安裝也比較簡單(注意#號,須要root權限):
# apt install mosquitto
固然若是真的是這麼安裝的,那麼很差意思,安裝的版本可能會比較低,不過也沒關係,照樣能夠用。可是若是你想安裝最新版的,那麼就按照下面的命令來吧:
一、先刪除剛剛安裝mosquitto(沒有安裝的能夠直接跳到第2步)
# apt-get --purge remove mosquitto
二、引入mosquitto倉庫並更新
# apt-add-repository ppa:mosquitto-dev/mosquitto-ppa
# apt-get update
三、安裝Mosquitto
# apt-get install mosquitto
四、檢查是否安裝成功
# service mosquitto status
安裝成功界面以下
mosquitto服務啓動命令
中止服務 brew services stop mosquitto
啓動服務 brew services start mosquitto
重啓服務 brew services restart mosquitto
接下來說一下mosquito的配置文件,配置文件是目錄/usr/local/etc/mosquitto/下的mosquitto.conf文件。配置文件相關說明以下,
# =================================================================
# General configuration
# =================================================================
# 客戶端心跳的間隔時間
#retry_interval 20
# 系統狀態的刷新時間
#sys_interval 10
# 系統資源的回收時間,0表示儘快處理
#store_clean_interval 10
# 服務進程的PID
#pid_file /var/run/mosquitto.pid
# 服務進程的系統用戶
#user mosquitto
# 客戶端心跳消息的最大併發數
#max_inflight_messages 10
# 客戶端心跳消息緩存隊列
#max_queued_messages 100
# 用於設置客戶端長鏈接的過時時間,默認永不過時
#persistent_client_expiration
# =================================================================
# Default listener
# =================================================================
# 服務綁定的IP地址
#bind_address
# 服務綁定的端口號
#port 1883
# 容許的最大鏈接數,-1表示沒有限制
#max_connections -1
# cafile:CA證書文件
# capath:CA證書目錄
# certfile:PEM證書文件
# keyfile:PEM密鑰文件
#cafile
#capath
#certfile
#keyfile
# 必須提供證書以保證數據安全性
#require_certificate false
# 若require_certificate值爲true,use_identity_as_username也必須爲true
#use_identity_as_username false
# 啓用PSK(Pre-shared-key)支持
#psk_hint
# SSL/TSL加密算法,可使用「openssl ciphers」命令獲取
# as the output of that command.
#ciphers
# =================================================================
# Persistence
# =================================================================
# 消息自動保存的間隔時間
#autosave_interval 1800
# 消息自動保存功能的開關
#autosave_on_changes false
# 持久化功能的開關
persistencetrue
# 持久化DB文件
#persistence_file mosquitto.db
# 持久化DB文件目錄
#persistence_location /var/lib/mosquitto/
# =================================================================
# Logging
# =================================================================
# 4種日誌模式:stdout、stderr、syslog、topic
# none 則表示不記日誌,此配置能夠提高些許性能
log_dest none
# 選擇日誌的級別(可設置多項)
#log_type error
#log_type warning
#log_type notice
#log_type information
# 是否記錄客戶端鏈接信息
#connection_messages true
# 是否記錄日誌時間
#log_timestamp true
# =================================================================
# Security
# =================================================================
# 客戶端ID的前綴限制,可用於保證安全性
#clientid_prefixes
# 容許匿名用戶
#allow_anonymous true
# 用戶/密碼文件,默認格式:username:password
#password_file
# PSK格式密碼文件,默認格式:identity:key
#psk_file
# pattern write sensor/%u/data
# ACL權限配置,經常使用語法以下:
# 用戶限制:user
# 話題限制:topic [read|write]
# 正則限制:pattern write sensor/%u/data
#acl_file
# =================================================================
# Bridges
# =================================================================
# 容許服務之間使用「橋接」模式(可用於分佈式部署)
#connection
#address [:]
#topic [[[out | in | both] qos-level] local-prefix remote-prefix]
# 設置橋接的客戶端ID
#clientid
# 橋接斷開時,是否清除遠程服務器中的消息
#cleansession false
# 是否發佈橋接的狀態信息
#notifications true
# 設置橋接模式下,消息將會發布到的話題地址
# $SYS/broker/connection//state
#notification_topic
# 設置橋接的keepalive數值
#keepalive_interval 60
# 橋接模式,目前有三種:automatic、lazy、once
#start_type automatic
# 橋接模式automatic的超時時間
#restart_timeout 30
# 橋接模式lazy的超時時間
#idle_timeout 60
# 橋接客戶端的用戶名
#username
# 橋接客戶端的密碼
#password
# bridge_cafile:橋接客戶端的CA證書文件
# bridge_capath:橋接客戶端的CA證書目錄
# bridge_certfile:橋接客戶端的PEM證書文件
# bridge_keyfile:橋接客戶端的PEM密鑰文件
#bridge_cafile
#bridge_capath
#bridge_certfile
#bridge_keyfile
mosquito 配置用戶名和密碼能夠參考https://www.jianshu.com/p/4b545332b495這篇簡書,我這裏作一個簡單demo就不配置用戶名和密碼了。
咱們須要改的配置不多
就設置一下host 和port就能夠了。配置好後重啓服務就能夠生效了。
要注意的地方和Apollo同樣 ,注意端口號是否打開或被佔用。
因爲mosquito沒有提供可視化界面,在本身不搭建可視化界面的狀況下,咱們能夠用兩個客戶端訂閱同一主題來測試mosquito服務器。mosquito至此就基本ok了。
四 MQTT客戶端
客戶端通常兩個經常使用的mqtt三方庫MQTTKit和MQTTClient,MQTTClient在Ios10出來後更新了一版,常常維護;MQTTKit,這個貌似好久沒更新了,因此咱們選用MQTTClient,搭建環境爲iOS。
1 安裝MQTTClient
直接用cocopod集成 pod 'MQTTClient'
2相關類
3 具體用法
這裏作鏈接的時候 須要先打開你的服務,用mosquito或者Apollo均可以
用Apollo 是須要加用戶名和密碼的,默認爲admin 和password ,用mosquito則不須要用戶名和密碼。host爲你服務器的ip,port爲你設置的port 我這邊是1883,服務器所在主機和手機在同一局域網內就能夠連上,以爲局域網麻煩的大佬能夠直接甩到阿里雲之類的服務器上去。連上後,訂閱同一主題的客戶端就能相互通訊了,好比在Apollo 服務器下手機客戶端能夠和其提供的webdemo通訊了。
客戶端接受消息
客戶端發送消息
其餘多主題訂閱 或者lastwill遺囑設置或者retain設置參考MQTTClient的註釋。
最後 用完後記得釋放資源
至此,一個簡單的MQTT協議從服務端到客戶端的實現到此就完成了,歡迎你們補充完善。
能讀到這裏我很佩服你的耐心,壯士請...留...步...,點個讚唄