【EMQX实践】MQTT发布/订阅

239 阅读4分钟

MQTT(Message Queuing Telemetry Transport)是一个轻量级的发布/订阅消息传输协议,它被设计为开放、简单、易于实现,并且能够在带宽有限或不稳定的网络环境中工作。MQTT广泛应用于物联网(IoT)场景,其中设备之间需要高效率地交换消息。

image.png

发布(Publish)

PUBLISH 报文是 MQTT 协议中用于发送消息的报文类型。当一个客户端(发布者)想要将消息发送给其他客户端(订阅者)时,它会发送一个 PUBLISH 报文。PUBLISH 报文包含以下部分: 固定头(Fixed Header) :

  • 消息类型: 3,表示 PUBLISH 报文。
  • 标志位: 包括 DUP(重发标志)、QoS(服务质量)、RETAIN(保留标志)。
  • 剩余长度: 表示可变头和负载的总长度。

可变头(Variable Header) :

  • 主题名称: 消息要发布的主题,是一个 UTF-8 编码的字符串。
  • 消息标识符: 对于 QoS 1 和 QoS 2,包含一个 16 位的消息标识符。

负载(Payload) :

  • 包含要发布的消息内容,可以是任何类型的数据。

订阅(Subscribe)

SUBSCRIBE 报文是 MQTT 协议中用于订阅主题的报文类型。当一个客户端(订阅者)想要接收来自特定主题的消息时,它会发送一个 SUBSCRIBE 报文。SUBSCRIBE 报文包含以下部分: 固定头:

  • 消息类型: 8,表示 SUBSCRIBE 报文。
  • 标志位: QoS 为 1,表示服务器需要确认订阅请求。

可变头:

  • 消息标识符: 一个 16 位的标识符,用于标识订阅请求。

负载:

  • 包含一系列主题名称和相应的 QoS 级别。订阅者可以请求订阅一个或多个主题,并为每个主题指定希望接收消息的 QoS 级别。

订阅确认(Suback)

当服务器接收到 SUBSCRIBE 报文后,它会发送一个 SUBACK 报文作为响应,确认订阅请求。SUBACK 报文包含: 固定头:

  • 消息类型: 9,表示 SUBACK 报文。
  • 标志位: 不使用 DUP、QoS 和 RETAIN 标志。

可变头:

  • 消息标识符: 与 SUBSCRIBE 报文中的标识符相同。

负载:

  • 包含一系列授予的 QoS 级别,对应于 SUBSCRIBE 报文中请求的主题/QoS 对。

消息分发

当发布者发送 PUBLISH 报文时,服务器会根据订阅者的订阅关系将消息分发给所有订阅了该主题的客户端。根据订阅者请求的 QoS 级别,可能会有不同的消息传递保证:

  • QoS 0: 至多一次传输,没有消息确认,消息可能会丢失,但不会产生重复。
  • QoS 1: 至少一次传输,通过 PUBACK 报文确认消息,可能会有重复,但不会丢失。
  • QoS 2: 精确一次传输,通过 PUBREC、PUBREL 和 PUBCOMP 报文确保消息只传递一次,既没有丢失也没有重复。

取消订阅报文:UNSUBSCRIBE

固定头(Fixed Header) :

  • 消息类型: 10,表示 UNSUBSCRIBE 报文。

  • 标志位:

    • DUP(重发标志): 通常设置为 0。
    • QoS(服务质量): 通常设置为 1,因为 UNSUBSCRIBE 报文需要服务器确认。
    • RETAIN(保留标志): 不使用,设置为 0。
    • 剩余长度: 表示可变头和负载的长度。

可变头(Variable Header) :

  • 消息标识符: 一个 16 位的标识符,用于唯一标识 UNSUBSCRIBE 报文。

负载(Payload) :

  • 包含一系列要取消订阅的主题名称。这些主题名称是 UTF-8 编码的字符串,并且按照主题名称的顺序紧密打包。

取消订阅确认报文:UNSUBACK

当服务器接收到 UNSUBSCRIBE 报文后,它会处理取消订阅请求,并发送一个 UNSUBACK 报文作为响应,确认取消订阅操作。 固定头:

  • 消息类型: 11,表示 UNSUBACK 报文。
  • 标志位: 不使用 DUP、QoS 和 RETAIN 标志。
  • 剩余长度: 表示可变头的长度,通常是 2 字节。

可变头:

  • 消息标识符: 与 UNSUBSCRIBE 报文中的消息标识符相同,用于匹配取消订阅请求。

负载:

  • 没有负载。UNSUBACK 报文仅确认服务器已收到并处理了 UNSUBSCRIBE 报文。

取消订阅流程

  • 客户端确定不再需要接收某些主题的消息,并决定取消订阅这些主题。
  • 客户端构建并发送 UNSUBSCRIBE 报文,包含要取消订阅的主题列表和相应的消息标识符。
  • 服务器接收到 UNSUBSCRIBE 报文后,处理取消订阅请求,停止向客户端发送指定主题的消息。
  • 服务器发送 UNSUBACK 报文给客户端,确认取消订阅操作。
  • 客户端接收到 UNSUBACK 报文后,知道它已成功取消订阅了指定的主题。

其它

关注公众号【 java程序猿技术】获取EMQX实践系列文章