MQTT & Eclipse Mosquitto™

MQTT 消息隊列遙測傳輸(Message Queuing Telemetry Transport)是 ISO 標準(ISO/IEC PRF 20922)下基於發布/訂閱範式的消息協議。它工作在 TCP/IP 協議族上,是為硬體性能低下的遠程設備以及網絡狀況糟糕的情況下而設計的發布/訂閱型消息協議,為此,它需要一個消息中間件 。 為何說是硬體性能低下,因為應用場景在 IoT 的應用需要考慮在低耗電長時間待命的狀態下在短時間內完成資料傳送過程。 以及網路狀況糟糕,因為地處偏遠訊號複雜狀態下會做訊息傳送與接收的確認。

Share This Post

MQTT 介紹

今天介紹的是因應 IoT 而生的 MQTT(Message Queuing Telemetry Transport)。

起源

MQTT 消息隊列遙測傳輸(Message Queuing Telemetry Transport)是 ISO 標準(ISO/IEC PRF 20922)下基於發布/訂閱範式的消息協議。它工作在 TCP/IP 協議族上,是為硬體性能低下的遠程設備以及網絡狀況糟糕的情況下而設計的發布/訂閱型消息協議,為此,它需要一個消息中間件 。
為何說是硬體性能低下,因為應用場景在 IoT 的應用需要考慮在低耗電長時間待命的狀態下在短時間內完成資料傳送過程。
以及網路狀況糟糕,因為地處偏遠訊號複雜狀態下會做訊息傳送與接收的確認。

特點介紹

  • 連接: 等待與伺服器建立連接然後創建節點之間的連接.
  • 斷開連接: 待 MQTT 客戶端完成所必須完成的工作,然後等待 TCP/IP 會話關閉連接。
  • 發布: 將請求傳遞給 MQTT 客戶端後立即返回到應用程式執行緒。
  • 服務品質(QOS)
    • 服務品質: 服務品質指的是交通優先級和資源預留控制機制,而不是接收的服務品質。 服務品質是為不同應用程式,用戶或數據流提供的不同優先級的能力,或者也可以說是為數據流保證一定的性能水平的能力。
    • 以下是每一個服務品質級別的具體描述
      • 0: 最多一次傳送 (只負責傳送,發送過後就不管數據的傳送情況)
      • 1: 至少一次傳送 (確認數據交付)
      • 2: 正好一次傳送 (保證數據交付成功)

MQTT的Publisher, Broker和Subscriber

根據MQTT 3.1.1版本規格書的描述,MQTT是一種基於「發布∕訂閱」機制的訊息傳輸協定(MQTT is a Client Server publish/subscribe messaging transport protocol),我們可以把它想成雜誌發行和訂閱的機制。MQTT訊息發送端,相當於雜誌出版社,雜誌出版之後並不直接寄給消費者,而是交給經銷商或者書店一般的代理人(broker),來統籌管理發行和訂閱事宜。每一個訊息來源(刊物)都有個唯一的主題名稱(刊物名稱)。

代理人是個伺服器軟體,向伺服器發送主題的一方是發布者(publisher),從伺服器獲取主題的一方則是訂閱者(subscriber)。以下圖為例,傳送感測器資料的一邊是發布者,接收感測器資料的一邊則是訂閱者。每個感測器∕微控器的訊息都需要有個主題名稱以利識別,像下圖的主題A、B和C。

架設 MQTT Broker

Windows

安裝 Mosquitto

mosquitto-2.0.14-install-windows-x64.exe

安裝完成後,打開工作管理員確認服務是否開啟。

Windows 要記得檢查防火牆設定,不然可能會連不到。


Linux

> sudo apt-get update
> sudo apt-get -y upgrade
> sudo apt install -y mosquitto

檢查 Mosquitto 是否有執行

> sudo systemctl status mosquitto
● mosquitto.service - Mosquitto MQTT v3.1/v3.1.1 Broker
     Loaded: loaded (/lib/systemd/system/mosquitto.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2022-03-17 05:37:30 UTC; 9min ago
       Docs: man:mosquitto.conf(5)
             man:mosquitto(8)
   Main PID: 12499 (mosquitto)
      Tasks: 3 (limit: 4677)
     Memory: 1.2M
     CGroup: /system.slice/mosquitto.service
             └─12499 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf

Mar 17 05:37:30 mqtt systemd[1]: Starting Mosquitto MQTT v3.1/v3.1.1 Broker...
Mar 17 05:37:30 mqtt mosquitto[12499]: [  220.488739]~DLT~12499~INFO     ~FIFO /tmp/dlt cannot be opened. Retrying late>
Mar 17 05:37:30 mqtt systemd[1]: Started Mosquitto MQTT v3.1/v3.1.1 Broker.

設定 MQTT

MQTT 的設定檔為 mosquitto.conf,預設會放在以下路徑:

Windows

你的mosquitto安裝路徑/mosquitto/mosquitto.conf

Linux

/etc/mosquitto/mosquitto.conf

加上以下基本設定

# MQTT 是否允許匿名連入
allow_anonymous true 

# MQTT Port & Protocol 設定
listener 1883
protocol mqtt

listener 1884
protocol websockets

連線到 Broker & Subscribe topics

Windows

Windows 可以使用 MQTTX

新增一個連線

連線成功

Subscribe topics “demo”

python

import paho.mqtt.client as mqtt

# mqtt subscribedefmqtt_sub(client, userdata, flags, rc):
  print("Connected")
  client.subscribe("demo")
 
# mqtt message defmptt_message(client, userdata, msg):
  print(msg.payload)

# mptt init
client = mqtt.Client()
client.on_connect = mqtt_sub
client.on_message = mptt_message

# 身分驗證用,後面會講# client.username_pw_set("admin","admin")# client.connect(HOST, PORT, KEEPALIVE)
client.connect("localhost", 1883, 60)
client.loop_forever()

node.js

const mqtt =require("mqtt");const mqttConnection ={host:"localhost",port:1883,endpoint:"/",clean:true,clientId:"node_32f83427",username:'admin',//身分驗證用,後面會講password:'admin',//身分驗證用,後面會講};const{host, port, endpoint,...options}= mqttConnection;const connectUrl =`mqtt://${host}:${port}${endpoint}`;
console.log("=== create connection mqtt ===", connectUrl);const client = mqtt.connect(connectUrl, options);

client.on("error",(error)=>{
  console.log("[MQTT] Connection failed", error);});const subTopic ={"demo":{qos:1}};
client.subscribe(subTopic,(error)=>{if(!error){
    console.log("[MQTT] Subscribe to topics", subTopic);return;}
  console.log("[MQTT] Subscribe to topics error", error);});

client.on("message",(topic, payload)=>{const data =JSON.parse(payload);
  console.log(`[MQTT] topic ${topic}`);
  console.log("[MQTT] ", data);});

發送測試

新增 MQTT 身份驗證

建立密碼檔

Windows

> 你的mosquitto安裝路徑\mosquitto\mosquitto_passwd.exe -c "密碼檔存放路徑\密碼檔名稱" username
Password:
Reenter Password:

Linux

> sudo mosquitto_passwd -b 密碼檔存放路徑/密碼檔名稱 username password

修改 MQTT 設定檔

# MQTT 是否允許匿名連入
allow_anonymous false

password_file **密碼檔路徑**

要記得重啟 MQTT

> sudo systemctl restart mosquitto

設定好後,之後連入都要帶帳號密碼才能連線。

訂閱研究文章

Get updates and learn from the best

More To Explore

Scroll to Top

hurry up !

軟體工程師培訓

限時免費報名中

藉由與「真實世界軟體專案」相同的技術、工具與開發流程,化簡成與商業機密無關、門檻較低更容易上手的「模擬專案」,讓你有機會在職場前輩的陪伴下,完成真槍實彈的練習,動手解決真實的問題,快速累積個人的經驗與作品,而不只是「學習技術」而已。