你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

Azure Functions 的 SignalR 服务触发器绑定

使用 SignalR 触发器绑定来响应从 Azure SignalR 服务发送的消息。 触发函数时,传递给函数的消息分析为 json 对象。

在 SignalR 服务无服务器模式下,SignalR 服务使用上游功能从客户端向函数应用发送消息。 函数应用会使用 SignalR 服务触发器绑定来处理这些消息。 一般的体系结构如下所示:

SignalR Trigger Architecture

有关设置和配置详细信息,请参阅概述

示例

可以使用以下 C# 模式之一创建 C# 函数:

  • 进程内类库:编译的 C# 函数,该函数在与 Functions 运行时相同的进程中运行。
  • 独立进程类库:编译的 C# 函数,该函数在独立于运行时的进程中运行。 支持在 .NET 5.0 上运行的 C# 函数需要独立的进程。
  • C# 脚本:主要在 Azure 门户中创建 C# 函数时使用。

适用于 C# 的 SignalR 服务触发器绑定具有两种编程模型。 基于类的模型和传统模型。 基于类的模型提供一致的 SignalR 服务器端编程体验。 传统模型提供更大的灵活性,并与其他函数绑定类似。

对于基于类的模型

有关详细信息,请参阅基于类的模型

public class SignalRTestHub : ServerlessHub
{
    [FunctionName("SignalRTest")]
    public async Task SendMessage([SignalRTrigger]InvocationContext invocationContext, string message, ILogger logger)
    {
        logger.LogInformation($"Receive {message} from {invocationContext.ConnectionId}.");
    }
}

对于传统模型

传统模型遵守使用 C# 开发的 Azure Function 的约定。 如果不熟悉该约定,可通过文档了解和学习。

[FunctionName("SignalRTest")]
public static async Task Run([SignalRTrigger("SignalRTest", "messages", "SendMessage", parameterNames: new string[] {"message"})]InvocationContext invocationContext, string message, ILogger logger)
{
    logger.LogInformation($"Receive {message} from {invocationContext.ConnectionId}.");
}

因为在触发器中使用 ParameterNames 可能很困难,所以以下示例展示了如何使用 SignalRParameter 属性来定义 message 属性。

[FunctionName("SignalRTest")]
public static async Task Run([SignalRTrigger("SignalRTest", "messages", "SendMessage")]InvocationContext invocationContext, [SignalRParameter]string message, ILogger logger)
{
    logger.LogInformation($"Receive {message} from {invocationContext.ConnectionId}.");
}

Java 目前不支持 SignalR 触发器。

下面是 function.json 文件中的绑定数据:

{
    "type": "signalRTrigger",
    "name": "invocation",
    "hubName": "SignalRTest",
    "category": "messages",
    "event": "SendMessage",
    "parameterNames": [
        "message"
    ],
    "direction": "in"
}

JavaScript 代码如下所示:

module.exports = async function (context, invocation) {
    context.log(`Receive ${context.bindingData.message} from ${invocation.ConnectionId}.`)
};

完整的 PowerShell 示例处于待定状态。

下面是 Python 代码:

import logging
import json
import azure.functions as func

def main(invocation) -> None:
    invocation_json = json.loads(invocation)
    logging.info("Receive {0} from {1}".format(invocation_json['Arguments'][0], invocation_json['ConnectionId']))

特性

进程内独立进程 C# 库都使用 SignalRTrigger 特性来定义函数。 C# 脚本改为使用 function.json 配置文件。

下表说明了 SignalRTrigger 特性的属性。

Attribute 属性 说明
HubName 此值必须设置为要触发的函数的 SignalR 中心的名称。
类别 此值必须设置为要触发的函数的消息类别。 类别可以是下列值之一:
  • 连接:包括“已连接”和“已断开连接”的事件
  • 消息:包含除连接类别中事件的所有其他事件
事件 此值必须设置为要触发的函数的消息事件。 对于消息类别,事件是客户端发送的调用消息中的目标 。 对于连接类别,只使用“已连接”和“已断开连接” 。
ParameterNames (可选)绑定到参数的名称列表。
ConnectionStringSetting 包含 SignalR 服务连接字符串(默认为 AzureSignalRConnectionString)的应用设置的名称。

批注

对于 SignalR 触发器,当前还没有受支持的 Java 注释。

配置

下表解释了在 function.json 文件中设置的绑定配置属性。

function.json 属性 说明
type 必须设置为 SignalRTrigger
direction 必须设置为 in
name 在函数代码中用于“触发器调用上下文”对象的变量名称。
hubName 此值必须设置为要触发的函数的 SignalR 中心的名称。
category 此值必须设置为要触发的函数的消息类别。 类别可以是下列值之一:
  • 连接:包括“已连接”和“已断开连接”的事件
  • 消息:包含除连接类别中事件的所有其他事件
event 此值必须设置为要触发的函数的消息事件。 对于消息类别,事件是客户端发送的调用消息中的目标 。 对于连接类别,只使用“已连接”和“已断开连接” 。
parameterNames (可选)绑定到参数的名称列表。
connectionStringSetting 包含 SignalR 服务连接字符串(默认为 AzureSignalRConnectionString)的应用设置的名称。

有关完整示例,请参阅示例部分

使用情况

Payloads

触发器输入类型声明为 InvocationContext 或自定义类型。 如果选择 InvocationContext,会获得对请求内容的完全访问权限。 对于自定义类型,运行时会尝试分析 JSON 请求正文,以设置对象属性。

InvocationContext

InvocationContext 包含从 SignalR 服务发送的消息中的所有内容,包括以下属性:

属性 说明
参数 可用于消息类别。 包含调用消息中的参数
错误 可用于“已断开连接”事件。 如果连接关闭时未发生错误,可以为空,否则会包含错误消息。
Hub 消息所属的中心的名称。
Category 消息的类别。
事件 消息的事件。
ConnectionId 发送消息的客户端的连接 ID。
UserId 发送消息的客户端的用户标识。
头文件 请求的标头。
查询 客户端连接到服务时的请求的查询。
声明 客户端的声明。

使用 ParameterNames

通过 SignalRTrigger 中的属性 ParameterNames,可将调用消息的参数绑定到函数的参数。 定义的名称可在其他绑定中用作绑定表达式的一部分,或者用作代码中的参数。 这为你提供了更方便的方法来访问 InvocationContext 的参数。

假设你有 JavaScript SignalR 客户端尝试使用两个参数 message1message2 调用 Azure Function 中的方法 broadcast

await connection.invoke("broadcast", message1, message2);

设置 parameterNames 后,定义的名称将对应于客户端发送的参数。

[SignalRTrigger(parameterNames: new string[] {"arg1, arg2"})]

然后,arg1 将包含 message1 的内容,arg2 将包含 message2 的内容。

ParameterNames 注意事项

对于参数绑定,顺序很重要。 如果使用 ParameterNames,则 ParameterNames 中的顺序与在客户端中调用参数的顺序相匹配。 如果在 C# 中使用特性 [SignalRParameter],则 Azure Function 方法中的参数顺序与客户端中参数的顺序相匹配。

ParameterNames 和特性 [SignalRParameter] 不能同时使用,否则将出现异常。

SignalR 服务集成

当你使用 SignalR 服务触发器绑定时,SignalR 服务需要一个用于访问函数应用的 URL。 应在 SignalR 服务端的上游设置中配置 URL。

Upstream Portal

使用 SignalR 服务触发器时,URL 可以十分简单,其格式可以设置为如下所示:

<Function_App_URL>/runtime/webhooks/signalr?code=<API_KEY>

Function_App_URL 可在函数应用的“概述”页上找到,API_KEY 由 Azure Function 生成。 可以从函数应用的“应用密钥”边栏选项卡中获取 signalr_extensionAPI_KEYAPI key

如果要将多个函数应用与一个 SignalR 服务一起使用,上游还可以支持复杂的路由规则。 有关更多详细信息,请查看上游设置

分步示例

可以按照 GitHub 中的示例,使用 SignalR 服务触发器绑定和上游功能在函数应用上部署聊天室:双向聊天室示例

后续步骤