MQTT.js 入門教程


簡介

MQTT.js 是一個開源的 MQTT 協議的客戶端庫,使用 JavaScript 編寫,主要用於 Node.js 和 瀏覽器環境中。是目前 JavaScript 生態中使用最為廣泛的 MQTT 客戶端庫

MQTT 是一種基於發布/訂閱模式的輕量級物聯網消息傳輸協議,可以用極少的代碼和帶寬為聯網設備提供實時可靠的消息服務,它廣泛應用於物聯網、移動互聯網、智能硬件、車聯網、電力能源等行業。

由於 JavaScript 單線程特性,MQTT.js 是全異步 MQTT 客戶端,MQTT.js 支持 MQTT/TCP、MQTT/TLS、MQTT/WebSocket,在不同運行環境支持的度如下:

  • 瀏覽器環境:MQTT over WebSocket(包括微信小程序、支付寶小程序等定制瀏覽器環境)
  • Node.js 環境:MQTT、MQTT over WebSocket

不同環境里除了少部分連接參數不同,其他 API 均是相同的。且在 MQTT.js v3.0.0 及以上版本后,已經完整支持到 MQTT 5.0。

安裝

使用 npm 或 yarn 安裝

npm install mqtt --save

# 或使用 yarn

yarn add mqtt

注意:如果您的 Node 環境是 v12 或 v14 及以上版本,請使用 MQTT.js 4.0.0 及以上版本

使用 CDN 安裝

在瀏覽器環境中,我們還可以使用 CDN 的方式引入 MQTT.js。MQTT.js 的 bundle 包通過 http://unpkg.com 管理,我們可以直接添加 unpkg.com/mqtt/dist/mqtt.min.js 來進行使用。

<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
<script>
  // 將在全局初始化一個 mqtt 變量
  console.log(mqtt)
</script>

全局安裝

除了上述的安裝方式外,MQTT.js 還提供了全局安裝的方式,使用命令行工具來完成 MQTT 的連接、發布和訂閱等。

npm install mqtt -g

我們會在下文中的一些使用教程中詳細描述如何使用 MQTT.js 的命令行工具。

使用

本文將使用 EMQ X Cloud 提供的 免費公共 MQTT 服務器 作為本次測試的 MQTT 服務器地址,服務器接入信息如下:

  • Broker: broker.emqx.io
  • TCP Port: 1883
  • SSL/TLS Port: 8883

更多詳情請訪問 EMQ X Cloud 官網,或查看 EMQ X Cloud 文檔

簡單例子

我們簡單編寫一段代碼實現連接到 EMQ X Cloud 的並完成訂閱主題、收發消息的例子:

const mqtt = require('mqtt')
const options = {
  // Clean session
  clean: true,
  connectTimeout: 4000,
  // Auth
  clientId: 'emqx_test',
  username: 'emqx_test',
  password: 'emqx_test',
}
const client  = mqtt.connect('mqtt://broker.emqx.io:1883')
client.on('connect', function () {
  console.log('Connected')
  client.subscribe('test', function (err) {
    if (!err) {
      client.publish('test', 'Hello mqtt')
    }
  })
})

client.on('message', function (topic, message) {
  // message is Buffer
  console.log(message.toString())
  client.end()
})

命令行

在全局安裝完 MQTT.js 后,我們同樣可以使用命令行工具來完成主題訂閱消息發布接收的動作。

示例連接到 broker.emqx.io 並訂閱 testtopic/# 主題:

mqtt sub -t 'testtopic/#' -h 'broker.emqx.io' -v

示例連接到 broker.emqx.io 並向 testtopic/hello 主題發送消息

mqtt pub -t 'testtopic/hello' -h 'broker.emqx.io' -m 'from MQTT.js'

API 介紹

mqtt.connect([url], options)

連接到指定的 MQTT Broker 的函數,並始終返回一個 Client 對象。第一個參數傳入一個 URL 值,URL 可以是以下協議:mqtt, mqtts, tcp, tls, ws, wss。URL 也可以是一個由 URL.parse() 返回的對象。然后再傳入一個 Options 對象,用於配置 MQTT 連接時的選項。下面列舉一些常用的 Options 對象中的屬性值:

  • Options

    • keepalive: 單位為,數值類型,默認為 60 秒,設置為 0 時禁止
    • clientId: 默認為 'mqttjs_' + Math.random().toString(16).substr(2, 8),可以支持自定義修改的字符串
    • protocolVersion: MQTT 協議版本號,默認為 4(v3.1.1)可以修改為 3(v3.1)和 5(v5.0)
    • clean: 默認為 true,是否清除會話。當設置為 true 時,斷開連接后將清除會話,訂閱過的 Topics 也將失效。當設置為 false 時,離線狀態下也能收到 QoS 為 1 和 2 的消息
    • reconnectPeriod: 重連間隔時間,單位為毫秒,默認為 1000 毫秒,注意:當設置為 0 以后將取消自動重連
    • connectTimeout: 連接超時時長,收到 CONNACK 前的等待時間,單位為毫秒,默認 30000 毫秒
    • username: 認證用戶名,如果 Broker 要求用戶名認證的話,請設置該值
    • password: 認證密碼,如果 Broker 要求密碼認證的話,請設置該值
    • will: 遺囑消息,一個可配置的對象值,當客戶端非正常斷開連接時,Broker 就會向遺囑 Topic 里面發布一條消息,格式為:
      • topic: 遺囑發送的 Topic
      • payload: 遺囑發布的消息
      • QoS: 遺囑發送的 QoS 值
      • retain: 遺囑發布的消息的 retain 標志
    • properties: MQTT 5.0 新增,可配置的對象的屬性值,詳情請參考:https://github.com/mqttjs/MQTT.js#mqttclientstreambuilder-options
  • 如果需要配置 SSL/TLS 連接,Option 對象會被傳遞給 tls.connect() ,因此可以在 option 中配置以下屬性

    • rejectUnauthorized: 是否驗證服務端證書鏈和地址名稱,設置為 false 時將跳過驗證,會暴露在中間人的攻擊之下,所以不建議在生產環境中使用這種配置,當設置為 true 時,將開啟強認證模式,且如果是自簽名證書,請在證書配置時設置 Alt name。
    • ca: 只有在服務器使用自簽名證書時才有必要,自簽名證書中生成的 CA 文件
    • cert: 只有當服務器需要客戶證書認證時才有必要(雙向認證),客戶端證書
    • key: 只有當服務器需要客戶證書認證時才有必要(雙向認證),客戶端密鑰

Client 事件

當連接成功后,返回的 Client 對象可通過 on 方法監聽多個事件,業務邏輯可在監聽的回調函數中完成。以下列舉一些常用的事件:

  • connect

    當連接成功時觸發,參數為 connack

    client.on('connect', function (connack) {
      console.log('Connected')
    })
    
  • reconnect

    當斷開連接后,經過重連間隔時間重新自動連接到 Broker 時觸發

    client.on('reconnect', function () {
      console.log('Reconnecting...')
    })
    
  • close

    在斷開連接以后觸發

    client.on('close', function () {
      console.log('Disconnected')
    })
    
  • disconnect

    在收到 Broker 發送過來的斷開連接的報文時觸發,參數 packet 即為斷開連接時接收到的報文,MQTT 5.0 中的功能

    client.on('disconnect', function (packet) {
      console.log(packet)
    })
    
  • offline

    當客戶端下線時觸發

    client.on('offline', function () {
      console.log('offline')
    })
    
  • error

    當客戶端無法成功連接時或發生解析錯誤時觸發,參數 error 為錯誤信息

    client.on('error', function (error) {
      console.log(error)
    })
    
  • message

    當客戶端收到一個發布過來的 Payload 時觸發,其中包含三個參數,topic、payload 和 packet,其中 topic 為接收到的消息的 topic,payload 為接收到的消息內容,packet 為 MQTT 報文信息,其中包含 QoS、retain 等信息

    client.on('message', function (topic, payload, packet) {
      // Payload is Buffer
      console.log(`Topic: ${topic}, Message: ${payload.toString()}, QoS: ${packet.qos}`)
    })
    

Client 方法

Client 除監聽事件外,也內置一些方法,用來進行發布訂閱的操作等,以下列舉一些常用的方法。

  • Client.publish(topic, message, [options], [callback])

    向某一 topic 發布消息的函數方法,其中包含四個參數:

    • topic: 要發送的主題,為字符串
    • message: 要發送的主題的下的消息,可以是字符串或者是 Buffer
    • options: 可選值,發布消息時的配置信息,主要是設置發布消息時的 QoS、Retain 值等。
    • callback: 發布消息后的回調函數,參數為 error,當發布失敗時,該參數才存在
    // 向 testtopic 主題發送一條 QoS 為 0 的測試消息
    client.publish('testtopic', 'Hello, MQTT!', { qos: 0, retain: false }, function (error) {
      if (error) {
        console.log(error)
      } else {
        console.log('Published')
      }
    })
    
  • Client.subscribe(topic/topic array/topic object, [options], [callback])

    訂閱一個或者多個 topic 的方法,當連接成功需要訂閱主題來獲取消息,該方法包含三個參數:

    • topic: 可傳入一個字符串,或者一個字符串數組,也可以是一個 topic 對象,{'test1': {qos: 0}, 'test2': {qos: 1}}
    • options: 可選值,訂閱 Topic 時的配置信息,主要是填寫訂閱的 Topic 的 QoS 等級的
    • callback: 訂閱 Topic 后的回調函數,參數為 error 和 granted,當訂閱失敗時 error 參數才存在, granted 是一個 {topic, qos} 的數組,其中 topic 是一個被訂閱的主題,qos 是 Topic 是被授予的 QoS 等級
    // 訂閱一個名為 testtopic QoS 為 0 的 Topic
    client.subscribe('testtopic', { qos: 0 }, function (error, granted) {
      if (error) {
        console.log(error)
      } else {
        console.log(`${granted[0].topic} was subscribed`)
      }
    })
    
  • Client.unsubscribe(topic/topic array, [options], [callback])

    取消訂閱單個主題或多個主題,該方法包含三個參數:

    • topic: 可傳入一個字符串或一個字符串數組
    • options: 可選值,取消訂閱時的配置信息
    • callback: 取消訂閱時的回調函數,參數為 error,當取消訂閱失敗時 error 參數才存在
    // 取消訂閱名為 testtopic 的 Topic
    client.unsubscribe('testtopic', function (error) {
      if (error) {
        console.log(error)
      } else {
        console.log('Unsubscribed')
      }
    })
    
  • Client.end([force], [options], [callback])

    關閉客戶端,該方法包含三個參數:

    • force: 設置為 true 時將立即關閉客戶端,而無需等待斷開連接的消息被接受。這個參數是可選的,默認為 false。注意:使用該值為 true 時,Broker 無法接收到 disconnect 的報文
    • options: 可選值,關閉客戶端時的配置信息,主要是可以配置 reasonCode,斷開連接時的 Reason Code
    • callback: 當客戶端關閉時的回調函數
    client.end()
    

總結

至此就簡單的介紹了 MQTT.js 一些常用的 API 的使用方法等,具體在實際項目中的使用請參考以下鏈接:

版權聲明: 本文為 EMQ 原創,轉載請注明出處。

原文鏈接:https://www.emqx.com/zh/blog/mqtt-js-tutorial

技術支持:如對本文或 EMQ 相關產品有疑問,可訪問 EMQ 問答社區 https://askemq.com 提問,我們將會及時回復支持。

更多技術干貨,歡迎關注我們公眾號【EMQ 中文社區】。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM