MQTT是一种基于TCP/IP协议栈构建的异步通信协议,是一种轻量级的发布/订阅信息传输协议,基于topic订阅关系的发布和推送;在实践中可空间上,将消息发送者和接受者分离,可以再不可靠的网络环境中进行扩展,适用于设备硬件存储空间有限或网络带宽有限的场景。
上面是比较官方的解释,那么我们用我们听得懂的话来解释,现在的抖音很火,那我们就用抖音举个栗子:
抖音是一个短视频平台,任何人都可以发布自己拍的视频,也可以看别人的视频,那么我们假设有用户A和用户B;
用户A ------关注------> 用户B
用户B ---没有关注---> 用户A
那么就会出现下面的情况:
用户A发送视频 ----不会推送----> 用户B
用户B发送视频 -------推送-------> 用户A
也就是说,用户B没有关注用户A,所以当用户A发布视频后,用户B是不会接收到用户A的视频的;
反之,用户B发布视频后,用户A会第一时间接收到;
那么,用户A为什么会第一时间接受到呢?
这是因为有抖音的服务器作为中间人,当存在订阅(关注)关系后,当用户B发送数据后,服务器会将数据推送给所有订阅(关注)的用户;MQTT就是这样基于topic订阅关系进行发布和推送的!
一、MQTT协议的元素
-
MQTT协议的角色:在MQTT中,就有三个角色,发布者、服务器和订阅者;
-
MQTT协议的主题:在MQTT中,主题可以理解成是发布者,即一个主题我可以发送多条信息,所有订阅了这个主题的用户,都可以接收到该主题信息;
-
MQTT协议的消息:在MQTT中,就可以理解成发布者发布的内容,当订阅者接收到信息后,就可以对信息进行处理;
-
那么服务器在哪里体现呢?
首先,每台主机都可以当做服务端和客户端,即都可以发布信息和接受信息;
其次,一台主机可以发布或订阅多个主题的信息;
二、树莓派上安装Mosquitto
# 安装mosquitto服务
apt-get install mosquitto
# 安装mosquitto工具
apt-get install mosquitto-clients
三、启动Mosquitto服务
mosquitto -v
出现上面的信息,那就证明mosquitto服务已经安装成功,并且服务已经启动了,端口为1883;
四、订阅消息
mosquitto_sub -v -t test -h 10.168.1.193
# mosquitto_sub -v -t 主题 -h 地址
五、发布消息
mosquitto_pub -t test -h 10.168.1.193 -m "hello"
# mosquitto_pub -t 主题 -h 地址 -m 消息内容
六、使用Python来接受并处理数据
- 安装Python MQTT库
pip install paho-mqtt
- 框架代码解释
# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt # 导入mqtt库
# 连接成功回调函数
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
client.subscribe("mqtt_ttt") # 这里即为订阅的主题
# client.subscribe("mqtt_ttt") 这里可以订阅多个主题
# 消息推送回调函数
def on_message(client, userdata, msg):
print(str(msg.topic),str(msg.payload))
# 这里需要注意的是,如果想要对接收到的数据进行处理,那么要转换成str类型
# msg.topic 主题名
# msg.payload 接收的信息
if __name__ == '__main__':
client = mqtt.Client() # 创建mqtt对象
client.on_connect = on_connect # 设置连接成功的回调函数
client.on_message = on_message # 设置接收到信息后的回调函数
try:
client.connect("10.168.1.193", 1883, 60) # 创建连接
client.loop_forever() # 保持监测状态
except KeyboardInterrupt:
client.disconnect() # 断开连接
- 使用MQTT控制树莓派GPIO
# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
import json
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(16,GPIO.OUT)
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
client.subscribe("mqtt_ttt")
# 消息推送回调函数
def on_message(client, userdata, msg):
st = json.loads(msg.payload) # 这里用json对数据进行处理,方便后面对数据的解析
# 还有一个原因是,我直接对数据进行判断,会出现问题,至今没有解决
print(st) # 输出解析后的数据
# 对数据进行判断和处理
if st['dt'] == 1:
GPIO.output(16,GPIO.HIGH)
elif st['dt'] == 0:
GPIO.output(16,GPIO.LOW)
else:
print('err')
if __name__ == '__main__':
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
try:
client.connect("10.168.1.193", 1883, 60)
client.loop_forever()
except KeyboardInterrupt:
client.disconnect()
GPIO.output(16,GPIO.LOW)
GPIO.cleanup()