Azure Web PubSub 可靠 JSON WebSocket 子协议
使用 JSON WebSocket 子协议 json.reliable.webpubsub.azure.v1
,可以通过服务以高度可靠的方式在客户端之间直接交换发布/订阅消息,而无需往返访问上游服务器。
本文档介绍子协议 json.reliable.webpubsub.azure.v1
。
备注
可靠协议仍处于预览阶段。 将来应会进行一些更改。
当 WebSocket 客户端连接由于间歇性网络问题而断开时,消息可能会丢失。 在发布/订阅系统中,发布服务器与订阅服务器是分离的,因此可能无法检测到订阅服务器连接断开或消息丢失。
若要克服间歇性网络问题并保持可靠的消息传送,可以使用 Azure WebPubSub json.reliable.webpubsub.azure.v1
子协议创建可靠 PubSub WebSocket 客户端。
可靠 PubSub WebSocket 客户端能够:
例如,可以使用以下 JavaScript 代码创建可靠 PubSub WebSocket 客户端:
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'json.reliable.webpubsub.azure.v1');
请参阅如何创建可靠客户端,以实现发布服务器与订阅服务器客户端的重新连接和消息可靠性。
当客户端使用此子协议时,传出和传入的数据帧都必须包含 JSON 有效负载。
PubSub WebSocket 客户端只有在获得授权后才能发布到其他客户端。 分配给客户端的 roles
决定了授予给客户端的权限:
角色 | 权限 |
---|---|
未指定 | 客户端可以发送事件请求。 |
webpubsub.joinLeaveGroup |
客户端可以加入/退出任何组。 |
webpubsub.sendToGroup |
客户端可以向任何组发布消息。 |
webpubsub.joinLeaveGroup.<group> |
客户端可以加入/退出 <group> 组。 |
webpubsub.sendToGroup.<group> |
客户端可以向 <group> 组发布消息。 |
服务器可通过 REST API 或服务器 SDK 动态授予或撤销客户端权限。
格式:
{
"type": "joinGroup",
"group": "<group_name>",
"ackId" : 1
}
ackId
是每个请求的标识,应具有唯一性。 该服务发送 ack 响应消息以通知请求的进程结果。 有关详细信息,请参阅 AckId 和 Ack 响应
格式:
{
"type": "leaveGroup",
"group": "<group_name>",
"ackId" : 1
}
ackId
是每个请求的标识,应具有唯一性。 该服务发送 ack 响应消息以通知请求的进程结果。 有关详细信息,请参阅 AckId 和 Ack 响应
格式:
{
"type": "sendToGroup",
"group": "<group_name>",
"ackId" : 1,
"noEcho": true|false,
"dataType" : "json|text|binary",
"data": {}, // data can be string or valid json token depending on the dataType
}
ackId
是每个请求的标识,应具有唯一性。 该服务发送 ack 响应消息以通知请求的进程结果。 有关详细信息,请参阅 AckId 和 Ack 响应noEcho
是可选项。 如果设置为 true,则不会将此消息回显到相同的连接。 如果未设置,则默认值为 false。dataType
可设置为json
、text
或binary
:json
:data
可以是 JSON 支持的任何类型,并且将按原样发布;如果未指定dataType
,则默认为json
。text
:data
应为字符串格式,并且将发布字符串数据;binary
:data
应采用 base64 格式,并且将发布二进制数据;
{
"type": "sendToGroup",
"group": "<group_name>",
"dataType" : "text",
"data": "text data",
"ackId": 1
}
<group_name>
中的子协议客户端接收:
{
"type": "message",
"from": "group",
"group": "<group_name>",
"dataType" : "text",
"data" : "text data"
}
<group_name>
中的简单 WebSocket 客户端接收字符串text data
。
{
"type": "sendToGroup",
"group": "<group_name>",
"dataType" : "json",
"data": {
"hello": "world"
}
}
<group_name>
中的子协议客户端接收:
{
"type": "message",
"from": "group",
"group": "<group_name>",
"dataType" : "json",
"data" : {
"hello": "world"
}
}
<group_name>
中的简单 WebSocket 客户端接收序列化字符串{"hello": "world"}
。
{
"type": "sendToGroup",
"group": "<group_name>",
"dataType" : "binary",
"data": "<base64_binary>",
"ackId": 1
}
<group_name>
中的子协议客户端接收:
{
"type": "message",
"from": "group",
"group": "<group_name>",
"dataType" : "binary",
"data" : "<base64_binary>",
}
<group_name>
中的简单 WebSocket 客户端接收二进制帧中的二进制数据。
格式:
{
"type": "event",
"event": "<event_name>",
"ackId": 1,
"dataType" : "json|text|binary",
"data": {}, // data can be string or valid json token depending on the dataType
}
ackId
是每个请求的标识,应具有唯一性。 该服务发送 ack 响应消息以通知请求的进程结果。 有关详细信息,请参阅 AckId 和 Ack 响应
dataType
可以是 text
、binary
或 json
之一:
json
:数据可以是 json 支持的任何类型,将按原样发布;默认值为json
。text
:数据采用字符串格式,将发布字符串数据;binary
:数据采用 base64 格式,将发布二进制数据;
{
"type": "event",
"event": "<event_name>",
"ackId": 1,
"dataType" : "text",
"data": "text data",
}
上游事件处理程序接收如下所示的数据:
POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: text/plain
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.user.<event_name>
ce-source: /client/{connectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-userId: {userId}
ce-connectionId: {connectionId}
ce-hub: {hub_name}
ce-eventName: <event_name>
text data
当 dataType
为 text
时,CloudEvents HTTP 请求的 Content-Type
为 text/plain
。
{
"type": "event",
"event": "<event_name>",
"ackId": 1,
"dataType" : "json",
"data": {
"hello": "world"
},
}
上游事件处理程序接收如下所示的数据:
POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: application/json
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.user.<event_name>
ce-source: /client/{connectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-userId: {userId}
ce-connectionId: {connectionId}
ce-hub: {hub_name}
ce-eventName: <event_name>
{
"hello": "world"
}
当 dataType
为 json
时,CloudEvents HTTP 请求的 Content-Type
为 application/json
{
"type": "event",
"event": "<event_name>",
"ackId": 1,
"dataType" : "binary",
"data": "base64_binary",
}
上游事件处理程序接收如下所示的数据:
POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: application/octet-stream
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.user.<event_name>
ce-source: /client/{connectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-userId: {userId}
ce-connectionId: {connectionId}
ce-hub: {hub_name}
ce-eventName: <event_name>
binary
当 dataType
为 binary
时,CloudEvents HTTP 请求的 Content-Type
为 application/octet-stream
。 对于文本消息帧,WebSocket 帧可以是 text
格式,对于 binary
消息帧,可以是 UTF8 编码的二进制数据。
如果消息与所述格式不匹配,Web PubSub 服务将拒绝客户端。
格式:
{
"type": "ping",
}
客户端可以向服务发送 ping
消息,以使 Web PubSub 服务能够检测客户端的运行情况。
格式:
{
"type": "sequenceAck",
"sequenceId": "<sequenceId>",
}
可靠 PubSub WebSocket 客户端在收到来自服务的消息后必须立即发送序列确认消息。 有关详细信息,请参阅如何创建可靠客户端
sequenceId
是收到的消息中的递增 uint64 编号。
客户端接收的消息可以有以下几种类型:ack
、message
、system
和 pong
。 message
类型的消息具有 sequenceId
属性。 客户端在收到消息后必须立即向服务发送序列确认。
如果请求包含 ackId
,则服务将为此请求返回确认响应。 客户端实现应处理此确认机制(包括使用 async
await
操作等待确认响应),并提供一个超时处理程序,用于处理在特定时间段内未收到确认响应的情况。
格式:
{
"type": "ack",
"ackId": 1, // The ack id for the request to ack
"success": false, // true or false
"error": {
"name": "Forbidden|InternalServerError|Duplicate",
"message": "<error_detail>"
}
}
客户端实现应始终首先检查 success
是 true
还是 false
。 仅当 success
为 false
时,客户端才会从 error
读取。
客户端可以接收从其加入的组或者从服务器(以服务器管理角色运行,可将消息发送到特定的客户端或用户)发布的消息。
来自组的响应消息:
{ "sequenceId": 1, "type": "message", "from": "group", "group": "<group_name>", "dataType": "json|text|binary", "data" : {} // The data format is based on the dataType "fromUserId": "abc" }
来自服务器的响应消息:
{ "sequenceId": 1, "type": "message", "from": "server", "dataType": "json|text|binary", "data" : {} // The data format is based on the dataType }
简单 WebSocket 客户端接收包含数据的文本 WebSocket 帧:
Hello World
;PubSub WebSocket 客户端接收 JSON 格式的消息:
{ "sequenceId": 1, "type": "message", "from": "server", "dataType" : "text", "data": "Hello World", }
简单 WebSocket 客户端接收包含字符串式数据的文本 WebSocket 帧:
{ "Hello" : "World"}
;PubSub WebSocket 客户端接收 JSON 格式的消息:
{ "sequenceId": 1, "type": "message", "from": "server", "dataType" : "json", "data": { "Hello": "World" } }
如果 REST API 使用 application/json
内容类型发送字符串 Hello World
,则简单 WebSocket 客户端将接收括在 "
中的 JSON 字符串 "Hello World"
。
简单 WebSocket 客户端接收包含二进制数据的二进制 WebSocket 帧。
PubSub WebSocket 客户端接收 JSON 格式的消息:
{ "sequenceId": 1, "type": "message", "from": "server", "dataType" : "binary", "data": "<base64_binary>" }
Web PubSub 服务可以向客户端返回系统相关的响应。
Web PubSub 服务从客户端收到 ping
消息时会向客户端发送 pong
消息。
格式:
{
"type": "pong",
}
对客户端连接请求的响应:
{
"type": "system",
"event": "connected",
"userId": "user1",
"connectionId": "abcdefghijklmnop",
"reconnectionToken": "<token>"
}
connectionId
和 reconnectionToken
用于重新连接。 建立包含 uri 的连接请求来进行重新连接:
wss://<service-endpoint>/client/hubs/<hub>?awps_connection_id=<connectionId>&awps_reconnection_token=<reconnectionToken>
在连接恢复中查找更多详细信息
当服务器关闭连接或者当服务拒绝客户端连接时的响应:
{
"type": "system",
"event": "disconnected",
"message": "reason"
}
使用这些资源开始生成自己的应用程序: