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

MQTT 客户端生命周期事件

客户端生命周期事件允许应用响应客户端连接状态或客户端资源操作的相关事件。 该功能允许:

  • 监视客户端的连接状态。 例如,可以生成应用程序,用于分析客户端的连接以优化行为。
  • 对客户端断开连接作出响应,采取缓解措施。 例如,可以生成应用程序,用于启动自动缓解流,或者在每次客户端断开连接时创建支持票证。
  • 跟踪客户端附加到的命名空间。 例如,在启动故障转移后,确认客户端已连接到正确的命名空间。

事件类型

事件网格命名空间发布以下事件类型:

事件类型 说明
Microsoft.EventGrid.MQTTClientSessionConnected 当 MQTT 客户端的会话连接到事件网格时发布。
Microsoft.EventGrid.MQTTClientSessionDisconnected 当 MQTT 客户端的会话从事件网格断开连接时发布。
Microsoft.EventGrid.MQTTClientCreatedOrUpdated 在事件网格命名空间中创建或更新 MQTT 客户端时发布。
Microsoft.EventGrid.MQTTClientDeleted 从事件网格命名空间删除 MQTT 客户端时发布。

事件架构

客户端生命周期事件提供有关已连接或断开连接的客户端和会话的所有信息。 它还提供一个 disconnectionReason 用于诊断方案,因为你可以使用该信息来自动采取缓解措施。

此示例事件显示当 MQTT 客户端的会话连接到事件网格时引发的事件的架构:

[{
  "specversion": "1.0",
  "id": "5249c38a-a048-46dd-8f60-df34fcdab06c",
  "time": "2023-07-29T01:23:49.6454046Z",
  "type": "Microsoft.EventGrid.MQTTClientSessionConnected",
  "source": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myrg/providers/Microsoft.EventGrid/namespaces/myns",
  "subject": "clients/client1/sessions/session1",
  "data": {
    "namespaceName": "myns",
    "clientAuthenticationName": "client1",
    "clientSessionName": "session1",
    "sequenceNumber": 1
  }
}]

此示例事件显示当 MQTT 客户端的会话与事件网格断开连接时引发的事件的架构:

[{
  "specversion": "1.0",
  "id": "e30e5174-787d-4e19-8812-580148bfcf7b",
  "time": "2023-07-29T01:27:40.2446871Z",
  "type": "Microsoft.EventGrid.MQTTClientSessionDisconnected",
  "source": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myrg/providers/Microsoft.EventGrid/namespaces/myns",
  "subject": "clients/client1/sessions/session1",
  "data": {
    "namespaceName": "myns",
    "clientAuthenticationName": "client1",
    "clientSessionName": "session1",
    "sequenceNumber": 1,
    "disconnectionReason": "ClientInitiatedDisconnect"
  }
}]

此示例事件显示在事件网格命名空间中创建或更新 MQTT 客户端时引发的事件的架构:

[{
  "specversion": "1.0",
  "id": "383d1562-c95f-4095-936c-688e72c6b2bb",
  "time": "2023-07-29T01:14:35.8928724Z",
  "type": "Microsoft.EventGrid.MQTTClientCreatedOrUpdated",
  "source": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myrg/providers/Microsoft.EventGrid/namespaces/myns",
  "subject": "clients/client1",
  "data": {
    "createdOn": "2023-07-29T01:14:34.2048108Z",
    "updatedOn": "2023-07-29T01:14:34.2048108Z",
    "namespaceName": "myns",
    "clientName": "client1",
    "clientAuthenticationName": "client1",
    "state": "Enabled",
    "attributes": {
      "attribute1": "value1"
    }
  }
}]

此示例事件显示当从事件网格命名空间删除 MQTT 客户端时引发的事件的架构:

[{
  "specversion": "1.0",
  "id": "2a93aaf9-66c2-4f8e-9ba3-8d899c10bf17",
  "time": "2023-07-29T01:30:52.5620566Z",
  "type": "Microsoft.EventGrid.MQTTClientDeleted",
  "source": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myrg/providers/Microsoft.EventGrid/namespaces/myns",
  "subject": "clients/client1",
  "data": {
    "namespaceName": "myns",
    "clientName": "client1",
    "clientAuthenticationName": "client1"
  }
}]

断开连接原因:

以下列表详细描述了 disconnectionReason 的不同值及其说明:

断开连接原因 说明
ClientAuthenticationError 客户端因任何身份验证问题(例如,证书已过期、客户端已禁用或客户端配置已更改)而断开连接
ClientAuthorizationError 客户端因任何授权问题(例如,由于主题空间、权限绑定或客户端组的配置发生更改)而断开连接
ClientError 客户端发送了错误的请求,或使用了某个不支持的功能,导致服务终止了连接。
ClientInitiatedDisconnect 客户端通过 DISCONNECT 数据包(对于 MQTT)或关闭 帧(对于基于 WebSocket 的 MQTT)启动了正常断开连接。
ConnectionLost 客户端与服务器之间的连接断开。
IpForbidden IP 筛选器或专用链接配置阻止了客户端的 IP 地址。
QuotaExceeded 客户端超出了一个或多个限制,导致服务终止了连接。
ServerError 连接因意外的服务器错误而终止
ServerInitiatedDisconnect 服务器出于任何操作原因启动了正常断开连接
SessionOverflow 客户端的未确认 QoS1 消息队列达到其限制,导致服务器终止了连接
SessionTakenOver 客户端使用相同的身份验证名称重新连接,导致前一连接终止。

有关每个属性的详细说明,请参阅事件网格命名空间的事件架构

提示

处理连接状态的高波动率:如果收到客户端断开连接事件,请等待一段时间(例如 30 秒),验证客户端是否仍处于脱机状态,然后再采取缓解措施。 这种优化提高了处理快速变化状态的效率。

配置

Azure 门户配置

使用以下步骤发出客户端生命周期事件:

  1. 在命名空间中,转到“事件”选项卡。
  2. 选择“+事件订阅”。
    • 提供事件网格订阅的名称。
    • 选择你偏好的事件架构,你将通过该架构使用事件。
    • 在“事件类型”下筛选事件。
    • 填写终结点详细信息。
  3. 选择“创建”。

Azure CLI 配置

使用以下步骤发出客户端生命周期事件:

  1. 创建系统主题
az eventgrid system-topic create --resource-group <Resource Group > --name <System Topic Name> --location \<Region> --topic-type Microsoft.EventGrid.Namespaces --source /subscriptions//resourceGroups/<Resource Group >/providers/Microsoft.EventGrid/namespaces/<Namespace Name>
  1. 创建事件网格订阅
  az eventgrid system-topic event-subscription create --name <Specify Event Subscription Name> -g <Resource Group> --system-topic-name <System Topic Name> --endpoint <Endpoint>

行为:

  • 不会为客户端生命周期事件提供延迟保证。 客户端连接状态事件指示客户端会话连接的最后报告状态,而不是实时连接状态。
  • 可能会发布重复的客户端生命周期事件。
  • 客户端生命周期事件的时间戳指示服务检测到事件的时间,这可能与事件的实际时间不同。
  • 无法保证客户端生命周期事件的顺序,事件可能不按顺序到达。 但是,可以使用连接状态事件的序列号来确定事件的原始顺序。
  • 对于客户创建或更新的事件,以及客户端删除的事件:
    • 如果在短时间内对客户端资源进行了多次状态更改,则将会为客户端的最终状态发出一件事件。
    • 示例 1:假设先创建一个客户端,然后在 3 秒钟内更新两次,则事件网格只会发出一个 MQTTClientCreatedOrUpdated 事件,其中包含客户端元数据的最终值。
    • 示例 2:假设创建了一个客户端,然后在 5 秒钟内将其删除,则事件网格只会发出一个 MQTTClientDeleted 事件。

对连接状态事件进行排序:

MQTTClientSessionConnected 和 MQTTClientSessionDisconnected 事件的序列号可用于确定客户端会话连接的最后报告状态,因为该序列号随每个新事件递增。 MQTTClientSessionDisconnected 的序列号始终与同一连接的 MQTTClientSessionConnected 事件的序列号匹配。 例如,下面的事件和序列号列表是同一客户端按正确顺序排列的事件示例:

  • MQTTClientSessionConnected > "sequenceNumber": 1
  • MQTTClientSessionDisconnected > "sequenceNumber": 1
  • MQTTClientSessionConnected > "sequenceNumber": 2
  • MQTTClientSessionDisconnected > "sequenceNumber": 2

下面是对事件进行排序的示例逻辑:对于每个客户端:

  • 存储第一个事件中的序列号和连接状态。
  • 对于每个新的 MQTTClientSessionConnected 事件:
    • 如果新序列号大于上一个序列号,请更新序列号和连接状态以匹配新事件。
  • 对于每个新的 MQTTClientSessionDisconnected 事件:
    • 如果新序列号等于或大于前一个序列号,请更新序列号和连接状态以匹配新事件。

后续步骤