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

使用 HTTP 协议的 Azure Web PubSub MQTT 事件处理程序的 CloudEvents 扩展

Web PubSub 服务使用 CloudEvents HTTP 协议绑定将客户端事件传送到上游 Webhook。

从 Web PubSub 服务发送到服务器的数据始终采用 CloudEvents binary 格式。

Webhook 验证

Webhook 验证遵循 CloudEvents。 每个 Webhook 终结点都应接受标头中包含的 WebHook-Request-Origin: xxx.webpubsub.azure.com HTTP OPTIONS 请求,并通过包括 WebHook-Allowed-Origin 标头来回复请求。 例如:

WebHook-Allowed-Origin: *

或:

WebHook-Allowed-Origin: xxx.webpubsub.azure.com

目前不支持 WebHook-Request-RateWebHook-Request-Callback

Web PubSub CloudEvents 属性扩展

此扩展定义 Web PubSub 为其生成的每个事件使用的属性。

名称 Type 说明 示例
userId string 连接的经过身份验证的用户 ID。
hub string 连接所属的中心。
connectionId string MQTT 协议中的客户端 ID。
eventName string 不带前缀的事件的名称。
subprotocol string 始终为 mqtt
connectionState string 定义连接的状态。 你可以使用相同的响应头来重置状态值。 不允许使用多个 connectionState 头。 如果字符串值包含复杂字符,则对 base64 中的字符串值进行编码;例如,用于 base64(jsonString) 使用此属性传递复杂对象。
signature string 上游 Webhook 的签名,用于验证传入请求是否来自预期来源。 服务使用主访问密钥和辅助访问密钥作为 HMAC 密钥计算值: Hex_encoded(HMAC_SHA256(accessKey, connectionId)) 上游应在处理请求之前验证请求是否有效。
physicalConnectionId string 服务为每个物理连接生成的唯一 ID。 其格式可能会更改,因此不应对其进行分析。
sessionId string 服务为每个会话生成的唯一 ID。 事件中 connect 不存在它。 其格式可能会更改,因此不应对其进行分析。

事件

有两种类型的事件: 阻塞 事件,其中服务等待事件响应继续,取消 阻止 事件,其中服务不会等待此类事件的响应,然后再处理下一条消息。

阻止事件

取消阻止事件

注意

  • 有关此规范的 TypeSpec 版本,请参阅 TypeSpec。 你可能希望打开 TypeSpec Playground 中的文件,以便获得更好的阅读体验和生成的 Swagger UI。
  • 有关此规范的 Swagger 版本,请参阅 Swagger。 你可能想要在 Swagger 编辑器打开该文件,以便获得更好的阅读体验和生成的 Swagger UI。

系统 connect 事件

  • ce-type: azure.webpubsub.sys.connect
  • Content-Type: application/json

请求格式

每次服务从客户端接收 CONNECT 数据包时,都会向上游发送 connect 请求。

POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: application/json; charset=utf-8
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.sys.connect
ce-source: /hubs/{hub}/client/{clientId}/{physicalConnectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-connectionId: {clientId}
ce-hub: {hub}
ce-eventName: connect
ce-physicalConnectionId: {physicalConnectionId}

{
  "mqtt": {
    "protocolVersion": 4,
    "cleanStart": true,
    "username": null,
    "password": null,
    "userProperties": null
  },
  "claims": {
    "type1": ["value1"]
  },
  "query": {
    "queryKey1": ["queryValue1"]
  },
  "headers": {
    "Connection": ["Upgrade"]
  },
  "subprotocols": ["mqtt"],
  "clientCertificates": [
    {
      "thumbprint": "3ce9b08a37566915dec4d1662cd2102121a99868",
      "content": "{string content of PEM format certificate}"
    }
  ]
}
  • mqtt.protocolVersion{MQTT protocol version of the client} 整数;可能的值是 4 (MQTT 3.1.1)和 5 (MQTT 5.0)。

  • mqtt.username{Username field in the MQTT CONNECT packet} UTF-8 编码字符串。 mqtt.username 可用于 mqtt.password 客户端的上游 Webhook 身份验证。

  • mqtt.password{Password field in the MQTT CONNECT packet} Base64 编码的二进制数据。 与用于客户端身份验证的用户名结合使用。

  • mqtt.userProperties{User properties field in the MQTT CONNECT packet} 字符串键值对的列表。 这是其协议支持用户属性的客户端提供的附加诊断或其他信息。 目前,只有 MQTT 5.0 支持它。

成功响应格式

  • 标头 ce-connectionState:如果此标头存在,则连接的状态将更新为标头的值。 请注意,只有 阻止 事件才能更新连接状态。 下面的示例使用 base64 编码的 JSON 字符串来存储连接的复杂状态。

  • HTTP 状态代码:

    • 204:成功,无内容。
    • 200:成功;内容应采用 JSON 格式,允许以下属性:
HTTP/1.1 200 OK

{
  "groups": ["newGroup1"],
  "subProtocol": "mqtt",
  "userId": "userId1",
  "roles": ["webpubsub.sendToGroup", "webpubsub.joinLeaveGroup"],
  "mqtt": {
    "userProperties": [
      {
        "name": "name1",
        "value": "value1"
      }
    ]
  }
}
  • subprotocol:它应始终为 mqtt null。 如果为 null,则默认为 mqtt.

  • userId{authenticated user ID} 由于服务允许匿名连接,事件 connect 负责告知服务客户端连接的用户 ID。 服务会从响应有效负载 userId 中读取用户 ID(如果存在)。 此属性仅在为物理连接创建新会话时生效。 如果物理连接已连接到现有会话,则忽略此属性,并使用现有会话的用户 ID。

  • groups{groups to join} 此属性提供了将连接添加到一个或多个组的便捷方法。 在 MQTT 方面,它会向客户端分配一个或多个具有默认订阅选项的订阅,组名称是主题筛选器。 此属性仅在为物理连接创建新会话时生效。 如果物理连接已连接到现有会话,则忽略此属性。

  • roles{roles the client has} 此属性为上游 Webhook 提供授权客户端的方法。 有不同的角色可以为 PubSub WebSocket 客户端授予初始权限。 有关权限的详细信息,请参阅 客户端权限。 此属性仅在为物理连接创建新会话时生效。 如果物理连接已连接到现有会话,则忽略此属性。

  • mqtt.userProperties{user properties that will be sent to clients in the CONNACK packet} 字符串键值对的列表。 它们将转换为 CONNACK 中的用户属性,并发送到其协议支持用户属性的客户端。 目前,只有 MQTT 5.0 支持用户属性。 上游 Webhook 可以使用此属性进行其他诊断或其他信息。

服务从上游收到成功响应后,它会向客户端发送成功的 CONNACK 数据包。

错误响应格式

  • 4xx5xx:错误。 内容类型应为 application/json. 服务收到错误响应后,会相应地向客户端发送失败的 CONNACK 数据包。
HTTP/1.1 401 Unauthorized
{
  "mqtt": {
    "code": 138,  // The CONNACK return code / reason code
    "reason": "banned by server",  // The reason string
    "userProperties": [{ "name": "name1", "value": "value1" }]
  }
}
  • mqtt.code{return code (MQTT 3.1.1) or reason code (MQTT 5.0) that will be sent to clients in the CONNACK packet} 指示失败原因的整数。 它将作为返回代码(MQTT 3.1.1)或原因代码(MQTT 5.0)发送到 CONNACK 数据包中的客户端。 上游 Webhook 应根据客户端的协议版本选择 MQTT 协议定义的有效整数值。 如果上游 Webhook 设置无效值,客户端将在 CONNACK 数据包中收到“未指定错误”。

  • mqtt.reason{failure reason string} 专为诊断设计的人工可读故障原因字符串。 它将发送到协议支持 CONNACK 数据包中原因字符串的客户端。 目前,只有 MQTT 5.0 支持它。

  • mqtt.userProperties{user properties that will be sent to clients in the CONNACK packet} 字符串键值对的列表。 它们将转换为 CONNACK 数据包中的用户属性,并发送到其协议支持用户属性的客户端。 目前,只有 MQTT 5.0 支持用户属性。 上游 Webhook 可以使用此属性进行其他诊断或其他信息。

系统 connected 事件

服务使用此事件通知上游 创建新会话。 如果客户端连接到 现有 会话,则没有上游调用。 在 MQTT 方面,服务在向客户端发送会话演示标志 0 CONNACK 数据包时发送此事件。

  • ce-type: azure.webpubsub.sys.connected
  • Content-Type: application/json

请求正文为空 JSON。

请求格式

POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: application/json; charset=utf-8
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.sys.connected
ce-source: /hubs/{hub}/client/{clientId}/{physicalConnectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-connectionId: {clientId}
ce-hub: {hub}
ce-eventName: connected
ce-physicalConnectionId: {physicalConnectionId}
ce-sessionId: {sessionId}

{}

connect 事件相比,该 connected 事件包含一个新的标头 ce-sessionId。 它是服务为每个会话生成的唯一 ID。 对于其余事件类型,还包含会话 ID 标头。

响应格式

  • 2xx:成功响应。

事件是异步的 connected 。 当响应状态代码未成功时,服务会记录错误。

HTTP/1.1 200 OK

系统 disconnected 事件

服务使用此事件通知上游会话已过期或已结束。

  • ce-type: azure.webpubsub.sys.disconnected
  • Content-Type: application/json

请求格式

POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: application/json; charset=utf-8
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.sys.disconnected
ce-source: /hubs/{hub}/client/{clientId}/{physicalConnectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-connectionId: {clientId}
ce-hub: {hub}
ce-eventName: disconnected
ce-physicalConnectionId: {physicalConnectionId}
ce-sessionId: {sessionId}

{
  "reason":"",
  "mqtt":{
    "initiatedByClient": true,
    "disconnectPacket":{
      "code": 0,
      "userProperties": [{ "name": "name1", "value": "value1" }]
    }
  }
}
  • reason{nullable string of the disconnect reason} 描述客户端断开连接的原因的用户可读字符串。 如果是正常的断开连接,则为 null。 如果会话中的多个连接连接和断开连接,则此属性代表上次断开连接的原因。 原因由客户端或服务提供,具体取决于发起断开连接的人员。 对于 MQTT,原因可能来自 MQTT 5.0 客户端或服务断开连接数据包中的原因字符串。 MQTT 3.1.1 协议在 DISCONNECT 数据包中没有原因字符串,因此 MQTT 3.1.1 客户端的此属性可能为 null 或由服务提供。

  • mqtt.initiatedByClient:一个布尔标志,指示客户端是否通过发送 DISCONNECT 数据包来启动断开连接。 客户端 true 发送 DISCONNECT 数据包以结束连接时,否则为 false

  • mqtt.disconnectPacket{nullable object containing properties of the last delivered DISCONNECT packet} 当连接断开连接时,如果没有客户端或服务发送 DISCONNECT 数据包,则为 null,例如,由于 IO 错误或网络故障。 上游可用于 mqtt.initiatedByClient 确定发送 DISCONNECT 数据包的人员。

  • mqtt.disconnectPacket.code{integer reason code in the DISCONNECT packet} 对于 MQTT 3.1.1 客户端,由于 DISCONNECT 数据包中没有原因代码,此属性默认为 0。 对于 MQTT 5.0,它是从客户端或服务发送的 DISCONNECT 数据包中的原因代码。

  • mqtt.disconnectPacket.userProperties{user properties in the DISCONNECT packet} 字符串键值对的列表。 客户端可以使用此属性将其他诊断或其他信息发送到上游。 如果服务发送 DISCONNECT 数据包,则为 null。

响应格式

  • 2xx:成功响应。

事件是异步的 disconnected 。 当响应状态代码未成功时,服务会记录错误。

HTTP/1.1 200 OK

用户 {custom_event} 事件

该服务将 MQTT 客户端发布的特定消息转换为对上游 Webhook 的 HTTP 请求,并将来自上游的响应转换为消息并将其发送到客户端。

触发器条件

  • MQTT 客户端以格式 $webpubsub/server/events/{eventName}将消息发布到主题。 {eventName} 不能包含字符 /
  • MQTT 客户端有权发布到该主题。
  • 如果客户端的协议为 MQTT 5.0,并且 PUBLISH 数据包包含内容类型字段,则内容类型值应为有效的 MIME 类型,因为它将转换为 Content-Type HTTP 请求的标头。

请求格式

MQTT 请求数据包

下表显示了 MQTT 请求消息中字段的用法。

MQTT 请求字段 使用情况
主题 指示消息是向上游发出的请求,并指定事件名称。
有效负载 是 HTTP 请求的正文。
内容类型 是 HTTP 请求的内容类型标头。
相关数据 是响应消息中的关联数据字段,由发送方用来标识响应消息所针对的请求。
QoS 是请求和响应消息传递的保证级别。
用户属性 成为 HTTP 请求中前缀的 mqtt- HTTP 标头。 在客户端和上游 Webhook 之间提供其他信息。

以下代码块显示了 JSON 格式的示例 MQTT PUBLISH 数据包。

{
  "topic": "$webpubsub/server/events/{eventName}",
  "payload": "{mqtt-request-payload}",
  "content-type": "{request/MIME}",
  "correlation-data": "{correlation-data}",
  "QoS": "{qos}",
  "user-properties": [
    {
      "name": "{request-property-1}",
      "value": "{request-property-value1}"
    }
  ]
}

以下代码块显示从 MQTT PUBLISH 数据包转换的 HTTP 请求。

HTTP 请求
POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: {request/MIME}
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.user.{eventName}
ce-source: /hubs/{hub}/client/{clientId}/{physicalConnectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-connectionId: {clientId}
ce-hub: {hub}
ce-eventName: {eventName}
ce-physicalConnectionId: {physicalConnectionId}
ce-sessionId: {sessionId}
mqtt-{request-property-1}: {request-property-value1}

{mqtt-request-payload}

响应格式

下表显示了 HTTP 响应中不同字段的用法。

HTTP 响应字段 使用情况
内容类型 是响应 MQTT 消息的内容类型字段。
Body 是响应 MQTT 消息的有效负载。
带有前缀的标头 mqtt- 成为响应 MQTT 消息中的用户属性。 在客户端和上游 Webhook 之间提供其他信息。
状态代码 指示请求是否成功。 如果成功(2xx),则响应主题为,否则$webpubsub/server/events/{eventName}/failed$webpubsub/server/events/{eventName}/succeeded。 它还将成为响应 MQTT 消息中命名 azure-status-code 的用户属性。

以下代码块显示了一个示例 HTTP 响应。

HTTP 响应
HTTP/1.1 200 OK
Host: xxxxxx
Content-Type: {response/MIME}
Content-Length: nnnn
ce-connectionState: eyJrZXkiOiJhIn0=
mqtt-response-property-1: response-property-value1

{mqtt-response-payload}

MQTT 响应

以下代码块显示了从 HTTP 响应转换的示例 MQTT 响应消息。

{
  "topic": "$webpubsub/server/events/{eventName}/succeeded",
  "payload": "{mqtt-response-payload}",
  "content-type": "{response/MIME}",
  "correlation-data": "{correlation-data}",
  "QoS": "{qos}",
  "user-properties": [
    {
      "name": "{response-property-1}",
      "value": "{response-property-value1}"
    }
  ]
}

后续步骤

使用这些资源开始生成自己的应用程序: