你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

Azure 事件网格的 MQTT 中转站功能支持的 MQTT 功能

MQTT 是一种发布-订阅消息传输协议,专为受限环境而设计。 其高效性、可伸缩性和可靠性使其成了 IoT 方案中的黄金通信标准。 MQTT 中转站支持通过 MQTT v3.1.1、基于 WebSocket 的 MQTT v3.1.1、MQTT v5 和基于 WebSocket 的 MQTT v5 发布和订阅消息的客户端。 MQTT 中转站还支持跨 MQTT 版本(MQTT 3.1.1 和 MQTT 5)通信。

MQTT v5 在 MQTT v3.1.1 的基础上引入了许多改进,提供更加无缝、透明和高效的通信。 其中新增了:

  • 更完善的 bug 报告。
  • 客户端可以通过用户属性和内容类型等功能以更透明的方式通信。
  • 客户端可以通过消息和会话过期等功能更好地控制通信。
  • 请求-响应模式等重要标准模式。

连接流:

MQTT 客户端必须通过 TLS 1.2 或 TLS 1.3 进行连接。 尝试跳过此步骤会导致连接失败。

连接到 MQTT 中转站时,请在通过 MQTT 通信期间使用以下端口:

  • 对于 MQTT v3.1.1 和 MQTT v5,请使用 TCP 端口 8883
  • 对于 WebSocket 的 MQTT v3.1.1 和基于 WebSocket 的 MQTTv5,请使用 TCP 端口 443。

CONNECT 数据包应包含以下属性:

  • ClientId 字段是必需的,它应该包含客户端的会话名称。 该会话名称需在整个命名空间中唯一。 如果每个客户端使用一个会话,则你可以使用客户端身份验证名称作为会话名称。 如果一个客户端使用多个会话,则它需要为其每个会话使用不同的 ClientId 值。
  • 如果在创建命名空间期间未在 alternativeAuthenticationNameSources 中选择值,则 Username 字段是必需的。 在这种情况下,需要在 Username 字段中提供客户端的身份验证名称。 该名称需要与提供的身份验证名称,以及在创建客户端资源期间指定的客户端证书字段中的值相匹配。

详细了解客户端身份验证

多会话支持

借助多会话支持,应用程序 MQTT 客户端可以同时使用多个活动会话连接到 MQTT 中转站,以获得可伸缩性和可靠性更高的实现。

命名空间配置

在使用此功能之前,需要将命名空间配置为每个客户端允许多个会话。 使用以下步骤在 Azure 门户中为每个客户端配置多个会话:

  • 在 Azure 门户中转到你的命名空间。
  • 在“配置”下,将“每个身份验证名称的客户端会话数量上限”的值更改为希望每个客户端可以进行的会话数量。
  • 选择“应用”。

注意

至于 Azure CLI 配置,请使用希望的值更新命名空间有效负载中的 MaxClientSessionsPerAuthenticationName 属性。

连接流:

每个会话的 CONNECT 数据包应包含以下属性:

  • 在 CONNECT 数据包中提供 Username 属性来表示客户端身份验证名称。
  • 在 CONNECT 数据包中提供 ClientID 属性来表示会话名称,例如,在每个 Username 的 ClientID 有一个或多个值的情况下。

例如,CONNECT 数据包中 Username 和 ClientIds 的以下组合使客户端“Mgmt-application”能够通过三个独立会话连接到 MQTT 中转站:

  • 第一个会话:
    • 用户名:Mgmt-application
    • ClientId:Mgmt-Session1
  • 第二个会话:
    • 用户名:Mgmt-application
    • ClientId:Mgmt-Session2
  • 第三个会话:
    • 用户名:Mgmt-application
    • ClientId:Mgmt-Session3

多会话示例图。

有关详细信息,请参阅如何为单个客户端建立多个会话

处理会话:

  • 如果某个客户端尝试通过使用不同的身份验证名称表示其会话名称来接管另一个客户端的活动会话,则其连接请求将被拒绝并出现未授权错误。 例如,如果客户端 B 尝试连接到当时已分配给客户端 A 的会话 123,则将拒绝客户端 B 的连接请求。 也就是说,如果同一客户端尝试使用相同的会话名称和相同的身份验证名称重新连接,则可以接管其现有会话。
  • 如果在未结束客户端资源会话的情况下删除该资源,则在会话过期之前,其他客户端将无法它的会话名称。 例如,如果客户端 B 创建了会话名称为 123 的会话,然后删除了客户端 B,则在会话 123 过期之前,客户端 A 将无法连接到该会话。
  • 每个客户端的会话数限制适用于任何时间点的联机和脱机会话。 例如,请考虑将每个身份验证名称的最大客户端会话数设置为 1 的命名空间。 如果客户端 A 连接到持久会话 123,然后断开连接,则客户端 A 将无法连接到新会话 456,因为它的会话 123 即使脱机也仍然处于活动状态。 因此,建议同一客户端始终使用相同的静态会话名称重新连接,而不是每次重新连接时生成新的会话名称。

MQTT 功能

Azure 事件网格的 MQTT 中转站功能支持以下 MQTT 功能:

服务质量 (QoS)

MQTT 中转站支持 QoS 0 和 1,这些功能定义了在客户端与 MQTT 中转站之间通过 PUBLISH 和 SUBSCRIBE 数据包传递消息的保证。 QoS 0 保证最多传递一次;使用 QoS 0 传递的消息不会由订阅服务器确认,也不会由发布服务器重新传输。 QoS 1 保证最少传递一次;消息由订阅服务器确认,如果未得到确认,则由发布服务器重新传输。 QoS 使客户端能够控制通信的效率和可靠性。

持久会话

MQTT 中转站支持 MQTT v3.1.1 的持久会话,使 MQTT 中转站在连接断开时保留有关客户端会话的信息,以确保通信的可靠性。 此信息包括客户端的订阅和丢失/未确认的 QoS 1 消息。 客户端可以通过将 CONNECT 数据包中的 cleanSession 标志设置为 false 来配置持久会话。

全新启动和会话过期

MQTT v5 引入了全新启动和会话过期功能,作为对 MQTT v3.1.1 在处理会话持久性方面的改进。 全新启动功能使客户端能够与 MQTT 中转站启动新会话,并丢弃以前的所有会话数据。 会话过期使客户端能够在将非活动会话视为已过期并自动将其删除时通知 MQTT 中转站。 在 CONNECT 数据包中,客户端可以将 Clean Start 标志设置为 true 和/或较短的会话过期间隔(出于安全原因,或者为了避免出现上一个会话期间可能发生的任何数据冲突)。 客户端还可以将 Clean Start 标志设置为 false 和/或较长的会话过期间隔,以确保持久会话的可靠性和效率。

最大会话过期间隔配置

可以为连接到事件网格命名空间的所有客户端配置允许的最大会话到期时间间隔。 对于 MQTT v3.1.1 客户端,配置的限制将应用为为所有持久会话的默认会话过期间隔。 对于 MQTT v5 客户端,配置的限制将应用为 CONNECT 数据包中“会话过期间隔”属性的最大值;超出该限制的任何值将会进行调整。 此命名空间属性的默认值为 1 小时,最多可延长至 8 小时。 使用以下步骤在 Azure 门户中配置最大会话过期间隔:

  • 在 Azure 门户中转到你的命名空间。
  • 在“配置”下,将“最大会话过期间隔(以小时为单位)”的值更改为所需的限制。
  • 选择“应用”。

最大会话过期间隔配置的屏幕截图。

会话溢出

在客户端再次与 MQTT 中转站连接以接收队列中的消息之前,MQTT 中转站将为每个未连接的活动 MQTT 会话维护一个消息队列。 如果客户端未连接以接收已排队的 QOS1 消息,会话队列将开始累积消息至达到 100 条消息或 1 MB 的限制为止。 队列在会话的生命周期内达到其限制后,会话将会终止。

Last Will and Testament (LWT) 消息

Last Will and Testament (LWT) 将通知你的 MQTT 客户端其他 MQTT 客户端突然断开连接。 可以使用 LWT 确保意外断开连接期间 MQTT 客户端之间的可预测且可靠的通信流,这对于实时通信、系统可靠性和协调操作至关重要的方案非常有用。 协作执行复杂任务的客户端可以通过调整其行为、重新分发任务或接管某些职责来相互响应 LWT 消息,以维持系统的性能和稳定性。 若要使用 LWT,客户端可以指定连接期间 CONNECT 数据包中的 will 消息、will 主题以及其余的 will 属性。 当客户端突然断开连接时,MQTT 代理会将 will 消息发布到订阅 will 主题的所有客户端。 为了减少不定时的断开连接带来的干扰,可以在客户端中将延迟间隔设置为大于零的值。 在这种情况下,如果客户端突然断开连接,但在遗嘱延迟间隔到期之前恢复连接,则系统不会发布遗嘱消息。

用户属性

MQTT 中转站支持 MQTT v5 PUBLISH 数据包中的用户属性,允许在消息标头中添加自定义键值对来提供有关消息的更多上下文。 用户属性的用例丰富多样。 可以使用此功能来包含消息的目的或来源,以便接收方可以在不分析有效负载的情况下处理消息,从而节省计算资源。 例如,在某个消息中,用户属性指明其目的是“警告”,该属性触发的处理逻辑可能与目的为“信息”的属性不同。

“请求-响应”模式

MQTTv5 在 MQTT PUBLISH 数据包标头中引入了字段,用于为请求-响应模式中的响应消息提供上下文。 这些字段包括一个响应主题和一个相关 ID,响应方无需事先进行配置即可在响应中使用它们。 响应信息使命令和控制方案中使用的标准请求-响应模式能够更有效地通信。

请求-响应模式示例图。

消息过期间隔:

在 MQTT v5 中,消息过期间隔允许消息具有可配置的生存期。 消息过期间隔定义为将消息发布到 MQTT 代理的时间与 MQTT 代理需要丢弃未传递的消息的时间之间的时间间隔。 如果消息仅在特定的时间内有效,例如时间敏感的命令、实时数据流式处理或安全警报,则此功能非常有用。 通过设置消息过期间隔,MQTT 中转站可以自动删除已过时的消息,确保只有相关信息可供订阅服务器使用。 如果消息的过期间隔设置为零,则表示该消息永不过期。

主题别名:

在 MQTT v5 中,客户端可以通过主题别名,使用较短的别名来代替已发布消息中的完整主题名称。 MQTT 中转站维护主题别名与实际主题名称之间的映射。 此功能可以节省网络带宽并减小消息标头的大小,特别是对于名称较长的主题。 如果同一主题在多个消息中重复发布(例如在传感器网络中),则此功能非常有用。 MQTT 中转站最多支持 10 个主题别名。 客户端可以使用 PUBLISH 数据包中的 Topic Alias 字段将完整主题名称替换为相应的别名。

主题别名示例图。

流量控制

在 MQTT v5 中,流控制是指用于管理客户端可处理的消息速率和大小的机制。 可以通过设置 CONNECT 数据包中的 Maximum Packet Size 和 Receive Maximum 参数来配置流控制。 客户端可以通过 Receive Maximum 参数将代理发送的消息数限制为客户端能够处理的消息数。 Maximum Packet Size 参数定义客户端可以接收的最大数据包大小。 MQTT 中转站的消息大小限制为 512 KiB。 此功能确保处理速度或存储功能受限的设备能够可靠稳定地通信。

否定确认和服务器发起的断开连接数据包

对于 MQTT v5,MQTT 中转站能够发送否定确认 (NACK) 和服务器发起的断开连接数据包,为客户端提供有关消息传递或连接失败的详细信息。 这些功能可帮助客户端诊断故障原因并采取适当的缓解措施。 MQTT 代理使用 MQTT v5 规范中定义的原因代码。

当前限制

MQTT 中转站将来会添加更多 MQTT v5 和 MQTT v3.1.1 功能,以便与 MQTT 规范更相符。 以下列表详细介绍了 MQTT 中转站和 MQTT 规范支持的功能之间的当前差异:

MQTTv5 当前限制

MQTT v5 目前在以下方面与 MQTT v5 规范不同:

  • 尚不支持共享订阅。
  • 尚不支持 Retain 标志。
  • 最大延迟间隔为 300。
  • 最大 QoS 为 1。
  • 最大数据包大小为 512 KiB
  • 不保证消息顺序。
  • 不支持订阅标识符。
  • 尚不支持分配的客户端标识符。
  • 主题别名最大数量为 10。 服务器目前不会为传出消息分配任何主题别名。 客户端可以在设置的范围内分配和使用主题别名。
  • 即使 CONNECT 请求包含请求响应信息属性,CONNACK 也不会返回响应信息属性。
  • 服务不使用 CONNECT、SUBSCRIBE、DISCONNECT、PUBACK、AUTH 数据包上的用户属性,因此它们不受支持。 如果其中任一请求包括用户属性,则请求将失败。
  • 如果服务器从客户端接收带有非成功响应代码的 PUBACK,则连接会终止。
  • Keep Alive 最大值为 1,160 秒。

MQTTv3.1.1 的当前限制

MQTT v5 目前在以下方面与 MQTT v3.1.1 规范不同:

  • 尚不支持 QoS2 和 Retain 标志。 包含 Retain 标志或 QoS2 的发布请求会失败并关闭连接。
  • 不保证消息顺序。
  • Keep Alive 最大值为 1,160 秒。

代码示例:

此存储库包含 C#、C 和 Python 代码示例,用于演示如何发送遥测数据、发送命令和广播警报。 通过示例创建的证书适合用于测试,但不适合用于生产环境。

后续步骤:

详细了解 MQTT:

详细了解 MQTT 中转站: