适用于 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 门户中仅限联机) 添加绑定 若要更新现有绑定扩展而不必重新发布函数应用,请参阅更新扩展

关键概念

Diagram showing the workflow of Azure Web PubSub service working with Function Apps.

(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>

Screenshot of get function system keys.

示例

[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 事件遵守 ConnectEventResponseEventErrorResponse,用户事件遵守 UserEventResponseEventErrorResponse,与当前情况不匹配的其他类型则将被忽略。 如果返回 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 必需 - 该值必须设置为消息的事件类型,用于要触发的函数。 该值应为 usersystem
eventName EventName 必需 - 该值必须设置为消息事件,用于要触发的函数。
对于 system 事件类型,事件名称应为 connectconnecteddisconnected
对于用户定义的子协议,事件名称为 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 描述上游请求 属性因事件类型而异,包括派生类 ConnectEventRequestConnectedEventRequestUserEventRequestDisconnectedEventRequest
connectionContext WebPubSubConnectionContext 常见请求信息 EventType、EventName、Hub、ConnectionId、UserId、Headers、Origin、Signature、States
数据 BinaryDatastringStreambyte[] 在用户 message 事件中从客户端请求消息数据 -
dataType WebPubSubDataType 请求消息数据类型,支持 binarytextjson -
声明 IDictionary<string, string[]> 系统 connect 请求中的用户声明 -
query IDictionary<string, string[]> 系统 connect 请求中的用户查询 -
subprotocols IList<string> 系统 connect 请求中的可用子协议 -
clientCertificates IList<ClientCertificate> 系统 connect 请求中客户端的证书指纹列表 -
reason string 系统 disconnected 请求中的原因 -

重要

在 C# 中,受支持参数的多种类型(例如默认的 BinaryData 类型之外的 requestdata)必须放在第一个位置,以使函数正确绑定。

返回响应

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-idx-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,还包括 groupsexpiresAfter。 如果客户需要在函数中添加角色或延迟构建访问令牌,建议使用 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 和从请求正文反序列化的其他属性可描述请求,例如 DisconnectedEventRequestReason
响应 HttpResponseMessage 扩展生成响应,主要针对 AbuseProtection 和错误情况。 -
errorMessage string 描述处理上游请求时的错误详细信息。 -
hasError bool 指示其是否是有效 Web PubSub 上游请求的标志。 -
isPreflight bool 指示其是否是 AbuseProtection 的预检请求的标志。 -

对于 WebPubSubEventRequest,会将其反序列化为不同的类,从而提供有关请求方案的其他信息。 对于 PreflightRequest 或无效的情况,用户可以检查标志 IsPreflightHasError 来了解情况。 建议直接返回系统生成响应 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”)。

疑难解答

设置控制台日志记录

如果想要更深入地了解针对服务发出的请求,还可以轻松启用控制台记录

后续步骤

使用这些资源开始生成自己的应用程序: