适用于 Azure Functions 的 Azure Web PubSub 触发器和绑定
本参考介绍了如何在 Azure Functions 中处理 Web PubSub 事件。
Web PubSub 是一项 Azure 托管服务,可帮助开发人员轻松构建具有实时功能和发布-订阅模式的 Web 应用程序。
操作 | 类型 |
---|---|
当消息来自服务时运行函数 | 触发器绑定 |
将请求绑定到 Http 触发器下的目标对象,用于协商和上游请求 | 输入绑定 |
调用服务执行操作 | 输出绑定 |
源代码 | 包 | API 参考文档 | 产品文档 | 示例
添加到 Functions 应用
使用触发器和绑定需要引用相应的包。 NuGet 包用于 .NET 类库,而扩展捆绑包用于其他所有应用程序类型。
语言 | 添加方式... | 备注 |
---|---|---|
C# | 安装 NuGet 包,预发行版本 | |
C# Script、JavaScript、Python、PowerShell | 显式安装扩展、使用扩展捆绑 | 建议将 Azure Tools 扩展用于 Visual Studio Code。 |
C# 脚本(Azure 门户中仅限联机) | 添加绑定 | 若要更新现有绑定扩展而不必重新发布函数应用,请参阅更新扩展。 |
关键概念
(1)-(2) 与 HttpTrigger 的 WebPubSubConnection
输入绑定以生成客户端连接。
(3)-(4) 与 HttpTrigger 的 WebPubSubTrigger
触发器绑定或 WebPubSubContext
输入绑定以处理服务请求。
(5)-(6) WebPubSub
输出绑定以请求服务器执行某些工作。
触发器绑定
使用函数触发器处理来自 Azure Web PubSub 服务的请求。
WebPubSubTrigger
在需要处理来自服务端的请求时使用。 触发器终结点模式如下所示,该模式应在 Web PubSub 服务端(门户:“设置”->“事件处理程序”->“URL 模板”)进行设置。 在终结点模式中,出于安全原因使用 Azure Function 应用时,查询部分 code=<API_KEY>
是必需的。 密钥可在“Azure 门户”中找到。 找到函数应用资源,将函数应用部署到 Azure 后,导航到“函数”>“应用密钥”>“系统密钥”>“webpubsub_extension”。 但是,在使用本地函数时不需要此密钥。
<Function_App_Url>/runtime/webhooks/webpubsub?code=<API_KEY>
示例
[FunctionName("WebPubSubTrigger")]
public static void Run(
[WebPubSubTrigger("<hub>", WebPubSubEventType.User, "message")] UserEventRequest request, ILogger log)
{
log.LogInformation($"Request from: {request.ConnectionContext.UserId}");
log.LogInformation($"Request message data: {request.Data}");
log.LogInformation($"Request message dataType: {request.DataType}");
}
在同步方案(例如系统 Connect
和用户事件)中,WebPubSubTrigger
绑定还支持返回值,服务器可以检查和拒绝客户端请求,或直接将消息发送到调用方。 Connect
事件遵守 ConnectEventResponse
和 EventErrorResponse
,用户事件遵守 UserEventResponse
和 EventErrorResponse
,与当前情况不匹配的其他类型则将被忽略。 如果返回 EventErrorResponse
,服务将断开客户端连接。
[FunctionName("WebPubSubTriggerReturnValueFunction")]
public static UserEventResponse Run(
[WebPubSubTrigger("hub", WebPubSubEventType.User, "message")] UserEventRequest request)
{
return request.CreateResponse(BinaryData.FromString("ack"), WebPubSubDataType.Text);
}
特性和注释
在 C# 类库中,使用 WebPubSubTrigger
特性。
下面是某个方法签名中的 WebPubSubTrigger
特性:
[FunctionName("WebPubSubTrigger")]
public static void Run([WebPubSubTrigger("<hub>", <WebPubSubEventType>, "<event-name>")]
WebPubSubConnectionContext context, ILogger log)
{
...
}
有关完整示例,请参阅 C# 示例。
配置
下表解释了在 function.json 文件中设置的绑定配置属性。
function.json 属性 | Attribute 属性 | 说明 |
---|---|---|
type | 不适用 | 必需 - 必须设置为 webPubSubTrigger 。 |
direction | 不适用 | 必需 - 必须设置为 in 。 |
name | 不适用 | 必需 - 在函数代码中对接收事件数据的参数使用的变量名称。 |
hub | 集线器 | 必需 - 该值必须设置为 Web PubSub 中心的名称,用于要触发的函数。 支持在特性中将该值设置为更高优先级,或者在应用设置中将该值设置为全局值。 |
eventType | WebPubSubEventType | 必需 - 该值必须设置为消息的事件类型,用于要触发的函数。 该值应为 user 或 system 。 |
eventName | EventName | 必需 - 该值必须设置为消息事件,用于要触发的函数。 对于 system 事件类型,事件名称应为 connect 、connected 或 disconnected 。 对于用户定义的子协议,事件名称为 message 。 对于系统支持的子协议 json.webpubsub.azure.v1. ,事件名称为用户定义的事件名称。 |
连接 | 连接 | 可选 - 指定上游 Azure Web PubSub 服务的应用设置或设置集合的名称。 该值用于签名验证。 默认情况下,该值会使用应用程序设置“WebPubSubConnectionString”自动解析。 null 表示不需要验证并且始终成功。 |
用途
在 C# 中,WebPubSubEventRequest
是具有识别类型的绑定参数,其他参数则由参数名称绑定。 请查看下表中的可用参数和类型。
在 JavaScript 等弱类型语言中,function.json
中的 name
用于绑定下面映射表的触发器对象。 当 name
设置为 data
作为触发器输入的绑定对象时,将遵守 function.json
中的 dataType
相应地转换消息。 所有参数都可以从 context.bindingData.<BindingName>
读取并使用 JObject
进行转换。
绑定名称 | 绑定类型 | 说明 | 属性 |
---|---|---|---|
request | WebPubSubEventRequest |
描述上游请求 | 属性因事件类型而异,包括派生类 ConnectEventRequest 、ConnectedEventRequest 、UserEventRequest 和 DisconnectedEventRequest |
connectionContext | WebPubSubConnectionContext |
常见请求信息 | EventType、EventName、Hub、ConnectionId、UserId、Headers、Origin、Signature、States |
数据 | BinaryData 、string 、Stream 、byte[] |
在用户 message 事件中从客户端请求消息数据 |
- |
dataType | WebPubSubDataType |
请求消息数据类型,支持 binary 、text 、json |
- |
声明 | IDictionary<string, string[]> |
系统 connect 请求中的用户声明 |
- |
query | IDictionary<string, string[]> |
系统 connect 请求中的用户查询 |
- |
subprotocols | IList<string> |
系统 connect 请求中的可用子协议 |
- |
clientCertificates | IList<ClientCertificate> |
系统 connect 请求中客户端的证书指纹列表 |
- |
reason | string |
系统 disconnected 请求中的原因 |
- |
重要
在 C# 中,受支持参数的多种类型(例如默认的 BinaryData
类型之外的 request
或 data
)必须放在第一个位置,以使函数正确绑定。
返回响应
WebPubSubTrigger
遵守connect
同步事件和用户事件的客户返回响应。 只有匹配的响应才会发送回服务,否则将被忽略。 此外,WebPubSubTrigger
返回对象支持用户通过 SetState()
和 ClearStates()
来管理连接的元数据。 该扩展会将返回值的结果与请求 WebPubSubConnectionContext.States
的原始结果合并。 现有密钥中的值将被覆盖,并添加新密钥中的值。
返回类型 | 说明 | 属性 |
---|---|---|
ConnectEventResponse |
connect 事件的响应 |
Groups、Roles、UserId、Subprotocol |
UserEventResponse |
用户事件的响应 | DataType、Data |
EventErrorResponse |
同步事件的错误响应 | Code、ErrorMessage |
*WebPubSubEventResponse |
受支持响应的基本响应类型,用于不确定的返回事例 | - |
输入绑定
扩展提供两个输入绑定,以满足不同的需求。
WebPubSubConnection
客户端在连接到 Azure Web PubSub 服务之前,必须知道服务终结点 URL 和有效的访问令牌。
WebPubSubConnection
输入绑定会生成所需信息,因此客户端无需自行处理令牌生成。 由于此令牌有时间限制,并且可用来对需要连接的特定用户进行身份验证,因此请不要缓存此令牌,也不要在客户端之间共享此令牌。 客户端可以使用处理此输入绑定的 HTTP 触发器来检索连接信息。WebPubSubContext
在使用 Static Web Apps 时,
HttpTrigger
是唯一受支持的触发器,而且在 Web PubSub 方案中,我们提供的WebPubSubContext
输入绑定可帮助用户对 Web PubSub 协议下来自服务端的上游 http 请求进行反序列化。 因此,客户可获得与WebPubSubTrigger
相似的结果,从而在函数中轻松处理。 请参阅以下示例。 使用HttpTrigger
时,客户需要在事件处理程序相应地配置 HttpTrigger 的公开 URL。
示例 - WebPubSubConnection
以下示例演示了一个 C# 函数,该函数使用输入绑定获取 Web PubSub 连接信息,并通过 HTTP 将其返回。 在下面的示例中,UserId
是通过客户端请求查询部分(如 ?userid={User-A}
)传入的。
[FunctionName("WebPubSubConnectionInputBinding")]
public static WebPubSubConnection Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req,
[WebPubSubConnection(Hub = "<hub>", UserId = "{query.userid}")] WebPubSubConnection connection)
{
return connection;
}
已经过身份验证的令牌
如果此函数由经过身份验证的客户端触发,则可向生成的令牌添加用户 ID 声明。 可以轻松地使用应用服务身份验证向函数应用添加身份验证。
应用服务身份验证会设置名为 x-ms-client-principal-id
和 x-ms-client-principal-name
(分别包含经身份验证的用户的客户端主体 ID 和名称)的 HTTP 标头。
可以使用绑定表达式将绑定的 UserId 属性设置为以下任一标头中的值:{headers.x-ms-client-principal-id}
或 {headers.x-ms-client-principal-name}
。
[FunctionName("WebPubSubConnectionInputBinding")]
public static WebPubSubConnection Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req,
[WebPubSubConnection(Hub = "<hub>", UserId = "{headers.x-ms-client-principal-name}")] WebPubSubConnection connection)
{
return connection;
}
注意
限于绑定参数类型不支持传递列表或数组的方式,服务器 SDK 的所有参数并不完全支持 WebPubSubConnection
,尤其是 roles
,还包括 groups
和 expiresAfter
。 如果客户需要在函数中添加角色或延迟构建访问令牌,建议使用 C# 服务器 SDK。
[FunctionName("WebPubSubConnectionCustomRoles")]
public static async Task<Uri> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req)
{
var serviceClient = new WebPubSubServiceClient(new Uri(endpoint), "<hub>", "<web-pubsub-connection-string>");
var userId = req.Query["userid"].FirstOrDefault();
// your method to get custom roles.
var roles = GetRoles(userId);
return await serviceClient.GetClientAccessUriAsync(TimeSpan.FromMinutes(5), userId, roles);
}
示例 - WebPubSubContext
以下示例演示了一个 C# 函数,该函数在 connect
事件类型下使用输入绑定获取 Web PubSub 上游请求信息,并通过 HTTP 将其返回。
[FunctionName("WebPubSubContextInputBinding")]
public static object Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req,
[WebPubSubContext] WebPubSubContext wpsContext)
{
// in the case request is a preflight or invalid, directly return prebuild response by extension.
if (wpsContext.IsPreflight || wpsContext.HasError)
{
return wpsContext.Response;
}
var request = wpsContext.Request as ConnectEventRequest;
var response = new ConnectEventResponse
{
UserId = wpsContext.Request.ConnectionContext.UserId
};
return response;
}
配置
WebPubSubConnection
下表解释了在 function.json 文件和 WebPubSubConnection
特性中设置的绑定配置属性。
function.json 属性 | Attribute 属性 | 说明 |
---|---|---|
type | 不适用 | 必须设置为 webPubSubConnection |
direction | 不适用 | 必须设置为 in |
name | 不适用 | 变量名称,在输入连接绑定对象的函数代码中使用。 |
hub | 集线器 | 必需 - 该值必须设置为 Web PubSub 中心的名称,用于要触发的函数。 支持在特性中将该值设置为更高优先级,或者在应用设置中将该值设置为全局值。 |
userId | UserId | 可选 - 用户标识符声明的值,在访问密钥令牌中设置。 |
连接 | 连接 | 必需 - 应用设置的名称,包含 Web PubSub 服务连接字符串(默认为“WebPubSubConnectionString”)。 |
WebPubSubContext
下表解释了在 functions.json 文件和 WebPubSubContext
特性中设置的绑定配置属性。
function.json 属性 | Attribute 属性 | 说明 |
---|---|---|
type | 不适用 | 必须设置为 webPubSubContext 。 |
direction | 不适用 | 必须设置为 in 。 |
name | 不适用 | 变量名称,在输入 Web PubSub 请求的函数代码中使用。 |
连接 | 连接 | 可选 - 指定上游 Azure Web PubSub 服务的应用设置或设置集合的名称。 该值用于滥用保护和签名验证。 默认情况下,该值将使用“WebPubSubConnectionString”自动解析。 null 表示不需要验证并且始终成功。 |
使用情况
WebPubSubConnection
WebPubSubConnection
提供以下属性。
绑定名称 | 绑定类型 | 说明 |
---|---|---|
BaseUri | Uri | Web PubSub 客户端连接 URI。 |
URI | URI | Web PubSub 连接的绝对 URI,包含根据请求生成的 AccessToken 。 |
AccessToken | 字符串 | 根据请求 UserId 和服务信息生成的 AccessToken 。 |
WebPubSubContext
WebPubSubContext
提供以下属性。
绑定名称 | 绑定类型 | 说明 | 属性 |
---|---|---|---|
request | WebPubSubEventRequest |
来自客户端的请求,请参阅下表了解详细信息。 | 来自请求标头的 WebPubSubConnectionContext 和从请求正文反序列化的其他属性可描述请求,例如 DisconnectedEventRequest 的 Reason 。 |
响应 | HttpResponseMessage |
扩展生成响应,主要针对 AbuseProtection 和错误情况。 |
- |
errorMessage | string | 描述处理上游请求时的错误详细信息。 | - |
hasError | bool | 指示其是否是有效 Web PubSub 上游请求的标志。 | - |
isPreflight | bool | 指示其是否是 AbuseProtection 的预检请求的标志。 |
- |
对于 WebPubSubEventRequest
,会将其反序列化为不同的类,从而提供有关请求方案的其他信息。 对于 PreflightRequest
或无效的情况,用户可以检查标志 IsPreflight
和 HasError
来了解情况。 建议直接返回系统生成响应 WebPubSubContext.Response
,或者客户可根据需要记录错误。 在不同的方案中,客户可以读取的请求属性如下所示。
派生类 | 说明 | 属性 |
---|---|---|
PreflightRequest |
当 IsPreflight 为“true”时,在 AbuseProtection 中使用 |
- |
ConnectEventRequest |
在系统 Connect 事件类型中使用 |
Claims、Query、Subprotocols、ClientCertificates |
ConnectedEventRequest |
在系统 Connected 事件类型中使用 |
- |
UserEventRequest |
在用户事件类型中使用 | Data、DataType |
DisconnectedEventRequest |
在系统 Disconnected 事件类型中使用 |
Reason |
注意
虽然 WebPubSubContext
是一个输入绑定,但与 WebPubSubTrigger
相比,它可在 HttpTrigger
下提供类似的请求反序列化方式,但也存在限制,即不支持合并后的连接状态。 服务端仍然会遵守返回响应,但用户需要自己构建响应。 如果用户需要设置事件响应,应返回一个包含 ConnectEventResponse
或用户事件消息的 HttpResponseMessage
作为“响应正文”,并在响应头中将连接状态与键 ce-connectionstate
放置在一起 。
输出绑定
使用 Web PubSub 输出绑定调用 Azure Web PubSub 服务以执行某些操作。 可以将消息广播到:
- 所有连接的客户端
- 对特定用户进行身份验证的已连接客户端
- 加入特定组的已连接客户端
- 特定客户端连接
通过输出绑定,还可以管理客户端和组,以及授予/撤销针对组的特定 connectionId 的权限。
- 向组添加连接
- 将用户添加到组
- 从组中删除连接
- 从组中删除用户
- 从所有组中删除用户
- 关闭所有客户端连接
- 关闭特定客户端连接
- 关闭组中连接
- 授予连接权限
- 撤销连接权限
有关设置和配置的详细信息,请参阅概述。
示例
[FunctionName("WebPubSubOutputBinding")]
public static async Task RunAsync(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req,
[WebPubSub(Hub = "<hub>")] IAsyncCollector<WebPubSubAction> actions)
{
await actions.AddAsync(WebPubSubAction.CreateSendToAllAction("Hello Web PubSub!", WebPubSubDataType.Text));
}
WebPubSubAction
WebPubSubAction
是输出绑定的基本抽象类型。 派生类型表示需要调用服务的操作服务器。
在 C# 语言中,我们在 WebPubSubAction
下提供了一些静态方法,以帮助发现可用操作。 例如,用户可通过调用 WebPubSubAction.CreateSendToAllAction()
来创建 SendToAllAction
。
派生类 | 属性 |
---|---|
SendToAllAction |
Data、DataType、Excluded |
SendToGroupAction |
Group、Data、DataType、Excluded |
SendToUserAction |
UserId、Data、DataType |
SendToConnectionAction |
ConnectionId、Data、DataType |
AddUserToGroupAction |
UserId、Group |
RemoveUserFromGroupAction |
UserId、Group |
RemoveUserFromAllGroupsAction |
UserId |
AddConnectionToGroupAction |
ConnectionId、Group |
RemoveConnectionFromGroupAction |
ConnectionId、Group |
CloseAllConnectionsAction |
Excluded、Reason |
CloseClientConnectionAction |
ConnectionId、Reason |
CloseGroupConnectionsAction |
Group、Excluded、Reason |
GrantPermissionAction |
ConnectionId、Permission、TargetName |
RevokePermissionAction |
ConnectionId、Permission、TargetName |
配置
WebPubSub
下表解释了在 function.json 文件和 WebPubSub
特性中设置的绑定配置属性。
function.json 属性 | Attribute 属性 | 说明 |
---|---|---|
type | 不适用 | 必须设置为 webPubSub |
direction | 不适用 | 必须设置为 out |
name | 不适用 | 变量名称,在输出绑定对象的函数代码中使用。 |
hub | 集线器 | 该值必须设置为 Web PubSub 中心的名称,用于要触发的函数。 支持在特性中将该值设置为更高优先级,或者在应用设置中将该值设置为全局值。 |
连接 | 连接 | 应用设置的名称,包含 Web PubSub 服务连接字符串(默认为“WebPubSubConnectionString”)。 |
疑难解答
设置控制台日志记录
如果想要更深入地了解针对服务发出的请求,还可以轻松启用控制台记录。
后续步骤
使用这些资源开始生成自己的应用程序: