MQTT协议


前言

MQTT (Message Queue Telemetry Transport)是一种基于发布/订阅publish/subscribe)模式的轻量级通讯协议,通过订阅相应的主题来获取消息,是物联网(Internet of Thing)中的一个标准传输协议。
该协议将消息的发布者(publisher)与订阅者(subscriber)进行分离,因此可以在不可靠的网络环境中,为远程连接的设备提供可靠的消息服务,使用方式与传统的 MQ 有点类似。
在这里插入图片描述

TCP 协议位于传输层,MQTT 协议位于应用层,MQTT 协议构建于 TCP/IP 协议上,理论上,只要支持 TCP/IP 协议栈的地方,都可以使用 MQTT 协议。

协议优势

MQTT 协议在物联网(IOT)中非常流行,主要有几点:

  • HTTP 协议它是一种同步协议,客户端请求后需要等待服务器的响应。而在物联网(IOT)环境中,设备会很受制于环境的影响,比如带宽低、网络延迟高、网络通信不稳定等,显然异步消息协议更为适合 IOT 应用程序。
  • HTTP 是单向的,如果要获取消息客户端必须发起连接,而在物联网(IOT)应用程序中,设备或传感器往往都是客户端,这意味着它们无法被动地接收来自网络的命令。
  • 通常需要将一条命令或者消息,发送到网络上的所有设备上。HTTP 要实现这样的功能不但很困难,而且成本极高。

协议结构

MQTT是一种轻量级的协议,它只专注于发消息, 所以此协议的结构也比较简单。

MQTT数据包

MQTT协议中,一个MQTT数据包由:固定头(Fixed header)、 可变头(Variable header)、 消息体(payload)三部分构成。
在这里插入图片描述

  • 固定头(Fixed header),所有数据包中都有固定头,包含数据包类型及数据包的分组标识。
  • 可变头(Variable header),部分数据包类型中有可变头。
  • 消息体(Payload),存在于部分数据包类,是客户端收到的具体消息内容。

    固定头

固定头 存在于所有 MQTT 数据包中,使用两个字节,共16位,结构如下:

Bit 7 6 5 4 3 2 1 0
byte 1 MQTT数据包类型 不同类型MQTT数据包的具体标识
byte 2… 剩余长度

4-7位表示消息类型,使用 4 位二进制表示,可代表如下的16种消息类型,不过 015位置属于保留待用,所以共14种消息事件类型。

名称 流方向 描述
Reserved 0 不可用 保留位
CONNECT 1 客户端到服务器 客户端请求连接到服务器
CONNACK 2 服务器到客户端 连接确认
PUBLISH 3 双向 发布消息
PUBACK 4 双向 发布确认
PUBREC 5 双向 发布收到(保证第1部分到达)
PUBREL 6 双赂 发布释放(保证第2部分到达)
PUBCOMP 7 双向 发布完成(保证第3部分到达)
SUBSCRIBE 8 客户端到服务器 客户端请求订阅
SUBACK 9 服务器到客户端 订阅确认
UNSUBSCRIBE 10 客户端到服务器 请求取消订阅
UNSUBACK 11 服务器到客户端 取消订阅确认
PINGREQ 12 客户端到服务器 PING请求
PINGRESP 13 服务器到客户端 PING应答
DISCONNECT 14 客户端到服务器 中断连接
Reserved 15 不可用 保留位

DUP Flag(重试标识)

  • DUP Flag:保证消息可靠传输,消息是否已送达的标识。默认为0,只占用一个字节,表示第一次发送,当值为 1 时,表示当前消息先前已经被传送过。

QoS Level(消息质量等级)

  • QoS Level:消息的质量等级

RETAIN(持久化)

  • 值为 1 :表示发送的消息需要一直持久保存,而且不受服务器重启影响,不但要发送给当前的订阅者,且以后新加入的客户端订阅了此 Topic,订阅者也会马上得到推送。注意:新加入的订阅者,只会取出最新的一个RETAIN flag = 1的消息推送。
  • 值为 0 :仅为当前订阅者推送此消息。

Remaining Length(剩余长度)

  • 在当前消息中剩余的 byte 数,包含可变头部和消息体payload

可变头

固定头部仅定义了消息类型和一些标志位,一些消息的元数据需要放入可变头部中。可变头部内容字节长度 + 消息体payload = 剩余长度。

可变头部居于固定头部和payload中间,包含了协议名称,版本号,连接标志,用户授权,心跳时间等内容。

可变头存在于这些类型的消息:

  • PUBLISH (QoS > 0)

  • PUBACK

  • PUBREC

  • PUBREL

  • PUBCOMP

  • SUBSCRIBE

  • SUBACK

  • UNSUBSCRIBE

  • UNSUBACK

    消息体

    消息体 payload 只存在于 CONNECT、PUBLISH、SUBSCRIBE、SUBACK、UNSUBSCRIBE 这几种类型的消息:

  • CONNECT:包含客户端的ClientId、订阅的TopicMessage以及用户名和密码。

  • PUBLISH:向对应主题发送消息。

  • SUBSCRIBE:要订阅的主题以及QoS

  • SUBACK:服务器对于SUBSCRIBE所申请的主题及 QoS 进行确认和回复。

  • UNSUBSCRIBE:取消要订阅的主题。

    消息质量(QoS)

    消息的发送质量,发布者(publisher)和订阅者(subscriber)都可以指定 qos 等级,有三个等级:

  • QoS 0

  • QoS 1

  • QoS 2

    QoS 0

    At most once(至多一次)只发送一次消息,不保证消息是否成功送达,没有确认机制,消息可能会丢失或重复。

具体流程
在这里插入图片描述

QoS 1

At least once(至少一次),相对于 QoS 0 而言 Qos 1 增加了 ack 确认机制,发送者(publisher)推送消息到MQTT代理(broker)时,两者自身都会先持久化消息,只有当publisher 或者 Broker分别收到 PUBACK确认时,才会删除自身持久化的消息,否则就会重发。

虽然可以通过确认来保证一定收到客户端 或 服务器的 message,可却不能保证只收到一次 message,当客户端publisher没收到Brokerpuback或者 Broker没有收到subscriberpuback,那么就会一直重发。

具体流程

  • publisher store msg -> publish ->broker (发送 message)
  • broker -> puback -> publisher delete msg (确认回执)

在这里插入图片描述

QoS 2

Exactly once(只有一次),相对于QoS 1,QoS 2升级实现了仅接受一次messagepublisherbroker 同样对消息进行持久化,其中 publisher 缓存了message和 对应的 msgId,而 broker 缓存了 msgId,可以保证消息不重复,由于又增加了一个confirm 机制,整个流程变得复杂很多。

具体流程:

  • publisher store msg -> publish ->broker -> broker store (发送消息)
  • msgId(传递 message) broker -> puberc (确认传递成功)
  • publisher -> pubrel ->broker delete msgId (通知broker删除msgId
  • broker -> pubcomp -> publisher delete msg (通知publisher删除msg
    在这里插入图片描述

最后遗嘱(LWT)

LWT 全称为 Last Will and Testament,遗嘱是一个由客户端预先定义好的主题和对应消息,附加在CONNECT的数据包中,包括遗愿主题、遗愿 QoS、遗愿消息等。

MQTT代理 Broker 检测到有客户端client非正常断开连接时,再由服务器主动发布此消息,然后相关的订阅者会收到消息。

遗嘱的相关参数:

  • Will Flag:是否使用 LWT,1 开启
  • Will Topic:遗愿主题名,不可使用通配符
  • Will Qos:发布遗愿消息时使用的 QoS
  • Will Retain:遗愿消息的 Retain 标识
  • Will Message:遗愿消息内容

客户端非正常断开连接的场景

  • Broker 检测到底层的 I/O 异常;
  • 客户端 未能在心跳 Keep Alive 的间隔内和 Broker 进行消息交互;
  • 客户端 在关闭底层 TCP 连接前没有发送 DISCONNECT 数据包;
  • 客户端 发送错误格式的数据包到 Broker,导致关闭和客户端的连接等。

当客户端通过发布 DISCONNECT 数据包断开连接时,属于正常断开连接,并不会触发 LWT 的机制,与此同时Broker 还会丢弃掉当前客户端在连接时指定的相关 LWT 参数。

中间件

MQTT 是一种协议,支持MQTT协议的消息中间件产品有很多,比如

  • RabbitMQ
  • Apache ActiveMQ
  • HiveMQ
  • Apache Apollo
  • emqttd Xively

    应用场景

    MQTT 协议广泛应用于物联网、移动互联网、智能硬件、车联网、电力能源等领域。

Author: stream
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source stream !
  TOC