MQTT协议基础(1):MQTT协议的基本介绍
MQTT协议的基础知识包括基本定义、通信模型的介绍、Client、Broker介绍
数据包格式:固定头、可变头、消息体
定义&特点
概念:mqqt协议(Message Queuing Telemetry Transport),是运行在tcp/ip协议栈之上的应用层协议,应用场景为物联网行业。
同传统的消息队列相比,MQTT具有以下的不同
- 传统消息队列需要先设立相应的队列来放置消息,而MQTT协议可以不用预先设立topic,直接发布。
- 传统消息队列中未被取用的数据会一直保存,而MQTT协议中发布的消息若没有被任何一个客户端订阅则直接丢弃
- 传统消息队列中,消息只能被一个客户端使用,而MQTT协议下,发布的消息可以被多个客户端订阅并接收
通信模型
概念:MQTT是采用发布/订阅的模式来构建通信模型。图示如下
可以看到,发布方和接收方不必直接建立连接。通过mqtt服务器判别发布/订阅关系,来分发相应的数据。
通信过程
- 在MQTT协议中,我们将服务端称为Broker,客户端称为client。同时客户端中分为:Publisher(发布方),Subscriber(订阅方)
在通讯流程中,其大致过程如下- 发布方与订阅方都建立了到Broker的TCP连接
- 订阅方告知Broker它要订阅的主题(Topic)
- 发布方将消息发送到Broker,并指定消息的主题(Topic)
- Broker接收到消息后,检查哪些订阅方订阅了该主题,分发该消息到相应订阅方
- 订阅方从Broker获取该消息
- 如果某个订阅方此时处于离线状态,Broker先为其保留此条消息,当订阅方下次连接时,将消息发到订阅方
通信主体
MQTT Client
任何终端类型,在程序中运行运行MQTT协议库或者运用其代码,连接到MQTT Broker,都可以称作客户端。客户端中Publisher和Subscriber的属性取决于当前的行为状态是在发布消息还是订阅消息。当然也可以既是Publisher也是Subscriber。
MQTT协议库, 可以查看相关源码:https://github.com/mqtt/mqtt.org/wiki/libraries
MQTT Broker
Broker的主体功能是接收Publisher发布的消息,分发到相应的Subscriber。除此之外还有如下的功能要求
- 可以对Client的接入进行授权,并对Client进行权限控制
- 可以横向扩展,比如集群,满足海量Client的接入
- 有较好的扩展性,可以比较好的接入原有的业务系统
- 易于监控,满足高可用性(注:Broker负责核心的业务,监控其实时状态可以有效避免因Broker故障而停机)
MQTT协议数据包格式
MQTT协议的数据包采用二进制。一个数据包由三部分组成
- 固定头:存在于所有的MQTT协议数据包中,用于表示数据包类型&对应标识&表明数据包大小
- 可变头:存在于部分的MQTT协议数据包中,具体内容由相应类型数据包决定。
- 消息体:存在于部分的MQTT协议数据包中,存储消息的具体数据。
固定头的数据包分析
基本样式:
第一个字节,高四位用来指定报文的类型,第四位用作报文类型标志位。
从第二个字节开始,指定剩余长度。该部分最少一个字节,最多四个字节,表示范围0(0x00)~268 435 455(0xFF 0xFF 0xFF 0x7F),也就是0-256MB.
- 控制报文类型
- 标志位定义(只有PUBLISH不同,其余均被置0保留)
- 剩余长度
在MQTT协议中,采用可变长度来表示剩余长度,这个字段最少一个字节,最多四个字节。其中,每一个字节的最高位叫做延续位,用于标志是否还有一个用于表示剩余长度的字节,剩下的低7位用于标识值0~127.
其可以表示的范围如下
这个范围是如何得来的? 编码时如何确定转换关系。
因为每个字节的最高位是标志位,所以其实际范围可以这样看待
1 | 字节数 范围 计算方式 最大值 |
通俗地说,在MQTT中当达到8的整数倍的字节时,进位要进到下一个字节。
示例:321如何编码?
先判断属于两个字节编码范围。
1 | 321/128= 2 高8位为2 0x02 |
321编码之后0xC1 0x02
可变报头
定义
某些MQTT控制报文中包含可变报头,它在固定报头和负载(消息体)之间。具体内容由报文的类型来确定。常见的报文标识符如下:
应用范围
进一步理解
出于简单理解,可将该标识符类比于TCP传输中序列号。在某些类型的报文中,在发送报文时要为这个新报文分配一个当前并未使用的报文标识符。如果需要重发某个特殊报文,报文标识符必须一致,当客户端处理完这个报文的确认之后,这个报文标识符就可以释放重用了。而且Broker和Client分配的报文标识符是独立的,也就是说可能出现同样的报文标识符但来自不同的主体。
消息体(有效载荷(payload))
定义
最为重要的是在PUBLISH中,有效载荷即为应用消息。
应用范围