系统:Ubuntu20.04, windows
软件要求:
(1)下载安装mosquitto
1. Linux通过ppa安装之后会自动启动服务,可以通过systemctl status mosquitto.service
查看,默认配置文件路径在/etc/mosquitto/mosquitto.conf
,如果修改了conf配置文件,需要重启服务以生效,参考教程https://www.dtmao.cc/news_show_759697.shtml,可以修改配置文件为:
#设置不允许匿名登录
allow_anonymous false
#设置账户密码文件位置为C:\MosquittoTest\pwfile.example
password_file pwfile.example
#把日志信息输入到指定文件
log_dest file mosquittotest.log
#在控制台输出信息,运行win服务无效
log_dest stdout
#不记录
#log_type none
#########下面的debug、error、warning.....等等可以组合使用。
#记录网络通信包,通信包大小(含心跳包),但不显示内容
log_type debug
#错误信息(没见过)
log_type error
#警告信息(没见过)
log_type warning
#设备的订阅信息、发布信息及下线信息(端口、设备名、用户、不包发布内容)
log_type notice
#服务启动关闭信息、版本号、端口号、配置文件信息
log_type information
#所有设备订阅主题提醒
log_type subscribe
#这个没有试出来干啥用的(没见过)
log_type unsubscribe
#websockets链接信息(没见过)
#MQTT协议
port 1883
protocol mqtt
#websockets协议
listener 8000
protocol websockets
log_type websockets
websockets_log_level 0
- windows系统下载安装后目录如下图所示:和Linux一样,需要配置 conf文件,另外,
pwfile.example
是存储用户名的文件,在conf中会用到
(2)安装python mqtt客户端:pip3 install -i https://pypi.doubanio.com/simple paho-mqtt
基本思路
首先在Linux或者windows系统运行mqtt服务程序,等待客户端连接;然后用python编写两个程序,一个用来发布信息,一个用来订阅信息,注意这两个程序都是需要连接到mqtt服务器的,发布信息和订阅信息的程序之间解耦,一切交给mqtt服务器去处理。
1.mqtt发布程序
# -*- coding: utf-8 -*-
"""
Created on Sun Jun 20 09:38:02 2021
@author: Wenqing Zhou (zhou.wenqing@qq.com)
@github: https://github.com/ouening
"""
# 参考链接:
# (1)https://www.cnblogs.com/chenpingzhao/p/11383856.html
# (2)https://www.emqx.cn/blog/how-to-use-mqtt-in-python
# (3)https://www.dtmao.cc/news_show_759697.shtml
import random
import time
import datetime
from paho.mqtt import client as mqtt_client
## ===========方法1===========
# 使用mosquitto服务端程序创建本地的mqtt服务,需要配置mosquitto.conf文件,
# 可以参考https://www.dtmao.cc/news_show_759697.shtml,此时host是127.0.0.1,或者是通过ipconfig(windows)查看本机ip地址
broker = '127.0.0.1'
## ==========方法2============
# 笔者在腾讯云有个带公网ip的ubuntu服务器,通过ppa安装好mosquitto之后,修改conf配置文件,
# 创建用户,重启mosquitto服务
# broker = '服务器ip地址' # 使用公网服务器ip地址
## ==========方法3============
# 使用物联网厂商提供的公共服务器或者私有服务器进行连接,可以参考https://www.emqx.cn/blog/how-to-use-mqtt-in-python
# broker = 'broker.emqx.io'
port = 1883
username = 'kindy'
passwd = 'kindy'
topic = "kindy/topic1"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 1000)}'
# 连接mqtt服务器
def connect_mqtt():
def on_exec(strcmd):
print ("Exec:",strcmd)
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
def on_publish(mqttc, obj, mid):
print("OnPublish, mid: "+str(mid))
def on_subscribe(mqttc, obj, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
def on_log(mqttc, obj, level, string):
print("Log:"+string)
def on_message(mqttc, obj, msg):
curtime = datetime.datetime.now()
strcurtime = curtime.strftime("%Y-%m-%d %H:%M:%S")
print(strcurtime + ": " + msg.topic+" "+str(msg.qos)+" "+str(msg.payload))
on_exec(str(msg.payload))
client = mqtt_client.Client(client_id)
print(client)
client.on_connect = on_connect
client.on_log = on_log
client.on_message = on_message
# 连接mqtt服务器
client.username_pw_set(username, password=passwd)
client.connect(broker, port)
return client
def publish(client):
msg_count = 0
while True:
time.sleep(1)
msg = f"messages: {msg_count}"
result = client.publish(topic, msg)
# result: [0, 1]
status = result[0]
if status == 0:
print(f"Send `{msg}` to topic `{topic}`")
else:
print(f"Failed to send message to topic {topic}")
msg_count += 1
def run():
client = connect_mqtt()
client.loop_start()
publish(client)
if __name__ == '__main__':
run()
2. mqtt订阅程序
# -*- coding: utf-8 -*-
"""
Created on Sun Jun 20 09:38:33 2021
@author: Wenqing Zhou (zhou.wenqing@qq.com)
@github: https://github.com/ouening
"""
# 参考链接:
# (1)https://www.cnblogs.com/chenpingzhao/p/11383856.html
# (2)https://www.emqx.cn/blog/how-to-use-mqtt-in-python
# 除了以下通过python程序接收mqtt订阅信息外,还可以下载相关的mqtt客户端程序,例如https://mqttx.app/zh
import random
from paho.mqtt import client as mqtt_client
# broker = 'broker.emqx.io'
# broker = '127.0.0.1'
broker = '服务器ip地址'
port = 1883
username = 'kindy'
passwd = 'kindy'
topic = "kindy/topic1"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 100)}'
def connect_mqtt() -> mqtt_client:
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt_client.Client(client_id)
client.on_connect = on_connect
# 连接mqtt服务器
client.username_pw_set(username, password=passwd)
client.connect(broker, port)
return client
def subscribe(client: mqtt_client):
def on_message(client, userdata, msg):
print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
client.subscribe(topic)
client.on_message = on_message
def run():
client = connect_mqtt()
subscribe(client)
client.loop_forever()
if __name__ == '__main__':
run()