本節書摘來自華章出版社《用于物聯網的arduino項目開發:實用案例解析》一 書中的第3章,第3.3節,作者[美]安德爾·傑韋德(adeel javed),更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。
mqtt是一個輕量級的機器對機器的協定。它采用的是釋出者-訂閱者模型,就是說由一個釋出者把資料釋出給伺服器(也叫作代理),然後訂閱者就能收到這個資料。釋出者和訂閱者彼此互不相識,但他們都連接配接在代理上,代理異步地完成這個通信。
代理用話題的概念來通知所有的訂閱者相關的資料已經釋出這一消息。話題就像新聞推送,你可以訂閱某些想要接收的新聞的話題。釋出者和訂閱者可以是傳感器、機器或移動應用。圖3-4是mqtt協定的高層概覽。
了解mqtt協定對于建構物聯網應用是很重要的,接下來,看幾個場景來進一步了解mqtt。
圖3-5為一個簡單的入侵檢測系統,包括三個部件:檢測入侵釋出資料的運動傳感器、接收這個資料通知使用者的移動應用,以及mqtt代理上的一個話題。

傳感器一檢測到入侵,就會作為釋出者向mqtt代理商的codifythings/intrusion-detected話題釋出新的消息。mqtt代理會把這個消息加到話題中。移動應用可以訂閱codifythings/intrusiondetected話題,當有新的消息被釋出到這個話題時,它就會得到通知,繼而可以通知使用者。第6章将建構一個這樣的系統。
mqtt另一種很棒的用處是為各種類型的裝置開發遙控器,比如做一個燈光控制應用。如圖3-6所示,一個遙控應用也是由三個部分組成,不過和上一個例子相比,前兩個部件的順序交換了一下。也就是說,首先是移動應用,它的使用者可以控制燈光的開關,然後是連着燈光的裝置,第三個部分是mqtt代理商的一個話題。
使用者與移動應用互動來開燈或關燈,無論做哪種動作,移動應用就會給mqtt代理商的codifythings/lightscontrol話題釋出一條消息。mqtt代理會把這個消息加到話題中。連接配接到實際的燈的裝置可以訂閱codifythings/intrusiondetected話題,當有新的消息被釋出到這個話題時,它就會得到通知,繼而可以開關燈光。第8章将建構一個這樣的遙控器。
所需的硬體、軟體和電路,請閱讀2.3節。
接下來,我們來寫用wifi将arduino和網際網路相連,并通過mqtt協定釋出資料給伺服器的代碼。
啟動arduino ide,輸入下面的代碼,或者從本書的網站下載下傳代碼檔案然後打開。所有的檔案都在單個源檔案(*.ino)中,不過為了便于了解和重用,這個代碼被分成以下四個部分:
外部庫
網際網路連接配接(無線)
資料釋出(mqtt)
資料訂閱(mqtt)
程式3-6給出了代碼的第一部分,引入了運作代碼所需的全部外部庫。這個程式主要有兩個依賴。為了實作網際網路連接配接,需要包含(假設用的是wifi盾闆),而為了實作與mqtt代理的通信,需要包含。
代碼的第二部分定義了連接配接網際網路要用的變量、常量和函數。在這裡使用了程式2-7、程式2-8和程式2-9中的代碼。
mqtt的資料釋出和訂閱
代碼的第三部分定義了将來向mqtt代理釋出和訂閱要用到的變量、常量和函數。這個代碼會釋出和訂閱同一個話題。
程式3-7首先定義了要arduino連接配接的mqtt代理的位址和端口(預設為1883)。topic變量定義了在代理上釋出和訂閱所用的話題。如果你的電腦上沒有安裝mqtt代理,可以使用eclipse基金會設立的公共mqtt代理(iot.eclipse.org)或mosquitto(test.mosquitto.org)。
如程式3-8所示來初始化mqtt用戶端。callback()函數把從代理收到的消息内容的細節封裝了起來。
最後,程式3-9是代碼的最後一部分,實作了arduino标準函數setup()和loop()。
在setup()函數中,代碼初始化序列槽,然後連接配接到網際網路。如果連上了mqtt代理,就訂閱codifythings/testmessage話題。一旦訂閱成功,代碼就向codifythings/testmessage話題釋出一條新消息。代碼訂閱了它所釋出的同一個話題,是以消息一釋出出去,callback()函數就會被調用。loop()函數隻是等待mqtt代理來的新消息。
這樣,arduino代碼就完成了。
要測試這個應用,按照第1章所介紹的,校驗然後上傳代碼到arduino。代碼上傳後,打開序列槽螢幕會看到如圖3-7所示的日志消息。