简述MQTT协议

发布于:2022-12-14 ⋅ 阅读:(402) ⋅ 点赞:(0)

目录

  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 客户端断开连接
名字 报文流动方向 描述
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 禁止 保留

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 3 Bit 2 Bit 1 Bit 0
CONNECT Reserved 0 0 0 0
CONNACK Reserved 0 0 0 0
PUBLISH Used in MQTT 3.1.1 DUP1 QoS2 QoS2 RETAIN3
PUBACK Reserved 0 0 0 0
PUBREC Reserved 0 0 0 0
PUBREL Reserved 0 0 1 0
PUBCOMP Reserved 0 0 0 0
SUBSCRIBE Reserved 0 0 1 0
SUBACK Reserved 0 0 0 0
UNSUBSCRIBE Reserved 0 0 1 0
UNSUBACK Reserved 0 0 0 0
PINGREQ Reserved 0 0 0 0
PINGRESP Reserved 0 0 0 0
DISCONNECT Reserved 0 0 0 0

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


网站公告

今日签到

点亮在社区的每一天
去签到