使用Node.js訂閱MQTT信息

MQTT教學(七):使用Node.js訂閱MQTT訊息

 2017/04/12  cubie  教學文件硬體與DIYhtml

 

本文將使用MQTT.js套件開發Node.js的MQTT前端應用程式。MQTT伺服器仍採用以前介紹的Mosquitto,附帶一提,有個採用Node.js開發的開放原始碼MQTT伺服器(broker)模組,叫作Mosca,能夠獨立運做,也能嵌入Node.js程式執行,有興趣的朋友請參閱Mosca的官網介紹。前端

透過MQTT.js命令行模式發布和接收MQTT主題

MQTT.js支援在命令行(終端機)中直接輸入命令,藉以發布或接收MQTT主題。若要使用命令行模式,請用全域(global)方式安裝MQTT.js:node

 

 

1jquery

npm install mqtt -gexpress

 

安裝後便可在命令行(終端機)輸入底下的命令,發布一則「home/yard/DHT11」主題訊息npm

發布一則「home/yard/DHT11」主題訊息的命令

這是透過MQTTLens程式接收此MQTT訊息的畫面:json

底下這個命令則可訂閱「home/yard/DHT11」主題app

訂閱「home/yard/DHT11」主題的命令

更多命令及其說明能夠執行mqtt help,或者mqtt help ‘命令’,例如,mqtt help pub。socket

透過Node.js程式檔訂閱MQTT主題

本節將使用MQTT.js製做一個在命令行(終端機)顯示訂閱主題訊息的Node.js程式。tcp

在命令行(終端機)顯示訂閱主題訊息的Node.js程式

由於下一節的程式碼將會使用到Express和Socket.io套件,所以筆者選擇在《超圖解物聯網IoT實做入門》書本的socket專案路徑中,輸入底下的命令安裝mqtt.js:

 

 

1

npm install mqtt --save

 

MQTT.js的程式很簡單,底下是訂閱「home/yard/DHT11」主題的Node.js程式碼,筆者將它命名為mqtt.js。

訂閱「home/yard/DHT11」主題的Node.js程式碼

其中,創建用戶端物件並連線到伺服器的敘述,能夠省略「連線參數」物件,它預設將連接到1883埠,並且創建一個以’mqttjs_’起頭,後面跟著8個隨機16進位數字的用戶端ID:

 

 

1

var client = mqtt.connect('mqtt://192.168.1.19');

 

每當收到新的主題訊息時,「message」事件會自動觸發,於是在命令行(終端機)顯示收到的主題和訊息。上面的程式碼執行結果以下,你能夠使用Arduino或者MQTTLens前端發送MQTT訊息測試:

在終端機顯示接收到的MQTT訊息

MQTT用戶端物件的subscribe(訂閱)方法的「主題」參數,能夠是字串、陣列或物件類型。若要訂閱多個主題,請將全部主題名稱寫在一個陣列裡面;底下的敘述將訂閱兩個主題:

使用陣列subscribe(訂閱)兩個主題

這是用物件類型訂閱兩個主題的示範。「主題名稱」是物件的「屬性」,QoS則是「值」

使用物件subscribe(訂閱)兩個主題

Node.js的Buffer資料類型

伴隨MQTT.js的message(訊息)事件傳入的訊息內容類型是Node.js的二進制資料,稱為Buffer。Buffer主要用於儲存文字之外的資料,例如:圖片、聲音、視訊…等等,它也能儲存文字。請在命令列(終端機)輸入下圖裡的藍色敘述,進入Node.js的REPL模式,練習創建與操做Buffer類型資料。

操做Buffer類型資料

上面的敘述宣告了一個20位元組空間大小的Buffer類型變數,接著對它寫入一個字串資料。Node.js的字串預設用UTF-8萬國編碼,這是一種可變動長度的編碼,不一樣的字元或符號可能佔用1~4位元組。英文字的UTF-8編碼相容於ASCII編碼,每個字元佔1個位元組;一個中文字的UTF-8編碼大多佔3個位元組。因此儲存「昨日是歷史、明日是謎團。」這12個字元須要36位元組空間,超出20個位元組之外的數據會被截掉。

僅輸入變數名稱「buff」,可取出它的原始資料值(字串資料的UTF-8編碼)。我們也能在宣告Buffer變數時,直接輸入資料,它將自動預留與資料大小相同的記憶體空間,例如:

操做Buffer類型資料

透過Socket.io即時更新MQTT訊息網頁

本單元的範例結合Express, Socket.io和MQTT.js,在網頁上顯示即時更新的MQTT訊息(溫濕度值),此範例的檔案結構和《超圖解物聯網IoT實做入門》「使用jQuery讀取並解析JSON訊息」一節(2-25頁)相同。

結合Express, Socket.io和MQTT.js,在網頁上顯示即時更新的MQTT訊息

Node.js專案資料夾的結構以下,js資料夾裡麪包含jQuery程式庫。

Node.js專案資料夾的結構

底下是mqtt.js當中的socket.io程式碼,它負責把收到的MQTT主題訊息即時轉發給HTML網頁,相關說明請參閱《超圖解物聯網IoT實做入門》「使用Socket.io創建即時連線」單元(5-27頁)。

socket.io程式碼

mqtt.js的完整程式碼以下:

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

var mqtt = require('mqtt');

var opt = {

  port:1883,

  clientId: 'nodejs'

};

var io = require("socket.io");

var express = require("express");

var app = express();

app.use(express.static('www'));

var server = app.listen(5438);

 

var client  = mqtt.connect('tcp://192.168.1.19');

var sio = io.listen(server);

 

client.on('connect', function () {

  console.log('已連接至MQTT伺服器');

  client.subscribe("home/yard/DHT11");

});

 

sio.on('connection', function(socket){

  client.on('message', function (topic, msg) {

      console.log('收到 ' + topic + ' 主題,訊息:' + msg.toString());

      socket.emit('mqtt', { 'msg': msg.toString() });

  });

});

 

HTML和前端JavaScript程式碼請直接參考底下的index.html原始碼;在瀏覽器端解析JSON資料、使用jQuery動態更新網頁內容,請參閱《超圖解物聯網IoT實做入門》第2-23和2-25頁。讀者也能搭配第九章介紹的C3.js或D3.js程式庫,以視覺化圖表呈現動態數據。

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

<html>

  <head>

    <meta charset="utf-8">

    <title>MQTT即時溫濕度</title>

  </head>

  <body>

    <h1>MQTT即時溫濕度</h1>

    <p>

      溫度:<span id="temp">??</span> &deg; <br>

      濕度:<span id="hum">??</span> %

    </p>

 

    <script src="/socket.io/socket.io.js"></script>

    <script src="js/jquery-2.1.3.min.js"></script>

    <script>

    $(function(){

      var socket = io.connect();

 

      socket.on('mqtt', function (data) {

        var json = JSON.parse(data.msg);

 

        $("#temp").html(json.temp);

        $("#hum").html(json.humid);

      });

    });

    </script>

  </body>

</html>

 

延伸閱讀

相關文章
相關標籤/搜索