摘要
MQTT是一种基于发布/订阅模型的轻量级消息协议,专为资源受限的物联网设备设计,能够在低带宽和不稳定网络环境下实现高效可靠的数据通信。其核心通过消息代理(Broker)实现发布者与订阅者的解耦,支持大规模设备连接,并提供不同服务质量等级保障消息传输。MQTT还具备良好的安全性、可扩展性和广泛的语言支持,已成为IoT领域的事实标准协议之一。
关键点
- MQTT是一种用于机器对机器通信的标准消息协议,广泛应用于物联网设备数据传输。
- 该协议具有轻量级特性,占用资源少,适用于微控制器等低性能设备。
- MQTT采用发布/订阅模型,通过消息代理实现发送者与接收者解耦。
- 协议支持大规模扩展,可连接数百万级设备。
- 提供三种服务质量等级(QoS 0/1/2)以确保消息传输的可靠性。
- MQTT通过TLS、OAuth等机制支持加密和身份认证,保障通信安全。
- MQTT客户端与代理通过TCP/IP连接,客户端之间不直接通信。
- 主题(Topic)机制用于消息分类与过滤,支持层级结构。
- MQTT不属于REST架构,但在5.0版本中引入类似请求/响应的机制。
用 Python + MQTT 做一个“温度传感器发布数据 + 客户端订阅接收”的示例。
使用
1️⃣ 安装依赖
pip install paho-mqtt
2️⃣ 发布端(模拟温度传感器)
import paho.mqtt.client as mqtt
import time
import random
broker = "test.mosquitto.org" # 公共MQTT服务器
topic = "demo/temperature"
client = mqtt.Client()
client.connect(broker, 1883, 60)
while True:
temp = round(random.uniform(20, 30), 2)
message = f"Temperature: {temp}°C"
client.publish(topic, message)
print("发布:", message)
time.sleep(2)
👉 这个程序每2秒发布一次温度数据到 demo/temperature 这个主题。
3️⃣ 订阅端(接收数据)
import paho.mqtt.client as mqtt
broker = "test.mosquitto.org"
topic = "demo/temperature"
def on_message(client, userdata, msg):
print(f"收到消息: {msg.payload.decode()}")
client = mqtt.Client()
client.connect(broker, 1883, 60)
client.subscribe(topic)
client.on_message = on_message
print("开始监听...")
client.loop_forever()
👉 这个程序会持续监听该主题,一有消息就打印出来。
4️⃣ 运行效果
你会看到类似:
发布端:
发布: Temperature: 25.3°C
发布: Temperature: 27.1°C
订阅端:
收到消息: Temperature: 25.3°C
收到消息: Temperature: 27.1°C
5️⃣ 这个例子对应MQTT概念
- 发布者(Publisher):温度传感器程序
- 订阅者(Subscriber):接收程序
- Broker:
test.mosquitto.org - Topic:
demo/temperature
QoS
QoS(Quality of Service,服务质量)是 MQTT里用来保证消息“送达程度”的机制。
MQTT一共有 3个等级:
✅ QoS 0:最多一次(At most once)
- 📦 特点:发出去就不管了
- ❌ 可能丢消息
- ✅ 不会重复
- 🚀 速度最快、开销最小
👉 类似:UDP
适用场景:
- 传感器实时数据(温度、湿度)
- 丢一两条无所谓
✅ QoS 1:至少一次(At least once)
- 📦 特点:保证送达
- ✅ 不会丢
- ⚠️ 可能重复(会重发)
👉 类似:发短信,可能收到两条
适用场景:
- 日志上传
- 状态上报(可以去重)
✅ QoS 2:刚好一次(Exactly once)
- 📦 特点:最严格
- ✅ 不丢
- ✅ 不重复
- 🐢 最慢、最耗资源(需要4步握手)
👉 类似:银行转账(必须且只能一次)
适用场景:
- 支付
- 关键指令(开锁、控制设备)
🔁 对比一眼看懂
- QoS 0 → 快但不可靠
- QoS 1 → 稳但可能重复
- QoS 2 → 最安全但最慢
🧪 代码里怎么用?
发布时指定:
client.publish("demo/topic", "hello", qos=1)
订阅时指定:
client.subscribe("demo/topic", qos=1)
👉 最终效果取决于 发布和订阅中较低的那个QoS
如果你愿意,我可以画一个“QoS1 和 QoS2 的握手流程图”,会一下子更清楚。