SignalR OnConnected 与多台服务器和 Redis 背板

Posted

技术标签:

【中文标题】SignalR OnConnected 与多台服务器和 Redis 背板【英文标题】:SignalR OnConnected with multiple servers and Redis backplane 【发布时间】:2013-10-25 14:59:56 【问题描述】:

我有以下 Hub 片段与 SignalR、Redis 背板和单个服务器一起使用。

公共抽象类 HubBase : Hub 私有只读静态 ConnectionMapping Connections = new ConnectionMapping(); 公共覆盖任务 OnConnected() Connections.Add(Context.User.Identity.Name, Context.ConnectionId); 返回 base.OnConnected();

我将连接用户存储在一个静态变量中,这样我就可以将 connectionId 映射到用户名,并能够在以后向特定用户发送消息。

我的问题是,是否会在 SignalR 场中的所有服务器上调用 OnConnected 函数?我对其进行了测试,从外观上看,它只在客户端连接的服务器上调用。

如果没有在所有服务器上调用它,处理这种情况的推荐方法是什么?

编辑:考虑到这一点,我意识到我的示例代码可能存在严重缺陷。如果在另一台服务器上也调用了 OnConnected 方法,那么显然不会设置 Context.User.Identity.Name,因为调用时没有请求。我想解决这个问题的唯一方法就是使用组。

【问题讨论】:

您好我有一个类似的问题 - 我正在研究连接、组状态和 REDIS 背板之间的关系。 David Fowler 说 signalR 是无状态的,所以我担心这是我需要自己跟踪/存储/广播的东西...... 你必须将你的Connections对象存储在Redis中,所以所有服务器都可以访问同一个列表 【参考方案1】:

有一种方法可以做到这一点,但正如 penderi 所说,信号器是无状态的,因此不能保证特定用户仍处于连接状态。我不确定Redis,但SQL Server背板使用IMessageBus,它将所有消息存储在本地缓存中,如果用户断开连接,则IMessageBus进程将发送自用户断开连接时已广播的所有消息,当用户重新连接时。需要注意的是,缓存只能保存这么长时间的消息。

这是一个数据库实现的链接,用于将用户映射到他们的 connectionIds

https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/mapping-users-to-connections#database

【讨论】:

以上是关于SignalR OnConnected 与多台服务器和 Redis 背板的主要内容,如果未能解决你的问题,请参考以下文章

.net core 3.0 Signalr - 04 使用Redis做底板来支持横向扩展

.net core 3.0 Signalr - 04 使用Redis做底板来支持横向扩展

新的位置 API Android。错误“调用 connect() 并等待调用 onConnected()”

SignalR:服务器如何建立与客户端的连接?

如何确定与 SignalR 客户端的服务器断开连接?

客户何时适合与 SignalR 服务重新协商?