适用于 JavaScript 的 Web PubSub 客户端 SDK
注意
有关此处使用的术语的详细信息,请参阅主要概念一文。
客户端 SDK 旨在加快开发人员的工作流;更具体地说,即:
- 简化客户端连接的管理
- 简化在客户端之间发送消息
- 在意外删除客户端连接后自动重试
- 从连接断开恢复后,按数量和顺序可靠地传递消息
如图所示,客户端与 Web PubSub 资源建立 WebSocket 连接。
入门
先决条件
- LTS 版本的 Node.js
- Azure 订阅
- Web PubSub 资源
1. 安装 @azure/web-pubsub-client
包
npm install @azure/web-pubsub-client
2. 连接 Web PubSub 资源
客户端使用 Client Access URL
连接服务并对其进行身份验证,该过程遵循 wss://<service_name>.webpubsub.azure.com/client/hubs/<hub_name>?access_token=<token>
模式。 客户端可以通过几种方式获取 Client Access URL
。 对于本快速指南,可以从显示的 Azure 门户复制并粘贴 URL。 (对于生产,客户端通常会在应用程序服务器上生成 Client Access 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.
示例
处理 connected
、disconnected
和 stopped
事件
Azure Web PubSub 会触发 connected
、disconnected
和 stopped
等系统事件。 可以注册事件处理程序,以确定触发事件时程序应执行的操作。
- 当客户端成功连接到 Web PubSub 资源时,将触发
connected
事件。 此代码片段仅输出连接 ID
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 an event handler for the "stopped" event
client.on("stopped", () => {
console.log(`Client has stopped`);
});
使用应用程序服务器以编程方式生成 Client Access URL
在生产中,客户端通常从应用程序服务器提取 Client Access URL
。 服务器将 connection string
保存到 Web PubSub 资源,并借助服务器端库 @azure/web-pubsub
生成 Client Access URL
。
1. 应用程序服务器
代码片段是应用程序服务器显示 /negotiate
终结点并返回 Client Access 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。
客户端使用来自应用程序服务器或已加入组的消息
客户端可以添加回叫以使用来自应用程序服务器或组的消息。
// Registers a listener for the "server-message". The callback is 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 is 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}`);
});
注意
对于 group-message
事件,客户端只能从已加入的组接收消息。
句柄重新加入失败
当客户端断开连接且无法恢复时,将在 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});
}
JavaScript 捆绑包
若要在浏览器中使用此客户端库,需要使用捆绑包。 有关如何创建捆绑包的详细信息,请参阅我们的捆绑文档。
疑难解答
启用日志
使用此库时,可设置以下环境变量来获取调试日志。
export AZURE_LOG_LEVEL=verbose
有关如何启用日志的更详细说明,请查看 @azure/logger 包文档。
实时跟踪
使用来自 Azure 门户的实时跟踪工具来检查通过 Web PubSub 资源的实时消息流量。