SignalR Redis backplane 是用于多服务器部署时跨节点转发 Hub 方法调用的官方消息总线,必须在负载均衡集群中启用以同步广播;它不复制连接状态或客户端视图,仅转发如 Clients.All.InvokeAsync 等调用指令。

SignalR Redis backplane 是什么,什么时候必须用
当 SignalR 应用部署在多台服务器(如负载均衡后的 IIS 或 Kestrel 集群)时,Hub 实例分散在不同进程里,单机内存无法同步连接状态和广播消息。此时必须启用 backplane——Redis 就是官方支持的三种 backplane 之一(另两个是 SQL Server、Azure Service Bus)。它不替代 SignalR 的实时通信,只负责跨节点转发 hub.SendAsync、Clients.All.InvokeAsync 这类调用。
安装 NuGet 包与注册 Redis backplane(.NET 6+)
SignalR 的 Redis 扩展已从 Microsoft.AspNetCore.SignalR.Redis 迁移至 Microsoft.AspNetCore.SignalR.StackExchangeRedis(依赖 StackExchange.Redis 2.x+)。注意:.NET 5 及更早版本用的是旧包名,不兼容新 API。
- 安装
Microsoft.AspNetCore.SignalR.StackExchangeRedis - 在
Program.cs中注册(非 Startup.cs):builder.Services.AddSignalR().AddStackExchangeRedis(options => { options.Configuration = "localhost:6379,abortConnect=false"; options.ChannelPrefix = "MyApp:SignalR"; }); -
options.Configuration支持连接字符串或ConfigurationOptions实例;若 Redis 启用了密码,写成"localhost:6379,password=xxx,abortConnect=false" -
ChannelPrefix建议显式设置,避免多个环境共用 Redis 时 channel 冲突
Redis backplane 不会自动同步 Hub 状态,别指望它解决连接 ID 跨节点查询
Backplane 只转发“方法调用”,不复制 IHubContext.Clients 的内存视图。例如:hubContext.Clients.Client(connectionId).SendAsync(...) 若该 connectionId 当前连在另一台服务器上,Redis backplane 会把消息转发过去;但如果你试图在 A 服务器上调用 hubContext.Clients.All.Count(),结果仍是本机在线数,不是集群总数。
- 需要全局连接统计?得自己用 Redis 的
SET或HASH维护,配合OnConnectedAsync/OnDisconnectedAsync - 按用户推送(
Clients.User(userId))依赖 SignalR 内置的 user ID 映射,backplane 会转发,但前提是所有节点使用相同的IUserIdProvider - 自定义 group 管理(
AddToGroupAsync)是线程安全且跨节点生效的,group 成员关系由 Redis 自动同步
常见报错与调试要点
启动失败或消息不达,优先检查 Redis 连通性与权限,而非 SignalR 代码逻辑。
-
StackExchange.Redis.RedisConnectionException: It was not possible to connect to the redis server(s):确认 Redis 正在监听外部 IP(bind配置)、防火墙放行、连接字符串端口正确 - 消息发出去但客户端收不到:用
redis-cli monitor查看是否有以ChannelPrefix开头的PUBLISH命令;没有说明 backplane 根本没触发 - .NET 6+ 中若 Hub 方法抛异常,错误不会自动传播到调用方(尤其是跨节点调用),需手动捕获并记录日志
- 高并发下 Redis 成为瓶颈:避免高频调用
Clients.All.SendAsync,改用 group 或 connection ID 精准推送;考虑 Redis 集群或读写分离
Redis backplane 的核心职责很窄:可靠地把“调用指令”从一台服务器广播到其他服务器。它不管理连接生命周期,也不提供分布式锁或状态缓存——那些得你自己补。










