MQTT在Python的使用整理(2024.11.06)

目的:
一个具备收发功能的mqtt通讯服务器
Debug
由于旧版代码有一些报错,参考官方源码,针对性进行一些删改,主要改动在方法connect_mqtt()

def connect_mqtt():
     # For paho-mqtt 2.0.0, you need to add the properties parameter.
    def on_connect(client, userdata, flags, rc, properties):
        if rc == 0:
            print("Connected to MQTT Broker!")
        else:
            print("Failed to connect, return code %d\n", rc)
    # For paho-mqtt 2.0.0, you need to set callback_api_version.
    client = mqtt_client.Client(client_id=client_id, callback_api_version=mqtt_client.CallbackAPIVersion.VERSION2)

    # client.username_pw_set(username, password)
    client.on_connect = on_connect
    client.connect(broker, port)
    return client

client无法像Rust中那样进行clone,所以想办法绕开它,这里将订阅和连接绑定在一起,则不会在初始化订阅时报错了

 # 将连接与订阅绑在一起,防止复用client导致连接冲突
def connect_mqtt():
    # For paho-mqtt 2.0.0, you need to add the properties parameter.
    def on_connect(client, userdata, flags, rc, properties):
        if rc == 0:
            print("Connected to MQTT Broker!")
        else:
            print("Failed to connect, return code %d\n", rc)
    # For paho-mqtt 2.0.0, you need to set callback_api_version.
    client = mqtt_client.Client(client_id=client_id, callback_api_version=mqtt_client.CallbackAPIVersion.VERSION2)

    # client.username_pw_set(username, password)
    client.on_connect = on_connect
    client.connect(broker, port)
    client.subscribe(su_topic[0])
    print("订阅完成")
    return client

根据需要,又做了一些扩展性修改

整理汇总

测试脚本(mqtt_one.py)

from paho.mqtt import client as mqtt_client
from threading import Thread
import time
 
broker = 'broker.emqx.io'
port = 1883
su_topic = [("python_mqtt_server",2),("python_mqtt_command",2)] #订阅频道,数组格式为(topic,qos)
pu_topic = ["python_mqtt_server"]  #发布频道
client_id = 'python_mqtt_center'


 # 将连接与订阅绑在一起,防止复用client导致连接冲突
def connect_mqtt():
    # For paho-mqtt 2.0.0, you need to add the properties parameter.
    def on_connect(client, userdata, flags, rc, properties):
        if rc == 0:
            print("Connected to MQTT Broker!")
        else:
            print("Failed to connect, return code %d\n", rc)
    # For paho-mqtt 2.0.0, you need to set callback_api_version.
    client = mqtt_client.Client(client_id=client_id, callback_api_version=mqtt_client.CallbackAPIVersion.VERSION2)

    # client.username_pw_set(username, password)
    client.on_connect = on_connect
    client.connect(broker, port)
    subscribe_many(client)
    print("订阅完成")
    return client

 # 订阅多个频道
def subscribe_many(client):
    # 根据client源码可知,订阅支持的数组格式是(topic,qos)
    client.subscribe(su_topic)

# 收到信息的回调函数
def on_message(client, userdata, msg):
    print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
	# 这里可以编写一些收到信息后的处理,比如收到什么信息开启什么任务,任务完成后再调publish发布信息给终端等等........
    # ----------处理例子------------------
    r_msg=msg.payload.decode()
    if int(r_msg)%2==0:
        print("收到偶数")
    # -----------------------------------
# 发布信息函数
def publish(client):
    for i in range(1,11):
        time.sleep(1)
        msg = f"{i}"
        result = client.publish(pu_topic[0], msg)
        # result: [0, 1]
        status = result[0]
        if status == 0:
            print(f"Send `{msg}` to topic `{pu_topic[0]}`")
        else:
            print(f"Failed to send message to topic {pu_topic[0]}")

if __name__ == '__main__':
    client = connect_mqtt()
    client.on_message = on_message  #重写回调函数,可以在方法体里,根据需求改收到信息后干什么
    # 多线程,这里启动一个发布任务的线程,模拟有一个发布消息的客户端
    thread1 = Thread(target=publish,args=(client,)) 
    # --*如要要实现流水线式的收发,则可以将线程内方法改为任务队列处理,用一个全局变量管理任务执行,执行后再publish
    thread1.start()

    client.loop_forever()   #这个要加,监听(on_message)与loop_forever配套
	# thread1.join()        #由于进程堵塞在上方,再join也无意义了

    #------------------------------------------------------------------
    # client.loop_start()   #如果只是发布 那么这个要加,发布与loop_start与stop配套
    # publish(client)
    # client.loop_stop()
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值