链接服务端网络
客户端到服务端的第一个报文必须是CONNECT,且只能发送一次,发送的第二个connect报文看成违规处理并断开链接。编码
有效载荷包含一个或者多个编码的字段。包括客户端的惟一标识符,Will主题,Will消息,用户名和密码。spa
除了标识外,其余字段都是可选的,基于标志位决定可变报头中是否须要包含这些字段。3d
固定报头server
报头长度:2 Bytesblog
一、报文类型:1 CONNECT字符串
二、标志位 0 0 0 0:it
三、剩余长度基础
等于可变报头的长度(10)加上有效载荷的长度。cli
可变报头
在固定CONNECT报文可变报头包含四个字段,协议名、协议级别、链接标志、保持链接:
一、协议名 (Protocol Name)。
若是协议名不正确,server端能够断开链接。
二、协议级别(Protocol Level)。
使用第7个字节:
客户端用8位的无符号值表示协议的版本。对于3.1.1,协议级别值是4(04)。
若是发现不支持的协议级别,server必须发送一个0x01的ACK报文响应CONNECT报文,而后断开链接。
三、链接标志(Connect Flags)。
bit 0 : server必须验证CONNECT的保留标志位(第0位)是否为0,若是不为0必须断开链接。
bit 1:指定了会话状态的处理方式。用于控制会话状态的生存时间。
= 0 :server必须基于当前会话的状态恢复与client的通讯。若是没有与这个client标识符关联的会话,server必须建立一个新会话。
在链接断开后,client和server必须保存会话信息。server必须将以后的QoS 1和QoS2级别的消息保存为会话状态的一部分,
若是这些消息匹配断开链接时client的任何订阅。server也能够保存知足相同条件的QoS 0级别的消息。
= 1:server和client必须丢弃以前的任何会话,并开始一个新的会话。
会话仅持续和网络链接一样长的时间。与这个会话关联的状态数据不能被任何以后的会话重用。
client的会话状态包括:
server会话状态包括:
bit 2:遗嘱标志 (Will Flag)
=1:若是链接请求被接受了,遗嘱消息必须被保存在server端而且与这个网络链接关联。以后网络链接关闭时,server必须发布这个遗嘱消息。
除非server收到DISCONNECT报文时删除了这个遗嘱消息。
遗嘱消息发布的条件:
以后的链接标志Will QoS 和Will Retain字段会被server用到,同是,有效载荷中必须包含Will Topic 和Will Message字段
一旦被发布或者server收到了client发送的DISCONNECT,遗嘱消息就必须从存储的会话状态中移除。
=0:以后的链接标志Will QoS 和Will Retain字段必须为0,而且有效载荷中不能包含Will Topic 和Will Message字段。
网络链接断开时,不能发送遗嘱消息。
server端应该迅速发布遗嘱消息。在关机或者故障的状况下,server能够推迟遗嘱消息的发布直到以后的重启。
若是发生了这种状况,在server故障和遗嘱消息被发布之间可能会有一个延迟。
bit 3-4:遗嘱QoS Will QoS
这两位用于指定发布遗嘱消息时使用的服务质量等级。
值由遗嘱标志位决定:
Will Flag = 0:它的值必须设置为0。
Will Flag = 1:它的值能够等于0,1,2。
bit 5:遗嘱保留 Will Retain
若是遗嘱消息被发布时须要保留,须要指定这一位的值。
若是Will Flag = 0: 它的值为 0 ,server必须将遗嘱消息看成非保留信息发布。
若是 Will Flag = 1: 它的值为 1 ,server必须将遗嘱消息看成保留信息发布。
bit 6:密码标志 Password Flag
=0:有效载荷中不能包含密码字段
=1:有效载荷中必须包含密码字段
若是用户名标志为0,它也必须为0
bit 7:用户名标志 User Name Flag
=0:有效载荷中不能包含用户名字段
=1:有效载荷中必须包含用户名字段
四、保持链接(Keep Alive)。
使用第九、10字节。
它是一个以秒为单位的时间间隔,表示为一个16位的字,它是指在client传输完一个控制报文的时刻到发送下一个报文的时刻。
client负责保证报文发送的时间间隔不超过保持链接的值。若是没有任何其余的报文发送,就必须发送一个PINGREQ报文。
无论保持链接的值是多少,client任什么时候候均可以发送PINGREQ报文,而且使用PINGRESP判断网络和server的活动状态。
= !0 :若是server在1.5倍的时间内没有收到client的报文,它必须断开链接。
client在发送了PINGREQ后,若是在合理的时间内没有收到PINGRESP,也应该关闭链接。
= 0 :表示关闭链接保持的功能。意味着,server不须要由于client不活跃而关闭链接。
无论保持值为多少,任什么时候候,只要server认为client是不活跃或无响应的,能够断开client链接。
可变报头示例:
有效载荷
CONNECT报文的有效载荷包含一个或多个以长度为前缀的字段,可变报头中的标志决定是否包含这些字段。
若是包含的话,必须按照这个顺序出现:client标识符,遗嘱主题,遗嘱消息,用户名,密码。
一、client标识符
server使用client标识符识别client。
链接到server的每一个client都有惟一的clientID。
client和server都必须使用clientID识别二者之间的MQTT会话相关的状态。
clientID必须存在,必须是CONNECT报文有效载荷的第一个字段。
clientID必须是UTF-8编码字符串。
server必须容许1到23个字节长的UTF-8编码的clientID,clientID只能包含这些字符:
“0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ”
server能够容许编码后超过23个字节的clientID,也能够容许包含不是上面列表字符的clientID。
若是server拒绝了这个clientID,它必须发送返回码0x02(表示ID不合格)的CONNACK。
于PUBLISH来讲就是消息内容了。
须要有效载荷的控制报文:CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE。 PUBLISH是可选。
二、遗嘱主题
若是遗嘱标志为1,有效载荷的下一个字段是遗嘱主题,它必须是UTF-8编码字符串。
三、遗嘱消息
若是遗嘱标志为1,有效载荷的下一个字段是遗嘱消息。遗嘱消息定义了将被发布到遗嘱主题的应用消息。
这个字段由一个两字节长度+有效载荷组成。长度给出了跟在后面的数据的字节数,不包含长度字段自己的两个字节。
遗嘱消息被发布到遗嘱主题时,它的有效载荷只包含这个字段的数据部分,不包含开头的两个长度字节。
四、用户名
若是用户名标志为1:有效载荷的下一个字段就是它,server用于身份验证和受权。
五、密码
密码字段包含一个两字节的长度字段,长度表示二进制数据的字节数(不包含长度字段自己占用的两个字节),后面跟着0-65535字节的二进制数据。
密码字节:
响应
server检查CONNECT报文的内容是否是知足任何进一步的限制,能够执行身份验证和受权检查。
若是验证成功,执行下列步骤:
容许client在发送CONNECT报文后当即发送其它的控制报文;client不须要等待server的CONNACK报文。
若是server拒绝了CONNECT,它不能继续处理在CONNECT报文以后发送的任何数据。
-----------------------------------------------------------------------------------------------------------------------
CONNACK-确认链接请求
server发送给client的第一个报文必须是CONNACK。
若是client在合理的时间内没有收到CONNACK,client应该关闭链接。(合理的时间取决于应用的类型和通讯基础设施)
固定报头
报头格式描述以下:
剩余长度字段表示可变报头的长度。对于CONNACK,这个值是2.
可变报头
可变报头描述以下:
byte 1 :链接确认标志,1-7位是保留,且必须设置为0。第0位是当前会话标志。使server和client在是否有已保存的会话状态上保持一致。
若是server收到清理会话标志为1的链接,除了将CONNACK报文中的返回码设置为0以外,还必须设置当前会话标志设为0。
若是server收到清理会话标志为0的链接,它的值取决于server是否保存了clientID对应client的会话状态。若是保存则为1,不然为0。
若是server发送了一个包含非零返回码的CONNACK报文,它必须将当前会话标志设置为0。
byte 2 :链接返回码,使用一个字节的无符号值。
若是server收到一个合法的CONNECT报文,可是出于某些缘由没法处理它,server应该尝试发送一个包含非零返回码,再关闭链接。
链接返回码:
若是认为上表中的全部链接返回码都不太适合,那么server必须关闭链接,不须要发送CONNACK报文。
有效载荷
CONNACK没有载荷