Azure Functions 的 SignalR 服务触发器绑定
使用 SignalR 触发器绑定来响应从 Azure SignalR 服务发送的消息。 触发函数时,传递给函数的消息分析为 json 对象。
在 SignalR 服务无服务器模式下,SignalR 服务使用上游功能从客户端向函数应用发送消息。 函数应用会使用 SignalR 服务触发器绑定来处理这些消息。 一般的体系结构如下所示:
若要了解设置和配置详细信息,请参阅概述。
示例
可使用以下 C# 模式之一来创建 C# 函数:
- 进程内类库:编译的 C# 函数,该函数在与 Functions 运行时相同的进程中运行。
- 独立工作进程类库:编译的 C# 函数,该函数在独立于运行时的工作进程中运行。 需要独立工作进程才能支持在 LTS 和非 LTS 版 .NET 和 .NET Framework 上运行的 C# 函数。
- C# 脚本:主要在 Azure 门户中创建 C# 函数时使用。
重要
对进程内模型的支持将于 2026 年 11 月 10 日结束。 为获得完全支持,强烈建议将应用迁移到独立工作模型。
以下示例演示一个 C# 函数,该函数从客户端接收消息事件并记录消息内容。
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
namespace Extensions.SignalR
{
public static class SignalRTriggerFunctions
{
// <snippet_on_connected>
[Function(nameof(OnConnected))]
public static void OnConnected(
[SignalRTrigger("chat", "connections", "connected", ConnectionStringSetting = "SignalRConnection")]
SignalRInvocationContext invocationContext, FunctionContext functionContext)
{
var logger = functionContext.GetLogger(nameof(OnConnected));
logger.LogInformation("Connection {connectionId} is connected", invocationContext.ConnectionId);
}
// </snippet_on_connected>
// <snippet_on_disconnected>
[Function(nameof(OnDisconnected))]
public static void OnDisconnected(
[SignalRTrigger("chat", "connections", "disconnected", ConnectionStringSetting = "SignalRConnection")]
SignalRInvocationContext invocationContext, FunctionContext functionContext)
{
var logger = functionContext.GetLogger(nameof(OnDisconnected));
logger.LogInformation("Connection {connectionId} is disconnected. Error: {error}", invocationContext.ConnectionId, invocationContext.Error);
}
// </snippet_on_disconnected>
// <snippet_on_message>
[Function(nameof(OnClientMessage))]
public static void OnClientMessage(
[SignalRTrigger("Hub", "messages", "sendMessage", "content", ConnectionStringSetting = "SignalRConnection")]
SignalRInvocationContext invocationContext, string content, FunctionContext functionContext)
{
var logger = functionContext.GetLogger(nameof(OnClientMessage));
logger.LogInformation("Connection {connectionId} sent a message. Message content: {content}", invocationContext.ConnectionId, content);
}
// </snippet_on_message>
}
}
重要
由于 C# 辅助角色模型的限制,C# 独立辅助角色中 SignalR 服务绑定的基于类的模型无法优化你编写 SignalR 触发器的方式。 有关基于类的模型的详细信息,请参阅基于类的模型。
Java 目前不支持 SignalR 触发器。
下面是 function.json 文件中的绑定数据:
{
"type": "signalRTrigger",
"name": "invocation",
"hubName": "hubName1",
"category": "messages",
"event": "SendMessage",
"parameterNames": [
"message"
],
"direction": "in"
}
app.generic("function1",
{
trigger: { "type": "signalRTrigger", "name": "invocation", "direction": "in", "hubName": "hubName1", "event": "SendMessage", "category": "messages" },
handler: (triggerInput, context) => {
context.log(`Receive ${context.Arguments[0]} from ${triggerInput.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 | 消息所属的中心的名称。 |
类别 | 消息的类别。 |
事件 | 消息的事件。 |
ConnectionId | 发送消息的客户端的连接 ID。 |
UserID | 发送消息的客户端的用户标识。 |
标头 | 请求的标头。 |
查询 | 客户端连接到服务时的请求的查询。 |
声明 | 客户端的声明。 |
使用 ParameterNames
通过 SignalRTrigger
中的属性 ParameterNames
,可将调用消息的参数绑定到函数的参数。 定义的名称可在其他绑定中用作绑定表达式的一部分,或者用作代码中的参数。 这为你提供了更方便的方法来访问 InvocationContext
的参数。
假设你有 JavaScript SignalR 客户端尝试使用两个参数 message1
、message2
调用 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。
使用 SignalR 服务触发器时,URL 可以十分简单,其格式可以设置为如下所示:
<Function_App_URL>/runtime/webhooks/signalr?code=<API_KEY>
Function_App_URL
可在函数应用的“概述”页上找到,API_KEY
由 Azure Function 生成。 可以从函数应用的“应用密钥”边栏选项卡中获取 signalr_extension
的 API_KEY
。
如果要将多个函数应用与一个 SignalR 服务一起使用,上游还可以支持复杂的路由规则。 有关更多详细信息,请查看上游设置。
分步示例
可以按照 GitHub 中的示例,使用 SignalR 服务触发器绑定和上游功能在函数应用上部署聊天室:双向聊天室示例