Ubuntu 安裝MQTT伺服器 & 測試與程式開發

楊皓程 2022/09/08

Last Updated on 2022/09/16 14:16

LINE加好友QRCode


◆ 課前準備
  1. Linux 虛擬機/伺服器(Ubuntu 20.04.1 LTS) 架設及安裝請參考 [Microsoft Hyper-V 安裝 Ubuntu 虛擬機器教學]
  2. 安裝 PuTTYWinSCP 工具,並完成連線設定
1. Ubuntu 安裝 MQTT 伺服器

1-1. Ubuntu 伺服器環境軟體更新

確保軟體版本符合本篇文章所用的環境,需使用 apt 將軟體升級到最新版本,此次操作使用 PuTTYroot 權限透過 ssh 連線至伺服器

root@aiot-1-i534:~# apt update
root@aiot-1-i534:~# apt upgrade -y

1-2. 安裝 MQTT 服務及測試工具

首先透過 apt-get 安裝 mosquittomosquitto-clients 套件

root@aiot-1-i534:~# apt install mosquitto mosquitto-clients -y
root@aiot-1-i534:~# systemctl enable mosquitto
root@aiot-1-i534:~# vim /etc/mosquitto/conf.d/test.conf

allow_anonymous true
listener 1883

#重新啟動MQTT服務
root@aiot-1-i534:~# sudo systemctl restart mosquitto

1-3. 測試 MQTT 服務(無安全性,本機測試)

測試 MQTT 需要開啟兩個 PuTTY 視窗,A視窗執行訂閱(Subscribe),B視窗執行推播(Publish)

視窗A:執行訂閱 Subscribe 頻道

root@aiot-1-i534:~# mosquitto_sub -h localhost -p 1883 -t "testchanel" -v

視窗B:執行推播 Publish 頻道

root@aiot-1-i534:~# mosquitto_pub -h localhost -p 1883 -t "testchanel" -m "Hello MQTT"

成功的話就可以從B視窗送出指令,就可以從A視窗接收到訊息

Testing mosquitto_sub and mosquitto_pub in command line

1-4. 設定具帳號密碼認證的 MQTT 服務

修改 mosquitto 設定檔 /etc/mosquitto/conf.d/test.conf

#mosquitto服務拒絕匿名連線,設定密碼檔
root@aiot-1-i534:~# vim /etc/mosquitto/conf.d/test.conf

allow_anonymous false
listener 1883
password_file /etc/mosquitto/passwd

#建立密碼檔
root@aiot-1-i534:~# sudo mosquitto_passwd -c /etc/mosquitto/passwd test
Password: test123
Reenter password: test123
#看一下密碼檔,有沒有建立帳號成功
root@aiot-1-i534:~# cat /etc/mosquitto/passwd

test:$7$101$d+bCwFBFwn8Ltldy$7u6mD...mPKRcc5KB0c4VCHm9VQA==

#重新載入MQTT設定
root@aiot-1-i534:~# sudo systemctl reload mosquitto

※第一次新增帳號mosquitto_passwd指令後面的參數為-c (create a new password file. This will overwrite existing files.),將會覆蓋整個檔案,第二次新增帳號就不需要-c的參數了

※為了方便新增帳號,可以加入指令參數-b (run in batch mode to allow passing passwords on the command line.),並將密碼直接放帳號後即可

#新增第二組MQTT帳號(batch mode)
root@aiot-1-i534:~# sudo mosquitto_passwd -b /etc/mosquitto/passwd hc 12345
#新增第三組MQTT帳號,如果帳號或密碼含特殊符號,可以用單引號包起來
root@aiot-1-i534:~# sudo mosquitto_passwd -b /etc/mosquitto/passwd 'iot-1' '!Aa12345'
#看一下密碼檔,有沒有建立帳號成功
root@aiot-1-i534:~# cat /etc/mosquitto/passwd

test:$7$101$d+bCwFBFwn8Ltldy$7u6mD...mPKRcc5KB0c4VCHm9VQA==
hc:$7$101$TQPXmXPJesBxCtCp$rYPS4tW...24dEoBGMjOERz3XYbZiQ==
iot-1:$7$101$23ix0DMo8Z/j7lwE$1S+L...5TPgYuLm7+oz9PDqLY6g==

#重新載入MQTT設定
root@aiot-1-i534:~# sudo systemctl reload mosquitto

※刪除MQTT使用者

#刪除使用者
root@aiot-1-i534:~# sudo mosquitto_passwd -D /etc/mosquitto/passwd 'iot-1'
root@aiot-1-i534:~# cat /etc/mosquitto/passwd

test:$7$101$d+bCwFBFwn8Ltldy$7u6mD...mPKRcc5KB0c4VCHm9VQA==
hc:$7$101$TQPXmXPJesBxCtCp$rYPS4tW...24dEoBGMjOERz3XYbZiQ==

#重新載入MQTT設定
root@aiot-1-i534:~# sudo systemctl reload mosquitto

1-5. 測試 MQTT 服務(帳號密碼認證,本機測試)

測試 MQTT 需要開啟兩個 PuTTY 視窗,A視窗執行訂閱(Subscribe),B視窗執行推播(Publish)

視窗A:執行訂閱 Subscribe 頻道 (帳號: test,密碼: test123)

root@aiot-1-i534:~# mosquitto_sub -h localhost -p 1883 -u test -P test123 -t "testchanel" -v

視窗B:執行推播 Publish 頻道 (帳號: test,密碼: test123)

root@aiot-1-i534:~# mosquitto_pub -h localhost -p 1883 -u test -P test123 -t "testchanel" -m "Hello MQTT with Authentication"

成功的話就可以從B視窗送出指令,就可以從A視窗接收到訊息

Testing mosquitto_sub and mosquitto_pub in command line with username password

1-6. 測試 MQTT 服務(帳號密碼認證,遠端測試)

這個時間跟 1-5 目的相同,差別在於在不同電腦及軟體測試,測試的電腦與伺服器不同網域,需要確認伺服器是否有固定IP

首先要確認伺服器位址,如果是虛擬IP,兩台電腦必須都是同在一個網域內才有辦法連線,透過 ifconfig 指令可以查詢到目前伺服器網路的狀態

root@aiot-1-i534:~# ifconfig

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
    inet 192.168.88.11 netmask 255.255.255.0 broadcast 192.168.88.255
    inet6 fe80::a0e7:5534:ff9:dbcc prefixlen 64 scopeid 0x20<link>
    ether 00:15:5d:58:0a:00 txqueuelen 1000 (Ethernet)
    RX packets 201940 bytes 136645195 (136.6 MB)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 48849 bytes 3544173 (3.5 MB)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
    inet 127.0.0.1 netmask 255.0.0.0
    inet6 ::1 prefixlen 128 scopeid 0x10<host>
    loop txqueuelen 1000 (Local Loopback)
    RX packets 2204 bytes 208172 (208.1 KB)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 2204 bytes 208172 (208.1 KB)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

如上例,我們知道目前伺服器的IP為 192.168.88.11 ,因此我們測試的電腦就必須在相同區域網路內,才能連線

測試工具使用 Chrome Extension - MQTTBox 作為 MQTT 測試,安裝完成後啟動應用程式

Install Chrome Extension - MQTTBox Tool

啟動程式後,點選 Create MQTT Client

MQTTBox Create MQTT Client

MQTT Client Name: 輸入連線名稱,範例: HC-Server
MQTT Client Id: 可以不用改,或按自動產生
Protocol: 選擇MQTT/TCP
Host: 輸入伺服器IP,範例: 192.168.88.11
Username: 1-4 設定之驗證帳號,範例: test
Password: 1-4 設定之驗證密碼,範例: test123

MQTTBox Client Setting

其他選項不需要修改,最下面按下 Save 即可

MQTTBox Client Setting

完成設定後,會自動連線到 MQTT 伺服器,上方狀態顯示 Connected 就表示成功連線了

MQTTBox Connected

Add subscribeer > 填寫 Topic to subscribe [範例: testchanel] > Subscribe

MQTTBox

Add publisher > Topic to publish [範例: testchanel] > Payload [範例: Hello MQTT] > Publish

成功送出就可以在右邊 subscribe 看到訊息

MQTTBox

2. Python MQTT 連線測試

下載

# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt

#訂閱[testchanel]
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("testchanel")
#收到訂閱
def on_message(client, userdata, msg):
    print(msg.topic+" "+ msg.payload.decode('utf-8'))

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.username_pw_set("test","test123")
client.connect("localhost", 1883, 60)
client.loop_forever()

下載

# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
import random
import json
import time

client = mqtt.Client()

# 設定登入帳號密碼
client.username_pw_set("test","test123")
client.connect("localhost", 1883, 60)

while True:
    #隨機濕度50~60
    value = random.randint(50,60)
    #送出訊息
    payload = {"value":value}
    print(payload)
    #發送目的
    client.publish("testchanel", json.dumps(payload))
    #延遲5秒
    time.sleep(5)
flag 檔案/工具
  1. 下載 PuTTY & PuTTYgen
  2. 下載 WinSCP | WinSCP Official Site
  3. MQTTBox - Chrome 線上應用程式商店
flag 參考文獻
  1. MQTT Broker 伺服器 Mosquitto 安裝、帳號密碼、加密傳輸設定教學與範例 - Office 指南