MQTT协议理解并实践
MQTT是一个轻量的发布订阅模式消息传输协议,专门针对低带宽和不稳定网络环境的物联网应用设计
MQTT协议根据主题来分发消息进行通信,支持通配符匹配,可以低开销的使用数百万Topic进行一对一,一对多双向通信。
协议特点
1. 开放消息协议,简单易实现
2. 发布订阅模式,一对多消息分发和应用程序分离
3. 基于TCP/IP网络连接,有序,无损,双向连接的网络协议
4. 字节固定包头,字节心跳报文,报文结构紧凑,协议交换最小化,以减少网络流量
5. 消息QoS支持,可靠传输保证
服务质量等级
QoS 0:消息可能丢失
QoS 1:消息不会丢失但可能重复
QoS 2:消息不会丢失也不会重复
MQTT报文类型
- 连接
CONNECT,CONNACk,DISCONNECT
- 发布
PUBLISH,PUBACk,PUBREC(publish receive),PUBREL(publish release),PUBCOMP(publish complete)
- 订阅
SUBSCRIBE,SUBACk,UNSUBSCRIBE,UNSUBACk
- 心跳
PINGREQ,PINGRESP
主要报文类型
- CONNECT
客户端标识符
用户名
密码
遗嘱消息
- PUBLISH
主题
QoS
Payload(负载)
- SUBSCRIBE
主题
QoS
发布订阅模式
发布者&订阅者 <----> Broker代理服务 <----> 订阅者&发布者
- 发布,订阅和取消订阅的相关报文
如何发布消息
client ------> publish(Topic Name,QoS,Payload) -------> broker
Topic Name(String):
示例:temperature livingroom/temperature kitchen/temperature
Qos(Integer):
Qos 0 消息可能丢失
Qos 1 消息不会丢失但可能重复
Qos 2 消息不会丢失也不会重复
Payload(Binary):
可为Json类型:
{
“from":"client",
"temperature":26
}
可为Binary类型进制数据
4d 69 72 61 63 6c 65 73...
可为Ciphertext类型加密数据
UFsdGVkX1/PucJg+taTQ...
如何订阅消息
client ------> subscribe(Packet ID,Subscription List) ------> broker
Packet ID:
Subscribe: Packet ID 45678
Suback: Packet ID 45678
Subscription List:
Topic Filter 1(QoS 1)
Topic Filter 2(Qos 2)
Topic Filter 3(Qos 3)
Topic Filter subscribe可以使用主题通配符
subscribed topic a/+
代表: publish to topic a/1
也可代表: publish to topic a/2 等
如何订阅响应
client -----> suback(Packet ID,Reason Codes) ------>Broker
Reason Codes(原因码):
成功:
0x00:订阅成功且最大QoS等级为0
0x01: 订阅成功且最大QoS等级为1
0x02:订阅成功且最大QoS等级为2
失败:
0x80:订阅失败
如何取消订阅
client -----> unsubscribe(Packet ID,Topic Filters) -----> broker
想要取消订阅的Topic Filter ------ 完全的文本匹配 ----- 实际订阅的Topic Filter
取消订阅响应
client ----- unsuback(Packet ID,Person Codes) ------ broker
Topic主题定义:
UTF-8字符串类型,最大长度65535长度,区分大小写
home/livingroom/temperature + 主题通配符 = 一次订阅多个主题
主题通配符类型:
1. 单层通配符(+): /home/+/temperature
2. 多层通配符(#): 也可匹配0个层级 /home/#
3. 以$开头的主题:$SYS/ (客户端上下线事件通知,报文收发统计,Broker状态信息)
注意:通配符+和#可以同时使用,不建议主题以“/”开头或者结尾
准备条件
需要用到的工具
1.EMQX - MQTT Broker
2.MQTTX- MQTT Client
3.Wireshark-网络抓包工具
拉取EMQX镜像
docker pull emqx:5.0.19
运行EMQX
docker run -d --name emqx -p 18083:18083 -p 1883:1883 emqx:5.0.19
修改EMQX日志等级为 Debug
docker exec -i emqx /opt/emqx/bin/emqx ctl log set-level debug
查看EMQX日志
docker logs -f emgx
mqtt题目练习
1. 发布两条QoS1消息,这两条消息将使用不同的 Packet ID,并且Packet ID 不需要我们自己设置。
2. 订阅未授权的主题 ($SYS/#),EMQX将返回 Reason Code 为 0x80的SUBACK。
3. 订阅 a/+,可以收到 a/1、a/2 等主题的消息。
4. 订阅 a/+ 和 a/1,当有客户端发布消息到主题 a/1时,订阅者将收到两条消息。
5. 使用相同的主题过滤器进行多次订阅,新的订阅会覆盖旧的订阅,不会失败,也不会收到重复的消息。
6. 订阅时设置最大 QoS为 1,发布 QoS为2的消息,订阅者收到的消息的 QoS为1
7. 订阅a/1 和a/+,取消订阅 a/+ 主题,只会取消订阅 a/+ 这个主题。
8. example和Example、example/ 属于不同的主题。
9. /example 主题必须用/+ 来匹配,仅使用+是匹配不到的。
10. 单层通配符可以多次出现,订阅 a/+/+/d,可以接收来自 a/1/2/d 和 a/3/4/d 主题的消息。
11. 订阅 a/#,可以接受来自 a/1 和 a/1/2 主题的消息
12. 单层通配符和多层通配符可以同时使用,订阅 a/+/# 主题,发布消息到 a/1/2/3 主题
13. 系统消息,订阅 $SYS/brokers/+/clients/#,可以接收到客户端上下线事件消息。