目录
1. MQTT协议规范
MQTT是基于TCP/IP协议栈构建的异步通信消息协议,是一种轻量级的发布、订阅信息传输协议。可以在不可靠的网络环境中进行扩展,适用于设备硬件存储空间或网络带宽有限的场景。使用MQTT协议,消息发送者与接收者不受时间和空间的限制。物联网平台支持设备使用MQTT协议接入。
举个例子:
假如我关注(订阅)了“乙”,但是“乙”没有关注我,当“乙”发送文章到服务器,而服务器知道我关注了“乙”,那么服务器会将“乙”发布的文章推送到我,但是我发布的东西,由于“乙”没有关注我,那么“乙”将不会第一时间了解到,我的动态。
假如我关注(订阅)了“甲”,并且“甲”也关注(订阅)了我,当“甲”发送文章到服务器,而服务器知道我关注了“甲”,那么服务器会将“甲”发布的文章推送到我,同样的服务器知道“甲”关注了我,若是我发布文章,,那么“甲”也会接收到我的文章推送。
这样看上去,像是我和甲在相互通讯,这就可以理解为topic(主题)。
2. 名词解释
名词 | 描述 |
产品 | 设备的集合,通常指一组具有相同功能的设备。物联网平台为每个产品颁发全局唯一的ProductKey。每个产品下最多可以包含50万个设备。 |
设备 | 归属于某个产品下的具体设备。物联网平台为设备颁发产品内唯一的证书DeviceName。设备可以直接连接物联网平台,也可以作为子设备通过网关连接物联网平台。 |
Topic | Topic是UTF-8字符串,是发布(Pub)/订阅(Sub)消息的传输中介。可以向Topic发布或者订阅消息。 |
Topic类 | 同一产品下不同设备的Topic集合,用${productkey}和${deviceName}通配一个唯一的设备,一个Topic类对一个ProductKey下所有设备通用。 |
网络连接 Network Connection | MQTT使用的底层传输协议基础设施。 |
应用消息 Application Message | MQTT协议通过网络传输应用数据。应用消息通过MQTT传输时,它们有关联的服务质量(QoS)和主题(Topic)。 |
客户端 Client | 使用MQTT的程序或设备。客户端总是通过网络连接到服务端。它可以: 发布应用消息给其它相关的客户端。 订阅以请求接受相关的应用消息。 取消订阅以移除接受应用消息的请求。 从服务端断开连接 |
服务端 Server |
接受来自客户端的网络连接。 接受客户端发布的应用消息。 处理客户端的订阅和取消订阅请求。 转发应用消息给符合条件的已订阅客户端。 |
订阅 Subscription | 订阅包含一个主题过滤器(Topic Filter)和一个最大的服务质量(QoS)等级。订阅与单个会话(Session)关联。会话可以包含多于一个的订阅。会话的每个订阅都有一个不同的主题过滤器。 |
3. CONNECT控制报文详解
客户端到服务端的网络连接建立后,客户端发送给服务端的第一个报文必须是CONNECT报文。
在一个网络连接上,客户端只能发送一次CONNECT报文。服务端必须将客户端发送的第二个CONNECT报文当作协议违规处理并断开客户端的连接。
有效载荷包含一个或多个编码的字段。包括客户端的唯一标识符,Will主题,Will消息,用户名和密码。除了客户端标识之外,其它的字段都是可选的,基于标志位来决定可变报头中是否需要包含这些字段。
3.1 固定报头 Fixed header
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
byte 1 | MQTT报文类型 (1) | Reserved 保留位 | ||||||
0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | |
byte 2... | 剩余长度 |
剩余长度字段:剩余长度等于可变报头的长度(10字节)加上有效载荷的长度。
3.2 可变报头 Variable header
CONNECT报文的可变报头按下列次序包含四个字段:协议名(Protocol Name),协议级别(Protocol Level),连接标志(Connect Flags)和保持连接(Keep Alive)。
3.2.1 协议名 Protocol Name
协议名字节构成:
说明 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
协议名 | |||||||||
byte 1 | 长度 MSB (0) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
byte 2 | 长度 LSB (4) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
byte 3 | ‘M’ | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 |
byte 4 | ‘Q’ | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 |
byte 5 | ‘T’ | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 |
byte 6 | ‘T’ | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 |
协议名是表示协议名 MQTT 的UTF-8编码的字符串。MQTT规范的后续版本不会改变这个字符串的偏移和长度。
如果协议名不正确服务端可以断开客户端的连接,也可以按照某些其它规范继续处理CONNECT报文。对于后一种情况,按照本规范,服务端不能继续处理CONNECT报文。
3.2.2 协议级别 Protocol Level
Protocol Level byte协议级别字节构成:
说明 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
协议级别 | |||||||||
byte 7 | Level(4) | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
客户端用8位的无符号值表示协议的修订版本。协议级别字段的值是4(0x04)。如果发现不支持的协议级别,服务端必须给发送一个返回码为0x01(不支持的协议级别)的CONNACK报文响应CONNECT报文,然后断开客户端的连接。
3.2.3 连接标志 Connect Flags
连接标志字节包含一些用于指定MQTT连接行为的参数。它还指出有效载荷中的字段是否存在。
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
User Name Flag | Password Flag | Will Retain | Will QoS | Will Flag | Clean Session | Reserved | ||
byte 8 | × | × | × | × | × | × | × | 0 |
服务端必须验证CONNECT控制报文的保留标志位(第0位)是否为0,如果不为0必须断开客户端连接。
3.2.4 保持连接 Keep Alive
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
byte 9 | 保持连接 Keep Alive MSB | |||||||
byte 10 | 保持连接 Keep Alive LSB |
保持连接(Keep Alive)是一个以秒为单位的时间间隔,表示为一个16位的字,它是指在客户端传输完成一个控制报文的时刻到发送下一个报文的时刻,两者之间允许空闲的最大时间间隔。客户端负责保证控制报文发送的时间间隔不超过保持连接的值。如果没有任何其它的控制报文可以发送,客户端必须发送一个PINGREQ报文。
不管保持连接的值是多少,客户端任何时候都可以发送PINGREQ报文,并且使用PINGRESP报文判断网络和服务端的活动状态。
如果保持连接的值非零,并且服务端在一点五倍的保持连接时间内没有收到客户端的控制报文,它必须断开客户端的网络连接,认为网络连接已断开 [MQTT-3.1.2-24]。
客户端发送了PINGREQ报文之后,如果在合理的时间内仍没有收到PINGRESP报文,它应该关闭到服务端的网络连接。
保持连接的值为零表示关闭保持连接功能。这意味着,服务端不需要因为客户端不活跃而断开连接。注意:不管保持连接的值是多少,任何时候,只要服务端认为客户端是不活跃或无响应的,可以断开客户端的连接。
3.3 有效载荷 Payload
CONNECT报文的有效载荷(payload)包含一个或多个以长度为前缀的字段,可变报头中的标志决定是否包含这些字段。如果包含的话,必须按这个顺序出现:客户端标识符,遗嘱主题,遗嘱消息,用户名,密码。