0


简述MQTT协议

目录

  1. 简介
  2. MQTT协议组成
  3. MQTT三种QOS

1.简介

1.1 MQTT介绍

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输):

  • 是IBM推出的一种针对移动终端设备基于TCP/IP的发布/订阅协议;
  • 可以连接大量的远程传感器和控制设备,MQTT的特点是可以保持长连接,具有一定的实时性;
  • 云端向设备端发送消息,设备端可以在最短的时间内接受并且作出回响;
  • MQTT更适合需要实时控制的场合,尤其适合执行器;
  • 要保持长连接,那么就要时不时地发送心跳包,这就不会省电;
  • MQTT的长连接按需要建立在TCP的基础上,TCP协议的复杂性决定了对设备的要求相比UDP更高些;
  • MQTT属于互联网中的应用层

1663382574144.png

MQTT协议特性:

  • 使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合;
  • 有三种消息发布服务质量(QoS0、QoS1、QoS2): - ”最多一次“,消息发布完全依赖于底层的TCP/IP网络,会发生消息丢失或者重复,这一级别可用于对采集数据要求不严格的情况;- ”至少一次“,确保消息到达,但是消息可能会重复发生;- ”只有一次“,确保消息只到达一次,这一级别可用于要求严格如涉及计费系统的情况,消息重复或者丢失都是不允许的。
  • 小型传输,开销很小(固定长度的头部是2字节),协议交换最小化,以降低网络流量;
  • 使用 Last Will和Testrament特性通知有关各方客户端异常中断的机制;
  • 允许用户动态创建主题,零运维成本;
  • 把低带宽、高延迟、不稳定的网络因素考虑在内;
  • 假设数据不可知,不强求传输数据的类型与格式,保持灵活性;
  • 官网:http://mqtt.org/

MQTT协议的中心是MQTT服务器或者代理(broker)

1663384311971.png

  • 用户可以使用MQTT构建一个传感器网络,其中各种传感器都能够以其传感器独有的消息形式发布传感器值,订阅程序能够订阅不同的消息,以据此采取措施,MQTT代理将处理从发布程序到订阅程序的转发消息。
  • MQTT服务器除了收集转发数据,还可以进行数据处理和存储,例如,实时存储共享单车车辆运行位置、电池用量、状态信息等数据,以及对总体的车辆进行计算和统筹管理,甚至为一些聊天工具提供平台的服务。

MQTT主题模式:

  • MQTT是通过主题对消息进行分类的
  • 主题的本质就是一个UTF-8的字符串
  • 主题可以通过反斜杠标识多层级关系
  • 主题不需要创建,直接使用就可以了
  • 主题还可以通过通配符进行过滤- +可以过滤一个层级- *只能够出现在主题最后表示过滤任意级别的层级举个例子:- building-b/floor-5:代表B楼5层的设备- +/floor-5:表示任意一个楼层的5层的设备- building-b/*:代表B楼所有的设备
  • MQTT中有3个角色- 发布者 Publisher- 订阅者 Subscriber- 代理 Broker
  • MQTT这种结构替代了传统的客户端/服务器模型,可以实现以下解耦:- 空间解耦,发布者和订阅者不需要知道对方- 时间解耦,发布者和订阅者不需要同时运行(离线消息)- 同步解耦,发布和接收都是异步通讯,无需停止任何处理

2.MQTT协议组成

2.1 MQTT报文格式

MQTT协议通过交换预定义的MQTT控制报文来通信。MQTT主要是有以下三部分组成的:

  • 固定控制报头 Fixed Header- 剩余数据长度 Pakcet Length(判断可变长度报头、有效数据载荷接下来有多少数据)
  • 可变长度报头 Variable Header(服务于有效数据载荷)
  • 有效数据载荷 Payload(有效数据载荷会根据可变长度报头而发生改变)****Fixed header固定报头,所有控制报文都包含Variable header可变报头,部分控制报文包含Payload有效载荷,部分控制报文包含

2.2 MQTT固定控制报头

固定报头格式:(每个byte可以理解为一个数组,然后数组中有许多的Bit每个Bit就可以比作一个索引,每个索引中只能存0,1)

1663378364886.png

2.2.1 控制报文的类型

  • CONNECT 客户端发送到服务端的连接请求
  • CONNACK 服务端发送到客户端的确认连接的信息
  • PUBLISH 发布消息(也就是发布端),客户端、服务端都可以发送,消息的服务质量为QoS0,也就是只发布消息但是不管发布之后的事情
  • PUBACK 消息发布出去,收到确认,也就是QoS1的消息服务质量
  • PUBREC 发布收到,服务器记录了这个消息
  • PUBREL 发布释放,发布方释放了这个消息
  • PUBCOMP QoS2发布完成(在三个QoS中,QoS2消息是最可靠的)
  • SUBSCRIBE 客户端订阅的请求
  • SUBACK 订阅请求报文的确认(收到请求后返回一个应答)
  • UNSUBSCRIBE 客户端取消订阅请求
  • UNSUBACK 客户端确认订阅取消
  • PINGEQ 心跳请求
  • PINGRESP 心跳响应
  • DISCONNECT 客户端断开连接
    名字值报文流动方向描述Reserved0禁止保留CONNECT1客户端到服务端客户端请求连接服务端CONNACK2服务端到客户端连接报文确认PUBLISH3两个方向都允许发布消息PUBACK4两个方向都允许QoS 1消息发布收到确认PUBREC5两个方向都允许发布收到(保证交付第一步)PUBREL6两个方向都允许发布释放(保证交付第二步)PUBCOMP7两个方向都允许QoS 2消息发布完成(保证交互第三步)SUBSCRIBE8客户端到服务端客户端订阅请求SUBACK9服务端到客户端订阅请求报文确认UNSUBSCRIBE10客户端到服务端客户端取消订阅请求UNSUBACK11服务端到客户端取消订阅报文确认PINGREQ12客户端到服务端心跳请求PINGRESP13服务端到客户端心跳响应DISCONNECT14客户端到服务端客户端断开连接Reserved15禁止保留

    2.2.3 控制报文的标志位

这个不要看蒙了,这个其实就是一个简单的约束关系,对应着上方的类型给予他的一些控制报文的约束,比如下方的:

  • Bit 3:为DUP字段,如果为1,则表明这个数据包是一条重复的消息,否则该数据包就是第一次发布的消息;
  • Bit 2:为QoS字段,如果为1,则表示QoS2:只有一次;
  • Bit 1:为QoS字段,如果为1,则表示QoS1:最少要有一次;
  • 如果Bit 2、Bit 1都为0的情况下,则为QoS0如果同时将Bit2、Bit1设置成1,那么客户端或者服务器就会认为你这个是个非法的消息,会自动关闭当前的连接。
    控制报文固定报头标志Bit 3Bit 2Bit 1****Bit 0CONNECTReserved0000CONNACKReserved0000PUBLISHUsed in MQTT 3.1.1DUP1QoS2QoS2RETAIN3PUBACKReserved0000PUBRECReserved0000PUBRELReserved0010PUBCOMPReserved0000SUBSCRIBEReserved0010SUBACKReserved0000UNSUBSCRIBEReserved0010UNSUBACKReserved0000PINGREQReserved0000PINGRESPReserved0000DISCONNECTReserved0000

    2.3 Remaining Length(剩余长度)

位置:从第2个字节开始

剩余长度(Remaining Length)表示当前报文剩余部分的字节数,包括可变报头和负载的数据。剩余长度不包括用于编码剩余长度字段本身的字节数。

剩余长度字段使用一个变长度编码方案,对小于128的值它使用单字节编码。更大的值按下面的方式处理。低7位有效用于编码数据,最高有效位用于指示是否有更多的字节。因此每个字节可以编码128个数值和一个延续位(continuation bit)。剩余长度字段最大4字节。(最多可以发送256MB的数据)

2.4 Variable header(可变长度报头)

某些MQTT控制报文包含一个可变报头部分。它在固定报头和负载之间。可变报头的内容根据报文类型的不同而不同。可变报头的报文标识符(Packet Identifier)字段存在于多个类型的报文里。

可变报头分为:

  • 根据报文的类型的不同,会有不同的报文识别
  • 协议名称(Protocol Name)
  • 协议级别(Protocol Level)
  • 连接时间(Connect Flags)
  • 保活时间(Keep Alive)
  • 连接标识(Packet Identifier)

2.4.1 报文标识符

1663109442208.png

很多控制报文的可变报头部分包含了一个两字节的报文标识符字段。其中PUBLSH(Qos>0时),PUBACK、PUBREC、PUBREL、PUBCOMP、SUBSCRIBE这些报文类型才有报文标识符字段。

报文标识符相当于自定义的Topic的ID,用ID号去代替具体的Topic,而不是字段,使得区分发来的Topic的同时又可以节省流量,可自定义,建议自己预先拟定一个服务ID表。

订阅返回,返回Topic订阅成功信息,返回的不是具体Topic,返回的就是报文标识符。

2.5 Payload(有效载荷)

有些报文类型是包含Payload的,Payload意思是消息载体的意思;

如PUBLISH的Payload就是指消息内容(应用程序发布的消息内容)。而CONNECT的Payload则包含ClientIdentifier,Will Topic,Will Message,Username,Password等信息。

包含payload的报文类型如下:
控制报文有效载荷CONNECT需要CONNACK不需要PUBLISH可选PUBACK不需要PUBREC不需要PUBREL不需要PUBCOMP不需要SUBSCRIBE需要SUBACK需要UNSUBSCRIBE需要UNSUBACK不需要PINGREQ不需要PINGRESP不需要DISCONNECT不需要

2.5.1 连接标志

连接标志位字节包含一些用于指定MQTT链接行为的参数。它还指出了有效载荷中的字段是否存在。

,

服务端必须验证CONNECT控制报文的保留标志位(第0位)是否为0,如果不为0必须断开客户端连接。

整个MQTT协议

1663110369751.png

2.6 MQTT的服务端与客户端

  • 服务端: - 一个程序或者设备,作为发送消息的客户端和请求订阅的客户端之间的中介- 接受来自客户端的网络连接- 接受客户端发布的应用消息- 处理客户端的订阅和取消订阅请求- 转发应用消息给符合条件的已订阅客户端
  • 客户端: - 使用MQTT的程序或者设备,客户端总是通过网络连接到服务端- 发布应用消息给其他相关的客户端- 取消订阅以移除接受应用消息的请求- 从服务端断开连接

3.MQTT协议中三种QOS的区别

3.1 QOS0

客户端直接通过PUBLISH发消息给服务器,让服务器进行消息的发布,但是服务器在不在,服务器能不能够接受得到消息,客户端都是未知的,所以导致的是,其他的客户端最多只能接收到一次你的消息,存在一定的隐患。

1663381537415.png

3.2 QOS1

客户端通过PUBLISH发消息给服务器,让服务器进行消息的发布,在此同时,服务器会回信给客户端一个应答,如果我没有接收到这个应答的话,我就会再发送一次,直到客户端接收到来自服务器的应答才不会再次进行发送。

1663381580660.png

3.3 QOS2

仅有一次,首先客户端将消息发送给服务器,让服务器进行发布消息,然后服务器会回复客户端说”我已经将你的数据记录下来了“,客户端接收到之后,他还会回复服务器一个”那我就把这个消息释放了“,服务器收到客户端的消息之后,回复一个服务器消息发布完成的消息给客户端,这才结束了QOS2的发布消息。

1663381605639.png


本文转载自: https://blog.csdn.net/JAVA_EE_J/article/details/126902969
版权归原作者 Netty. 所有, 如有侵权,请联系我们删除。

“简述MQTT协议”的评论:

还没有评论