通过python实现MQTT发布和订阅

前言

   paho-mqtt是一个Python实现的MQTT客户端库,它提供了MQTT协议的基本功能。使用paho-mqtt,你可以在Python应用程序中创建MQTT客户端,连接到MQTT代理(broker),并发布消息和订阅主题。

paho-mqtt具有以下优点:

  1. 支持多种MQTT版本 - paho-mqtt支持MQTT v3.1和v3.1.1两个版本的协议,可以方便地满足不同项目或设备的需求。
  2. 可靠性高 - paho-mqtt使用异步I/O,可确保消息在通信时即使网络中断或断开连接也能够被正确处理。
  3. 容易集成 - paho-mqtt提供了完备、清晰的API,使用非常容易。
  4. 广泛的平台支持 - paho-mqtt适用于各种不同平台、操作系统和Python版本,包括Windows、Linux、macOS等。
  5. 社区活跃 - paho-mqtt是一个活跃的开源项目,在GitHub上有很多开发者参与维护和更新,可以及时获得技术支持和问题解答。

一、安装paho-mqtt

1、通过命令安装

pip install paho-mqtt

二、实现MQTT发布和订阅

1、发布消息

from paho.mqtt import client as mqtt
import uuid


def on_connect(client, userdata, flags, rc):
    """
    一旦连接成功, 回调此方法
    rc的值表示成功与否:
        0:连接成功
        1:连接被拒绝-协议版本不正确
        2:连接被拒绝-客户端标识符无效
        3:连接被拒绝-服务器不可用
        4:连接被拒绝-用户名或密码不正确
        5:连接被拒绝-未经授权
        6-255:当前未使用。
    """
    rc_status = ["连接成功", "协议版本不正确", "客户端标识符无效", "服务器不可用", "用户名或密码不正确", "未经授权"]
    print("connect:", rc_status[rc])


def mqtt_connect():
    """连接MQTT服务器"""
    mqttClient = mqtt.Client(str(uuid.uuid4()))
    mqttClient.on_connect = on_connect  # 返回连接状态的回调函数
    MQTTHOST = "IP"  # MQTT服务器地址
    MQTTPORT = 1883  # MQTT端口
    mqttClient.username_pw_set("username", "password")  # MQTT服务器账号密码, 无密码时注释即可
    mqttClient.connect(MQTTHOST, MQTTPORT, 60)
    mqttClient.loop_start()  # 启用线程连接

    return mqttClient


def mqtt_publish():
    """发布主题为'mqtt/demo',内容为'Demo text',服务质量为2"""
    mqttClient = mqtt_connect()
    text = "Demo text"
    mqttClient.publish('mqtt/demo', text, 2)
    mqttClient.loop_stop()


if __name__ == '__main__':
    mqtt_publish()

2、订阅消息

from paho.mqtt import client as mqtt
import uuid


def on_connect(client, userdata, flags, rc):
    """一旦连接成功, 回调此方法"""
    rc_status = ["连接成功", "协议版本不正确", "客户端标识符无效", "服务器不可用", "用户名或密码不正确", "未经授权"]
    print("connect:", rc_status[rc])


def on_message(client, userdata, msg):
    """一旦订阅到消息, 回调此方法"""
    print("主题:"+msg.topic+" 消息:"+str(msg.payload.decode('gb2312')))


def mqtt_connect():
    """连接MQTT服务器"""
    mqttClient = mqtt.Client(str(uuid.uuid4()))
    mqttClient.on_connect = on_connect  # 返回连接状态的回调函数
    mqttClient.on_message = on_message  # 返回订阅消息回调函数
    MQTTHOST = "IP"  # MQTT服务器地址
    MQTTPORT = 1883  # MQTT端口
    mqttClient.username_pw_set("username", "password")  # mqtt服务器账号密码
    mqttClient.connect(MQTTHOST, MQTTPORT, 60)
    mqttClient.loop_start()  # 启用线程连接

    return mqttClient


def on_subscribe():
    """订阅主题:mqtt/demo"""
    mqttClient = mqtt_connect()
    mqttClient.subscribe("mqtt/demo", 2)
    while True:
        pass


if __name__ == '__main__':
    on_subscribe()

3、通过queue获取订阅消息

  • Queue类

   Queue类是一种FIFO(先进先出)队列,它使用锁来实现线程安全。可以使用Queue(maxsize)创建一个新的队列对象,maxsize是可选参数,指定队列的长度。如果maxsize小于或等于零,则队列大小无限制。

常见方法:

  • get(block=True, timeout=None): 从队列中取出并返回一个元素。如果队列为空,且block为True且timeout不为None,则会阻塞直到获取到一个元素或超时。否则,如果队列为空且block为False,则会引发Empty异常。
  • put(item, block=True, timeout=None): 将item放入队列。如果队列已满,且block为True且timeout不为None,则会阻塞直到有空间或超时。否则,如果队列已满且block为False,则会引发Full异常。
  • empty(): 如果队列为空,则返回True,否则返回False。
  • full(): 如果队列已满,则返回True,否则返回False。
  • qsize(): 返回队列中元素的数量。
# a.py文件
from paho.mqtt import client as mqtt
import uuid
import queue  # 导入 queue 模块,该模块为实现多线程编程提供了队列数据结构

# 创建了一个 Queue 对象,该对象可用于多线程编程中线程间通信和数据共享
message_queue = queue.Queue()


class Subscription():

    def __init__(self, mt_ip, mt_user, mt_pwd):
        self.mt_ip = mt_ip
        self.mt_user = mt_user
        self.mt_pwd = mt_pwd

    def on_connect(self, client, userdata, flags, rc):
        """一旦连接成功, 回调此方法"""
        rc_status = ["连接成功", "协议版本不正确", "客户端标识符无效", "服务器不可用", "用户名或密码不正确", "未经授权"]
        print("connect:", rc_status[rc])

    def on_message(self, client, userdata, msg):
        """
        msg.payload.decode('gb2312', 'ignore'):
        表示将 msg.payload 使用 GB2312 进行解码,并指定当遇到无法解码的字符时使用 ignore 参数进行错误处理,即忽略无法解码的字符

        msg.payload.decode('gb2312'):
        则是指定当遇到无法解码的字符时,抛出 UnicodeDecodeError 异常并停止程序运行
        """
        result = msg.payload.decode('gb2312', 'ignore')
        # 将收到的消息放入到消息队列中
        message_queue.put(result)

    def mqtt_connect(self):
        """连接MQTT服务器"""
        mqttClient = mqtt.Client(str(uuid.uuid4()))
        mqttClient.on_connect = self.on_connect  # 返回连接状态的回调函数
        mqttClient.on_message = self.on_message  # 返回订阅消息回调函数
        mqttClient.username_pw_set(self.mt_user, self.mt_pwd)  # MQTT服务器账号密码
        mqttClient.connect(self.mt_ip, 1883, 60)  # MQTT地址、端口、心跳间隔(单位为秒)
        mqttClient.loop_start()  # 启用线程连接

        return mqttClient

    def on_subscribe(self):
        """订阅主题:mqtt/demo"""
        mqttClient = self.mqtt_connect()
        mqttClient.subscribe("mqtt/demo", 2)
# b.py文件
from a import message_queue, Subscription

run = Subscription("IP", "username", "password")
run.on_subscribe()
while True:
    if not message_queue.empty():
        result = message_queue.get()
        # 处理消息
        print(f"获取数据:{result}")
<think>好的,我现在需要帮助用户在树莓派上配置MQTT并连接到华为云平台。首先,我得回忆一下MQTT的基本概念配置步骤。用户提到他们已经在华为云有相关的工具,比如生成鉴权三元组的在线工具,这可能涉及到ClientID、用户名密码的设置。 首先,树莓派上安装MQTT客户端库,通常是用Python的paho-mqtt库。我需要确保用户正确安装了这个库,可以通过pip安装。然后,连接到华为云需要获取正确的连接参数,比如服务器地址、端口、设备ID、密钥等。用户提供的引用里提到,华为云的MQTT连接参数包括服务器地址、端口1883或8883(SSL),以及鉴权三元组。 接下来,生成鉴权三元组可能需要使用华为云提供的工具,引用[1]中的链接可能相关。用户需要登录华为云IoT平台,创建设备,获取设备ID、密钥,然后用工具生成用户名密码。用户名通常包含设备ID、产品ID时间戳,密码可能是使用密钥加密后的字符串。 然后,编写Python代码连接到MQTT服务器。代码结构可能包括导入库、设置参数、定义回调函数、连接订阅主题。需要注意的是,引用[2]提到命令中的会话编号消息格式,虽然这是针对AT指令的,但MQTT库的使用也需要正确处理参数,比如client_id、用户名、密码,以及保持连接的心跳间隔。 可能还需要处理SSL连接,如果需要使用8883端口,用户可能需要下载华为云的CA证书,并在代码中指定证书路径。引用[3]提到不同云平台的参数类似,可以用数组存储,所以用户可能需要灵活配置参数。 测试连接时,用户需要确保树莓派联网,并且防火墙允许MQTT端口的通信。发布订阅消息时,主题需要符合华为云的规定,比如$oc/devices/{device_id}/sys/properties/report上报属性。 最后,用户可能需要参考示例代码,确保消息格式正确,并处理异常情况,比如网络断开重连。引用[4]中的树莓派示例可能提供了基本的框架,用户可以根据华为云的文档进行调整。 总结步骤:安装依赖、获取华为云连接参数、编写连接代码、测试连接并处理消息。需要提醒用户注意参数的正确性,尤其是设备ID密钥,以及SSL证书的使用。可能的问题包括网络连接问题、参数错误或权限问题,需要逐步排查。</think>### 在树莓派上配置MQTT并连接华为云平台的步骤 #### 1. 安装MQTT客户端库 在树莓派终端执行以下命令安装Python的`paho-mqtt`库: ```bash pip install paho-mqtt ``` #### 2. 获取华为云MQTT连接参数 - **服务器地址**: 参考华为云IoT平台中设备详情页的接入地址,例如:`xxx.iotda.cn-north-4.myhuaweicloud.com`[^1] - **端口**: 非加密端口为`1883`,加密端口为`8883`(需配置SSL证书) - **设备ID**(ClientID): 在华为云IoT平台创建设备时分配的ID,格式如`xxx_xxx` - **用户名**: 格式为`{设备ID}@{产品ID}|{时间戳}|安全模式` - **密码**: 通过华为云工具生成的加密字符串,使用设备密钥工具生成[^1] #### 3. 编写MQTT连接代码 ```python import paho.mqtt.client as mqtt # 华为云连接参数(替换为实际值) huawei_params = { "server": "xxx.iotda.cn-north-4.myhuaweicloud.com", "port": 1883, "client_id": "your_device_id", "username": "your_username", "password": "your_password" } def on_connect(client, userdata, flags, rc): if rc == 0: print("Connected to Huawei Cloud!") client.subscribe("$oc/devices/#") # 订阅设备主题 else: print(f"Connection failed with code {rc}") client = mqtt.Client(client_id=huawei_params["client_id"]) client.username_pw_set(huawei_params["username"], huawei_params["password"]) client.on_connect = on_connect try: client.connect(huawei_params["server"], huawei_params["port"], 60) client.loop_forever() except Exception as e: print(f"Connection error: {e}") ``` #### 4. 数据上报与订阅 - **上报属性**(JSON格式): ```python topic = f"$oc/devices/{huawei_params['client_id']}/sys/properties/report" payload = '{"services": [{"service_id": "temperature","properties": {"value": 25}}]}' client.publish(topic, payload) ``` - **订阅命令**:通过`on_message`回调处理云端下发的指令[^3] #### 5. 配置SSL加密(可选) 若使用8883端口,需下载华为云CA证书并修改代码: ```python client.tls_set(ca_certs="/path/to/ca.crt") client.connect(huawei_params["server"], 8883, 60) ``` #### 关键注意事项 1. 确保树莓派已通过`sudo raspi-config`启用网络接口并连接互联网 2. 设备密钥需通过华为云工具生成 3. 若使用企业版IoTDA,需核对地域节点地址 4. 心跳间隔建议设置为`60-120`秒[^2]
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值