MQTT介绍
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅
(publish/subscribe
)模式的“轻量级”通讯协议。
MQTT最大优点在于,用极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。
作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。
在这里笔者不打算做原理性的介绍,而是直接进行演示MQTT的使用过程。
MQTT 服务器
在生产环境中,正常是需要部署MQTT服务器的(或者是使用云服务器厂商的物联网平台)。笔者只是进行短暂的测试,所以使用免费的在线 MQTT 服务器。
EMQ的免费服务器为 2 个节点的 EMQX 企业版集群,部署在上海腾讯云。
EMQ 提供了通俗易懂的技术文章,帮助开发者快速了解 MQTT 协议及其相关特性。
参考EMQ的使用手册,笔者了解到进行测试需要MQTT 服务器信息。
当然,EMQ提供了MQTT客户端工具(用于快速连接和测试 MQTT 服务与应用),可以用来快速测试MQTT服务器的可用性。
在这里,笔者演示使用online-mqtt-client。步骤如下。
进入MQTT客户端工具,界面如下。
参考公共MQTT服务器地址,新建连接。
连接成功,可以看到绿色的提示符。
输入订阅的主题,发送数据。
如果此时没有订阅该主题,是无法接收到数据的,这个时候可以在客户端添加订阅进行测试(或者通过代码对该主题进行订阅)。
发送数据,得到反馈,测试成功。
PC端MQTT测试
参考文档如何在 Python 中使用 MQTT | EMQ (emqx.com)进行测试,参考文档十分详细,因此笔者只提供publish、subscribe的两个文件的代码。
publish.py(代码用于实现向/python/mqtt主题发送消息,消息内容是计数值1、2、3······)
import random
import time
from paho.mqtt import client as mqtt_client
broker = 'broker-cn.emqx.io'
port = 1883
topic = "/python/mqtt"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 1000)}'
def connect_mqtt():
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
client.connect(broker, port)
return client
def publish(client):
msg_count = 0
while True:
time.sleep(1)
msg = f"messages:" + str(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()
subscribe.py(代码功能为mqtt消息的订阅,当消息发布之后打印至控制台)
import random
from paho.mqtt import client as mqtt_client
broker = 'broker-cn.emqx.io'
port = 1883
topic = "/python/mqtt"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 1000)}'
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
client.connect(broker, port)
return client
def subscribe(client: mqtt_client):
def on_message(client, userdata, msg):
print(f"Received `{msg.payload}` 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()
运行以上两端代码,测试结果如下。
这里表明作为发布者,正在发布数据包messages:x,其中x是一个计数值。
这里可以看到订阅者可以接收到数据包,测试成功。
ESP32端MQTT测试
刚才通过PC端演示了MQTT的通信过程,其实并不能体现MQTT在嵌入式通信的实用性。所以笔者在ESP32端进行演示。
首先介绍一下MicroPython。MicroPython和Python编程语言一样,在任何板子上都可以使用通用的API控制硬件底层,比如点亮 LED 灯,读取传感器信息, LCD 显示字符串、控制电机、连接网络、连接蓝牙等等。
因此,笔者参考MQTT快速上手进行测试,利用MQTT客户端工具发布消息为My name is LIN!
,效果如下。
我的想法
笔者通过PC端以及嵌入式端进行了MQTT的通信测试。演示的结果可以表明,通过MQTT协议,可以进行广域网下的设备通信。
实际上,可以通过ESP32+MQTT实现远程的电脑开机棒(不同于WOL网络唤醒),即通过esp32短接电脑主板对应端子实现远程电脑开机。
参考资料
https://zhuanlan.zhihu.com/p/421109780
https://post.smzdm.com/p/a5kq0or7/
https://www.emqx.com/zh/mqtt
https://doc.itprojects.cn/0006.zhishi.esp32/02.doc/index.html#/c05.mqtt
https://zhuanlan.zhihu.com/p/73137316