MQTT协议设计简介

MQTT协议设计简介

0cool

简介

MQTT全称为MQ Telemetry Transport,它是一种轻量级的基于订阅分发的消息协议,适用于慢网络和嵌入式设备通信。MQTT支持一对多的消息分发,提供QoS以保证消息的准确到达,使用TCP作为传输层协议,当前比较流行的版本是3.1。

如今业界已经有很多公司在使用MQTT来构建应用,比如国外的facebook,国内也有很多,比如提供第三方push的云巴等。

MQTT协议设计的比较简洁,没有什么冗余的东西,相信这也是很多公司愿意尝试使用它的原因,至少学习起来并不费太大功夫。

消息设计

MQTT协议的消息最多由两部分构成:固定头部可变头部负载

(1)固定头部MSB;由两个字节构成,第一个字节包含4位消息类型、1位DUP标识、2位Qos等级和1位保留位,第二个字节保存了消息的剩余长度。

MQTT消息类型只有4位来标识,意味着最多不会超过16种,实际上MQTT协议定义了14种消息类型,还有两种是保留类型。简单列举下:

CONNECT(1,连接请求)
CONNACK(2,连接ACK)
PUBLISH(3,发布消息)
PUBACK(4,发布ACK)
PUBREC(5,发布已接受)
PUBREL(6,发布释放)
PUBCOMP(7,发布完成)
SUBSCRIBE(8,订阅)
SUBACK(9,订阅ACK)
UNSUBSCRIBE(10,取消订阅)
UNSUBACK(11,取消订阅ACK)
PINGREQ(12,PING请求)
PINGRESP(13,PING响应)
DISCONNECT(14,断开连接)

DUP标识表示客户端或服务端尝试重发消息(包括PUBLISH、PUBREL、SUBSCRIBE和UNSUBSCRIBE四类消息),如果置为1表示该消息需要进行确认,此时QoS值大于0,且可变头部里需要包含消息ID(16位无符号整型、由客户端维护)。

虽然MQTT协议采用了TCP协议作为传输层来保证报文的可靠性,但为了确保消息能正常被应用接收到,MQTT协议提供了QoS机制,分三种等级:0表示最多发送一次、1表示至少发送一次、2表示确定只有一次。目前QoS只适用于PUBLISH类型。
保留标识也只适用于PUBLISH类型,如果置为1表示服务端需要保存消息直到被订阅者接收。
头部第二个字节保存了消息的剩余长度,包括可变头部和负载的总长度。8位剩余长度由两部分构成:前7位记录消息长度,第8位表示是否还有延续,用来处理长度超过127字节的消息。

MQTT协议严格定义了剩余长度最长为256MB,最长可以用4个字节来表示剩余长度。

具体表示范围:用1个字节表示长度从0(0x00)到127(0x7F),2个字节表示长度从128(0x80,0x01)到16383(0xFF,0x7F),3个字节表示长度从16384(0x80,0x80,0x01)到2097151(0xFF,0xFF,0x7F),4个字节表示长度从2097152(0x80,0x80,0x80,0x01)到268435455(0xFF,0xFF,0xFF,0x7F)。

下面是长度X编码的算法:

    do
      digit = X MOD 128
      X = X DIV 128
      // if there are more digits to encode, set the top bit of this digit
      if ( X > 0 )
        digit = digit OR 0x80
      endif
      'output' digit
    while ( X> 0 )

解码算法:

    multiplier = 1
    value = 0
    do
      digit = 'next digit from stream'
      value += (digit AND 127) * multiplier
      multiplier *= 128
    while ((digit AND 128) != 0)

协议规定剩余长度包含在固定头部中,不计入可变头部,意味着固定长度最少为2个字节,最大为5个字节。

 

(2)可变头部;可变头部包含有多种信息,规定以以下顺序来保存:
协议名称:协议名称会出现在CONNECT类型消息中,保存的是一串UTF-8编码的字符串"MQIsdp"。


协议版本号:同样也出现在CONNECT类型消息中,记录客户端当前所使用的MQTT协议版本号,如最新的是3(0x03)。


连接标识:包括清空会话、Will、Will QoS和Will retain标识,均会出现在CONNECT类型消息中。简单说明下几个标识的含义:
a、清空会话置为1表示服务端会清空客户端以前的所有信息,置为0表示服务器会保存客户端的状态信息,即使客户端断开连接,服务器会保存QoS为1或2的消息,当客户端重连(清空会话置为0)时服务器会将订阅的消息发送给客户端。
b、Will消息:当服务端与客户端通信时发生I/O错误,或客户端没有在keep alive时间内与服务端通信,此时服务器会向客户端发送Will消息。而当客户端向服务端发送DISCONNECT消息时,服务器不会向客户端发送此类消息。
一旦连接标示中设置了Will标识,Will QoS和Will Retain字段也必须设置。Will QoS用来定义Will消息的QoS等级,Will Retain定义服务器是否保留消息,Will消息包含在CONNECT消息的负载中。

用户名和密码标识,客户端与服务端进行连接时可以提供用户名和密码来验证。当设置了用户名标示时,需要提供用户名信息;若设置了密码标示,则需要指定密码。


Keep Alive定时器出现在CONNECT消息可变头部中,它定义了从客户端收到消息的最大时间间隔,使得服务端不需要等待TCP/IP超时,根据时间间隔来检测客户端是否已断开连接。客户端有义务在该时间段内向服务器发送消息,若没有待发的数据,客户端需要发送PINGREQ消息,等待服务器的PINGRESP消息。
Keep Alive定时器由2个字节构成,存储了最大时间间隔数值。


连接返回代码出现在CONNACK消息可变头部中,由1个字节构成,客户端根据返回代码可以知道是否与服务器连接成功,如果失败也可以知道失败当具体原因。
0x00表示连接成功、0x01表示不支持客户端协议版本号、0x02表示拒绝标示符、0x03表示服务器不可用、0x04表示用户名密码有误、0x05表示未授权。
topic名称,表示数据所发往的信道标识。
 

(3)负载;CONNECT、SUBSCRIBE和SUBACK消息均包含负载。

CONNECT负载包括客户端唯一ID、也可能包括Will topic、Will消息、用户名和密码。
SUBSCRIBE包含所订阅的topic名称列表,以及QoS等级。
SUBACK包含允许的QoS等级列表。

 

Reference

MQTT v3.1 specification

MQTT org

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值