«
树莓派安装搭建MQTT服务

时间:2023-6-28    作者:Deri    分类: 树莓派


环境安装

sudo apt-get install libssl-dev
sudo apt-get install uuid-dev
sudo apt-get install cmake
sudo apt install libcjson1 libcjson-dev

下载Mosquitto

从下面网页下载最新软件包并解压到文件夹;
https://mosquitto.org/download/
如:https://mosquitto.org/files/source/mosquitto-2.0.15.tar.gz
解压命令如:

tar -zxvf mosquitto-2.0.15.tar.gz

安装

进入到解压后的文件夹
sudo make
sudo make install

如果遇到问题,就是缺少各种组件,参考:
编译找不到openssl/ssl.h
安装openssl
sudo apt-get install libssl-dev

编译过程g++命令未找到:
sudo apt-get install g++

编译过程找不到ares.h
sudo apt-get install libc-ares-dev

编译过程找不到uuid/uuid.h
sudo apt-get install uuid-dev

编辑配置文件(非必须)

编辑/etc/mosquitto/mosquitto.conf

//配置允许外部访问的端口设置
//配置不允许匿名访问,需输入账号密码才可订阅或者发布,如果设为true,则只能本机访问
//配置账号密码存放的路径,注意更改为实际路径,并且先创建这个文件
listener 1883
allow_anonymous false
password_file /etc/mosquitto/pwfile.example

设置用户名和密码(非必须)

sudo mosquitto_passwd /etc/mosquitto/pwfile.example 用户名
然后输两次密码

启动

sudo mosquitto -v
后台启动
sudo mosquitto -d

可以看到监听端口号为1883,IP地址就是树莓派的IP地址

使用过程中找不到libmosquitto.so.1

error while loading shared libraries: libmosquitto.so.1: cannot open shared object file: No such file or directory
解决方法——修改libmosquitto.so位置:
创建链接
sudo ln -s /usr/local/lib/libmosquitto.so.1 /usr/lib/libmosquitto.so.1
更新动态链接库
sudo ldconfig

提示没有对应用户,则创建一个

报错:Warning: Unable to drop privileges to 'mosquitto' because this user does not exist. Trying 'nobody' instead.

sudo groupadd mosquitto
sudo useradd -g mosquitto mosquitto
sudo chown -R mosquitto:mosquitto /etc/mosquitto/

开机自启

编辑cron

sudo crontab -e
加入一行
sudo mosquitto -v
重启
sudo reboot

命令方式使用

订阅消息主题

mosquitto_sub -v -t topic1

topic1为主题

发布一个消息

mosquitto_pub -t"主题" -m"内容" -u 用户名 -P 密码注意这个P是大写

详细参数

mosquitto_pub命令参数
-d 打印debug信息
-f 将指定文件的内容作为发送消息的内容
-h 指定要连接的域名 默认为localhost
-i 指定要给哪个cilentld的用户发送消息
-l 指定给哪个clientld前缀的用户发送消息
-m 消息内容
-n 发送一个空(null)消息
-p 连接端口号
-q 指定QoS的值(0,1,2)
-t 指定topic
-u 指定broker访问用户
-P指定broker 访问密码
-V 指定MQTT协议版本
–will-payload 指定一个消息,该消息当客户端与broker意外断开连接时发出。该参数需要与–will-topic一起使用
–will-qos Will的QoS值。该参数需要与–will-topic一起使用
–will-retain 指定Will消息被当做一个retain消息(即消息被广播后,该消息被保留起来)。该参数需要与–will-topic一起使用
–will-topic 用户发送Will消息的topic。

mosquitto_sub 命令参数说明
-c 设定‘clean session’为无效状态,这样一直保持订阅状态,即便是已经失去连接,如果再次连接仍旧能够接收的断开期间发送的消息。
-d 打印debug信息
-h 指定要连接的域名 默认为localhost
-i 指定clientld
-l 指定clientld前缀
-k keepalive 每隔一段时间,发PING消息通知broker,仍处于连接状态。 默认为60秒。
-q 指定希望接收到QoS为什么的消息 默认QoS为0
-R 不显示陈旧的消息
-t 订阅topic
-v 打印消息
–will-payload 指定一个消息,该消息当客户端与broker意外断开连接时发出。该参数需要与–will-topic一起使用
–will-qos Will的QoS值。该参数需要与–will-topic一起使用
–will-retain 指定Will消息被当做一个retain消息(即消息被广播后,该消息被保留起来)。该参数需要与–will-topic一起使用
–will-topic 用户发送Will消息的topic

Python方式使用

先安装库

pip3 install paho-mqtt
#没有python3,也可以用python2,安装:pip install paho-mqtt

订阅消息

# 加载库
import paho.mqtt.client as mqtt

broker = "127.0.0.1" # 使用IP地址需要在服务器端已经部署MQTT服务端,并设置允许远程访问
port = 1883 # MQTT 默认端口
keepalive = 60 # 连接保持时间
topic = "/lingshun/mqtt_message" # 需要订阅的主题

# 当客户端收到服务器的CONNACK响应时的回调
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    # 在on_connect()中订阅意味着,如果我们失去连接并重新连接,那么订阅将被更新。
    client.subscribe(topic)

# 当从服务器收到PUBLISH消息时的回调。
def on_message(client, userdata, msg):
    print(msg.topic+" "+str(msg.payload))

client = mqtt.Client() #  创建客户
#设置账号密码
client.username_pw_set(username="UUUUUUU",password="PPPPPPPP")
client.on_connect = on_connect # 当 发生连接时 回调的函数
client.on_message = on_message # 当 收到信息时 回调的函数
client.connect(broker, port, keepalive)  # 建立连接

# 阻断调用,处理网络流量,分配回调并处理重新连接的问题。
# 其他loop*()函数可以提供一个线程接口和一个手动接口。
client.loop_forever()

发布消息

# 加载库
import paho.mqtt.client as mqtt
import time

broker = "127.0.0.1" # 使用IP地址需要在服务器端已经部署MQTT服务端,并设置允许远程访问
port = 1883 # MQTT 默认端口
keepalive = 60 # 连接保持时间
topic = "/lingshun/mqtt_message" # 需要发布的主题

client = mqtt.Client()
#设置账号密码
client.username_pw_set(username="UUUUUUU",password="PPPPPPPP")
client.connect(broker, port)

send_count = 0
while 1:

    msg = f"This is the {send_count} message."
    result = client.publish(topic, msg)
    status = result[0]
    if status == 0:
        print(f"Send `{msg}` to topic `{topic}`")
    else:
        print(f"Failed to send message to topic {topic}")
    send_count += 1
    time.sleep(1)

参考了:
https://lingshunlab.com/book/raspberry-pi/raspberry-pi-use-python-mqtt-paho-simple
https://blog.csdn.net/qq_43010516/article/details/124651792
https://blog.csdn.net/weixin_48487878/article/details/118569070

树莓派 MQTT