什么是MQTT
MQTT是一个客户端服务端架构的发布/订阅模式的消息传输协议。
一、MQTT是一个协议
协议意味着同http协议、https协议、tcp协议等协议一样,MQTT只是一个规范,这个规范告诉你在限定的框架下如何实现特定的功能。
二、MQTT的架构是C-S(client-server)
MQTT是介于客户端和服务端之间进行交互的协议。说的更具体一点,两者在MQTT协议中的定义如下:
客户端 Client
使用MQTT的程序或设备。客户端总是通过网络连接到服务端。它可以
- 发布应用消息给其它相关的客户端。
- 订阅以请求接受相关的应用消息。
- 取消订阅以移除接受应用消息的请求。
- 从服务端断开连接。
服务端 Server
一个程序或设备,作为发送消息的客户端和请求订阅的客户端之间的中介。服务端
- 接受来自客户端的网络连接。
- 接受客户端发布的应用消息。
- 处理客户端的订阅和取消订阅请求。
- 转发应用消息给符合条件的已订阅客户端。
三、MQTT的模式是发布/订阅
MQTT的模式是发布和订阅,也就是这个协议想要实现的主要功能。发布可以是客户端也可以是服务端,但最终都需要在服务端进行转发。订阅是客户端发起。其相关的定义如下:
订阅 Subscription
订阅包含一个主题过滤器(Topic Filter)和一个最大的服务质量(QoS)等级。订阅与单个会话(Session)关联。会话可以包含多于一个的订阅。会话的每个订阅都有一个不同的主题过滤器。
主题名 Topic Name
附加在应用消息上的一个标签,服务端已知且与订阅匹配。服务端发送应用消息的一个副本给每一个匹配的客户端订阅。
主题过滤器 Topic Filter
订阅中包含的一个表达式,用于表示相关的一个或多个主题。主题过滤器可以使用通配符。
会话 Session
客户端和服务端之间的状态交互。一些会话持续时长与网络连接一样,另一些可以在客户端和服务端的多个连续网络连接间扩展。
控制报文 MQTT Control Packet
通过网络连接发送的信息数据包。MQTT规范定义了十四种不同类型的控制报文,其中一个(PUBLISH报文)用于传输应用消息。
MQTT的消息传输机制的实现
一、什么是控制报文
控制报文本质是信息数据包,客户端和服务端从报文中的信息来进行通信,从而进行各种不同的操作。MQTT协议处于五层模型中的应用层,其底层基础是TCP/IP,使用socket编程实现报文的编辑、发送等。
二、控制报文的结构
控制报文的结构:
其中:
- 固定报头是所有报文都存在
- 可变报头和负载部分存在
- 可变报头包含的是各中不同类型消息中的个性化部分(具体先下一章节)
控制报文的表现形式:
控制报文的类型:
位置:第1个字节,二进制位7-4。
类型:表示为4位无符号值,MQTT定义了0-15的16种控制报文的类型:
名字 | 值 | 报文流动方向 | 描述 |
---|---|---|---|
Reserved | 0 | 禁止 | 保留 |
CONNECT | 1 | 客户端到服务端 | 客户端请求连接服务端 |
CONNACK | 2 | 服务端到客户端 | 连接报文确认 |
PUBLISH | 3 | 两个方向都允许 | 发布消息 |
PUBACK | 4 | 两个方向都允许 | QoS 1消息发布收到确认 |
PUBREC | 5 | 两个方向都允许 | 发布收到(保证交付第一步) |
PUBREL | 6 | 两个方向都允许 | 发布释放(保证交付第二步) |
PUBCOMP | 7 | 两个方向都允许 | QoS 2消息发布完成(保证交互第三步) |
SUBSCRIBE | 8 | 客户端到服务端 | 客户端订阅请求 |
SUBACK | 9 | 服务端到客户端 | 订阅请求报文确认 |
UNSUBSCRIBE | 10 | 客户端到服务端 | 客户端取消订阅请求 |
UNSUBACK | 11 | 服务端到客户端 | 取消订阅报文确认 |
PINGREQ | 12 | 客户端到服务端 | 心跳请求 |
PINGRESP | 13 | 服务端到客户端 | 心跳响应 |
DISCONNECT | 14 | 客户端到服务端 | 客户端断开连接 |
Reserved | 15 | 禁止 | 保留 |
控制报文的标志
位置:固定报头第1个字节的剩余的4位 [3-0]
类型:任何标记为“保留”的标志位,都是保留给以后使用的,必须设置为表格中列出的值。如果收到非法的标志,接收者必须关闭网络连接。有关错误处理的详细信息见 4.8节,固定值如下:
备注:再次提醒:任何标记为“保留(Reserved)”的标志位,都是保留给以后使用的,必须设置为表格中列出的值。如果收到非法的标志,接收者必须关闭网络连接。
总结:
- MQTT报文大致分为固定报头、可变报头、负载三部分;
- 固定报头用来表示MQTT报文的类型,可变报头来表示对应类型中的一些必要信息,负载部分用来表示具体的数据;
- 固定报头分为类型和标志两部分,类型通过0-15的值来表示报文类型,标志位为固定值,每种类型的标志位都是一样的;