Azure Web PubSub 支持的 JSON WebSocket 子协议
使用 JSON WebSocket 子协议 json.webpubsub.azure.v1
,可以通过服务在客户端之间交换发布/订阅消息,而无需往返访问上游服务器。 使用 json.webpubsub.azure.v1
子协议的 WebSocket 连接称为 PubSub WebSocket 客户端。
概述
简单 WebSocket 连接在发送消息时会触发 message
事件,并依赖于服务器端处理消息以及执行其他操作。
使用 json.webpubsub.azure.v1
子协议,可以创建具有以下功能的 PubSub WebSocket 客户端:
例如,可以使用以下 JavaScript 代码创建 PubSub WebSocket 客户端:
// PubSub WebSocket client
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'json.webpubsub.azure.v1');
本文档介绍子协议 json.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 格式,并且将发布二进制数据;
案例 1:发布文本数据:
{
"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
。
案例 2:发布 JSON 数据:
{
"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"}
。
案例 3:发布二进制数据:
{
"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 格式,将发布二进制数据;
案例 1:发送包含文本数据的事件:
{
"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
。
案例 2:发送包含 JSON 数据的事件:
{
"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
案例 3:发送包含二进制数据的事件:
{
"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 服务将拒绝客户端。
响应
客户端接收的消息类型可以是:
- 确认 - 对包含
ackId
的请求的响应。 - 消息 - 来自组或服务器的消息。
- 系统 - 来自 Web PubSub 服务的消息。
确认响应
如果客户端请求包含 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
时才读取错误。
消息响应
客户端可以接收从其加入的组或者从服务器(以服务器管理角色运行,可将消息发送到特定的客户端或用户)发布的消息。
当消息来自组时
{ "type": "message", "from": "group", "group": "<group_name>", "dataType": "json|text|binary", "data" : {} // The data format is based on the dataType "fromUserId": "abc" }
当消息来自服务器时,
{ "type": "message", "from": "server", "dataType": "json|text|binary", "data" : {} // The data format is based on the dataType }
案例 1:通过 REST API 使用 Content-Type
=text/plain
将数据 Hello World
发送到连接
简单 WebSocket 客户端接收包含数据的文本 WebSocket 帧:
Hello World
;PubSub WebSocket 客户端接收:
{ "type": "message", "from": "server", "dataType" : "text", "data": "Hello World", }
案例 2:通过 REST API 使用 Content-Type
=application/json
将数据 { "Hello" : "World"}
发送到连接
简单 WebSocket 客户端接收包含字符串式数据的文本 WebSocket 帧:
{ "Hello" : "World"}
。PubSub WebSocket 客户端接收:
{ "type": "message", "from": "server", "dataType" : "json", "data": { "Hello": "World" } }
如果 REST API 使用 application/json
内容类型发送字符串 Hello World
,则简单 WebSocket 客户端将接收一个 JSON 字符串,即括在双引号 ("
) 中的 "Hello World"
。
案例 3:通过 REST API 使用 Content-Type
=application/octet-stream
将二进制数据发送到连接
简单 WebSocket 客户端接收包含二进制数据的二进制 WebSocket 帧。
PubSub WebSocket 客户端接收:
{ "type": "message", "from": "server", "dataType" : "binary", "data": "<base64_binary>" }
系统响应
Web PubSub 服务将系统相关的消息发送到客户端。
连续
当客户端成功连接时发送到客户端的消息:
{
"type": "system",
"event": "connected",
"userId": "user1",
"connectionId": "abcdefghijklmnop",
}
已断开连接
当服务器关闭连接或者当服务拒绝客户端时发送到客户端的消息。
{
"type": "system",
"event": "disconnected",
"message": "reason"
}
后续步骤
使用这些资源开始生成自己的应用程序: