发布与订阅流程

  • ClientA 连接到 Broker;
  • ClientB 连接到 Broker,并订阅主题 Topic1;
  • ClientA 发送给 Broker 一条消息,主题为 Topic1;
  • Broker 收到 ClientA 的消息,发现 ClientB 订阅了 Topic1,然后将消息转发到 ClientB;
  • ClientB 从 Broker 接收到该消息。

消息离线接收

接收离线的消息需要 Client 使用持久化会话,且发布时消息的 QoS 不小于 1。

Publisher 和 Subscriber

Publisher 和 Subscriber 是相对于 Topic 来说的身份,如果一个 Client 向某个 Topic 发布消息,那么它就是 Publisher;如果一个 Client 订阅了某个 Topic,那么它就是 Subscriber。

Sender 和 Receiver

Sender 和 Receiver 是相对于消息传输方向的身份,例子:

  • 当 ClientA 发布消息时,它发送给 Broker 一条消息,那么 ClientA 是 Sender,Broker 是 Receiver;
  • 当 Broker 转发消息给 ClientB 时,Broker 是 Sender,ClientB 是 Receiver。

PUBLISH

PUBLISH 数据包是用于在 Sender 和 Receiver 之间传输消息数据的,也就是说,当 Publisher 要向某个 Topic 发布一条消息的时候,Publisher 会向 Broker 发送一个 PUBLISH 数据包;当 Broker 要将一条消息转发给订阅了某条主题的 Subscriber 时,Broker 也会向 Subscriber 发送一条 PUBLISH 数据包。

固定头

  • 消息重复标识(DUP flag):1bit,0 或者 1,当 DUP flag = 1 的时候,代表该消息是一条重发消息,因 Receiver 没有确认收到之前的消息而重新发送的。这个标识只在 QoS 大于 0 的消息中使用。
  • QoS:2bit,0、1 或者 2,代表 PUBLISH 消息的 QoS level。
  • Retain 标识(Retain flag):1bit,0 或者 1,在从 Client 发送到 Broker 的 PUBLISH 消息中被设为 1 的时候,Broker 应该保存该条消息,当之后有任何新的 Subscriber 订阅 PUBLISH 消息中指定的主题时,都会先收到该条消息,这种消息也叫 Retained 消息;在从 Broker 发送到 Client 的 PUBLISH 消息中被设为 1 的时候,代表该条消息是一条 Retained 消息。

可变头

  • 数据包标识( Packet Identifier):2bit,用来标识一个唯一数据包,数据包标识只需要保证在从 Sender 到 Receiver 的一次消息交互(比如发送、应答为一次交互)中保持唯一。只在 QoS 不小于 1 的消息中使用,因为只有 QoS 不小于 1 的消息有应答流程。
  • 主题名称(Topic Name):主题名称是一个 UTF-8 编码的字符串,用来命名该消息发布到哪一个主题,Topic Name 可以是长度大于等于 1 任何一个字符串(可包含空格),但是在实际项目中,我们最好还是遵循以下一些最优方法。
  • 主题名称应该包含层级,不同的层级用 / 划分,比如,2 楼 201 房间的温度感应器可以用这个主题:“home/2ndfloor/201/temperature”。
  • 主题名称开头不要使用 /,例如:“/home/2ndfloor/201/temperature”。
  • 不要在主题中使用空格。
  • 只使用 ASCII 字符。
  • 主题名称在可读的前提下尽量短。
  • 主题是大小写敏感的,“Home” 和 “home” 是两个不同的主题。
  • 可以将设备的唯一标识加到主题中,比如:“warehouse/shelf/shelf1_ID/status”。
  • 主题尽量精确,不要使用泛用的主题,例如在 201 房间有三个传感器,温度、亮度和湿度,那么你应该使用三个主题名称:“home/2ndfloor/201/temperature”、“home/2ndfloor/201/brightness”和“home/2ndfloor/201/humidity”,而不是让三个传感器都使用“home/2ndfloor/201”。
  • 以 $ 开头的主题属于 Broker 预留的系统主题,通常用于发布 Broker 的内部统计信息,比如 $SYS/broker/clients/connected,应用程序不要使用 $ 开头的主题收发数据。

消息体

PUBLISH 消息的消息体中包含的是该消息要发送的具体数据,数据可以是任何格式的,二进制数据、文本、JSON 。

订阅

MQTT新增订阅 Python mqtt订阅topic_字符串

  • Client 向 Broker 发送一个 SUBSCRIBE 数据包,其中包含了 Client 想要订阅的主题以及其他一些参数;
  • Broker 收到 SUBSCRIBE 数据包后,向 Client 发送一个 SUBACK 数据包作为应答。

SUBSCRIBE

可变头

  • 数据包标识(Packet Identifier):两个字节,用来唯一标识一个数据包,数据包标识只需要保证在从 Sender 到 Receiver 的一次消息交互中保持唯一。

消息体

  • 订阅列表(List of Subscriptions):SUBSCRIBE 的消息体中包含 Client 想要订阅的主题列表,列表中的每一项由订阅主题名和对应的 QoS 组成。

SUBACK

可变头

  • 数据包标识(Packet Identifier):两个字节,用来唯一标识一个数据包,数据包标识只需要保证在从 Sender 到 Receiver 的一次消息交互中保持唯一。

消息体

  • 返回码:

返回码

含义

0

订阅成功, 最大可用QoS为0

1

订阅成功,最大可用QoS为1

2

订阅成功, 最大可用QoS为2

128

订阅失败