你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
适用于 JavaScript 的 Web PubSub 客户端库
Azure Web PubSub 是一项云服务,可帮助开发人员使用发布-订阅模式大规模在 Web 应用程序中轻松构建实时功能。
任何需要在服务器和客户端之间或在遵循发布-订阅模式的客户端之间进行实时消息传送的方案都可以受益于使用 Web PubSub。 开发人员不再需要通过每隔一段时间发送重复的 HTTP 请求来轮询服务器,这是浪费且难以缩放的。
如下图所示,客户端与 Web PubSub 资源建立 WebSocket 连接。 此客户端库:
- 简化客户端连接的管理
- 简化在客户端之间发送消息
- 在意外删除客户端连接后自动重试
- 从连接断开恢复后,按数量和顺序可靠地传递消息
有关此处使用的术语的详细信息,请参阅 关键概念 部分。
此库托管在 NPM 上。
入门
目前支持的环境
先决条件
1. 安装 @azure/web-pubsub-client
包
npm install @azure/web-pubsub-client
2. 连接 Web PubSub 资源
客户端使用客户端访问 URL 以连接服务并对其进行身份验证,该过程遵循 wss://<service_name>.webpubsub.azure.com/client/hubs/<hub_name>?access_token=<token>
模式。 客户端可以通过几种方式获取客户端访问 URL。 对于本快速入门,可以从 Azure 门户复制并粘贴一个,如下所示。 (对于生产,客户端通常会在应用程序服务器上获取生成客户端访问 URL。 请参阅下面的详细信息 )
如上图所示,客户端有权向名为“group1”的特定组发送消息并加入该组。
// Imports the client libray
const { WebPubSubClient } = require("@azure/web-pubsub-client");
// Instantiates the client object
const client = new WebPubSubClient("<client-access-url>");
// Starts the client connection with your Web PubSub resource
await client.start();
// ...
// The client can join/leave groups, send/receive messages to and from those groups all in real-time
3. 加入组
请注意,客户端只能从已加入的组接收消息,你需要添加回调以在接收消息时指定逻辑。
// ...continues the code snippet from above
// Specifies the group to join
let groupName = "group1";
// Registers a listener for the event 'group-message' early before joining a group to not miss messages
client.on("group-message", (e) => {
console.log(`Received message: ${e.message.data}`);
});
// A client needs to join the group it wishes to receive messages from
await client.joinGroup(groupName);
4. 向组发送消息
// ...continues the code snippet from above
// Send a message to a joined group
await client.sendToGroup(groupName, "hello world", "text");
// In the Console tab of your developer tools found in your browser, you should see the message printed there.
示例
为已连接、已断开连接和已停止事件添加回调
- 当客户端成功连接到 Web PubSub 资源时,将触发
connected
事件。
client.on("connected", (e) => {
console.log(`Connection ${e.connectionId} is connected.`);
});
- 当客户端断开连接且无法恢复连接时,将触发
disconnected
事件。
client.on("disconnected", (e) => {
console.log(`Connection disconnected: ${e.message}`);
});
- 当
stopped
客户端断开连接 且 客户端停止尝试重新连接时,将触发 该事件。 这通常发生在调用client.stop()
、禁用autoReconnect
或达到尝试重新连接时的指定限制之后。 如果要重启客户端,可以在已停止事件中调用client.start()
。
// Registers a listener for the "stopped" event
client.on("stopped", () => {
console.log(`Client has stopped`);
});
使用协商服务器以编程方式生成客户端访问 URL
在生产环境中,客户端通常从应用程序服务器提取客户端访问 URL。 服务器将连接字符串保存到 Web PubSub 资源,并在服务器库 @azure/web-pubsub
的帮助下生成客户端访问 URL。
1. 应用程序服务器
下面的代码片段是应用程序服务器公开 /negotiate
路径并返回客户端访问 URL 的示例。
// This code snippet uses the popular Express framework
const express = require('express');
const app = express();
const port = 8080;
// Imports the server library, which is different from the client library
const { WebPubSubServiceClient } = require('@azure/web-pubsub');
const hubName = 'sample_chat';
const serviceClient = new WebPubSubServiceClient("<web-pubsub-connectionstring>", hubName);
// Note that the token allows the client to join and send messages to any groups. It is specified with the "roles" option.
app.get('/negotiate', async (req, res) => {
let token = await serviceClient.getClientAccessToken({roles: ["webpubsub.joinLeaveGroup", "webpubsub.sendToGroup"] });
res.json({
url: token.url
});
});
app.listen(port, () => console.log(`Application server listening at http://localhost:${port}/negotiate`));
2. 客户端
下面的代码片段是客户端的示例。
const { WebPubSubClient } = require("@azure/web-pubsub-client")
const client = new WebPubSubClient({
getClientAccessUrl: async () => {
let value = await (await fetch(`/negotiate`)).json();
return value.url;
}
});
await client.start();
若要查看此示例的完整代码,请参阅 samples-browser。
客户端使用来自应用程序服务器或已加入组的消息
客户端可以添加回调以使用来自应用程序服务器或组的消息。 请注意,对于 group-message
事件,客户端 只能 接收已加入的组消息。
// Registers a listener for the "server-message". The callback will be invoked when your application server sends message to the connectionID, to or broadcast to all connections.
client.on("server-message", (e) => {
console.log(`Received message ${e.message.data}`);
});
// Registers a listener for the "group-message". The callback will be invoked when the client receives a message from the groups it has joined.
client.on("group-message", (e) => {
console.log(`Received message from ${e.message.group}: ${e.message.data}`);
});
句柄重新加入失败
当客户端断开连接且无法恢复时,将在 Web PubSub 资源中清理所有组上下文。 这意味着客户端重新连接时,需要重新加入组。 默认情况下,客户端已启用 autoRejoinGroup
选项。
但是,应注意 autoRejoinGroup
的限制。
- 客户端只能重新加入最初由 客户端代码而不是 服务器端代码联接的组。
- “重新加入组”操作可能会由于各种原因而失败,例如客户端无权加入组。 在这种情况下,需要添加回叫来处理此问题。
// By default autoRejoinGroups=true. You can disable it by setting to false.
const client = new WebPubSubClient("<client-access-url>", { autoRejoinGroups: true });
// Registers a listener to handle "rejoin-group-failed" event
client.on("rejoin-group-failed", e => {
console.log(`Rejoin group ${e.group} failed: ${e.error}`);
})
操作和重试
默认情况下,操作(如 client.joinGroup()
、client.leaveGroup()
、client.sendToGroup()
、client.sendEvent()
)有三次重试机会。 可以通过messageRetryOptions
进行配置。 如果所有重试都失败,将引发错误。 可以通过传入与之前的重试相同的 ackId
来继续重试,以便 Web PubSub 服务可以删除重复操作。
try {
await client.joinGroup(groupName);
} catch (err) {
let id = null;
if (err instanceof SendMessageError) {
id = err.ackId;
}
await client.joinGroup(groupName, {ackId: id});
}
指定子协议
可以更改客户端要使用的子协议。 默认情况下,客户端使用 json.reliable.webpubsub.azure.v1
。 可以选择使用 json.reliable.webpubsub.azure.v1
或 json.webpubsub.azure.v1
。
// Change to use json.webpubsub.azure.v1
const client = new WebPubSubClient("<client-access-url>", { protocol: WebPubSubJsonProtocol() });
// Change to use json.reliable.webpubsub.azure.v1
const client = new WebPubSubClient("<client-access-url>", { protocol: WebPubSubJsonReliableProtocol() });
关键概念
连接
连接(也称为客户端或客户端连接)表示连接到 Web PubSub 的单个 WebSocket 连接。 成功连接后,Web PubSub 会向此连接分配唯一的连接 ID。 每个都 WebPubSubClient
创建自己的独占连接。
恢复
如果使用可靠协议的客户端断开连接,则新的 WebSocket 会尝试使用丢失的连接的连接 ID 建立连接。 如果成功连接新的 WebSocket 连接,则恢复该连接。 在客户端断开连接期间,服务会保留客户端的上下文以及客户端订阅的所有消息,当客户端恢复时,服务会将这些消息发送到客户端。 如果服务返回 WebSocket 错误代码 1008
或恢复尝试持续时间超过 30 秒,则恢复将失败。
重新连接
当客户端连接断开且无法恢复时,会发生重新连接。 重新连接将启动新连接,新连接具有新的连接 ID。 与恢复不同,服务将重新连接的客户端视为新的客户端连接。 客户端连接需要重新加入组。 默认情况下,客户端库在重新连接后重新加入组。
集线器
中心是客户端连接集的逻辑概念。 通常,将一个中心用于一个目的,例如聊天中心或通知中心。 创建客户端连接后,它会连接到某个中心,并且在其生存期内属于该中心。 不同的应用程序可以通过使用不同的中心名称共享一个 Web PubSub。
组
组是与中心的连接的子集。 可以随时向组添加客户端连接或者从组中删除客户端连接。 例如,当某个客户端加入聊天室,或某个客户端离开聊天室,此类聊天室可以看成是一个组。 一个客户端可以加入多个组,一个组可以包含多个客户端。
用户
与 Web PubSub 的连接可以属于一个用户。 用户可能具有多个连接,例如当单个用户跨多个设备或多个浏览器选项卡进行连接时。
客户端生存期
每个 Web PubSub 客户端都可以安全地缓存,并在应用程序的生存期内用作单一实例。 已注册的事件回调与客户端共享相同的生存期。 这意味着可以随时添加或删除回调,注册状态在重新连接或客户端停止后不会更改。
JavaScript 捆绑包
若要在浏览器中使用此客户端库,首先需要使用捆绑程序。 有关如何执行此操作的详细信息,请参阅捆绑 文档。
疑难解答
启用日志
使用此库时,可设置以下环境变量来获取调试日志。
export AZURE_LOG_LEVEL=verbose
有关如何启用日志的更详细说明,请查看 @azure/logger 包文档。
实时跟踪
使用 Web PubSub 门户中的 实时跟踪工具 查看实时流量。
其他资源
详细了解客户端权限,请参阅 权限
贡献
若要为此库做出贡献,请阅读贡献指南,详细了解如何生成和测试代码。