你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
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-Rate 和 WebHook-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 不存在它。 其格式可能会更改,因此不应对其进行分析。 |
事件
有两种类型的事件: 阻塞 事件,其中服务等待事件响应继续,取消 阻止 事件,其中服务不会等待此类事件的响应,然后再处理下一条消息。
阻止事件
取消阻止事件
注意
系统 connect 事件
ce-type:azure.webpubsub.sys.connectContent-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:它应始终为mqttnull。 如果为 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 数据包。
错误响应格式
4xx或5xx:错误。 内容类型应为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.connectedContent-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.disconnectedContent-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-TypeHTTP 请求的标头。
请求格式
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}"
}
]
}
后续步骤
使用这些资源开始生成自己的应用程序: