SignalR:管理OnDisconnect()与多个集线器
本文关键字:集线器 管理 OnDisconnect SignalR | 更新日期: 2023-09-27 18:07:26
我有一个SignalR应用程序,它管理用户和连接,用户/房间,与数据库。我遵循以下文章(在永久性,外部存储 -> 数据库)
http://www.asp.net/signalr/overview/guide-to-the-api/mapping-users-to-connections当有人登录时,我将他们的条目插入到Room表中,并在他们离开时将其删除。
我现在有两个中心,"聊天"answers"游戏"。
让我们以UserA同时进入聊天和游戏中心为例。我在聊天表和游戏表中创建了2个条目。但是,如果UserA对单个集线器进行"非优雅"关闭(例如:关闭选项卡),我无法选择哪个房间/中心UserA断开连接。(OnDisconnect不允许我捕捉这些细节)。这迫使我在数据库
中找到的所有表中删除所有出现的UserA。现在我怎么可能知道UserA从哪个中心退出,这样我就可以只删除他的特定房间的条目。(例如,UserA同时存在于Game Room和Chat Room中。他关上了Game Room窗口。应用程序只需要从Game Room表中删除他的条目。
在您的SignalR Hub
中调用的每个方法中,您可以通过this.Context.ConnectionId
访问唯一的ConnectionId
。你应该把这个id链接到用户。
一旦进入OnDisconnected
处理程序,使用该ConnectionId
来知道哪个用户离开了。
根据这篇文章:
连接ID是由SignalR分配的GUID(你不能在自己的代码中指定该值)。每个连接都有一个连接ID,如果您的应用程序中有多个hub,则所有hub都使用相同的连接ID。
我所做的是当用户连接时,在OnConnected
方法中,我简单地将他们的ConnectionId
添加到数据库中的一个键,类似于:
UserId:HubName:ConnectionId
通过反思得到的HubName
部分:Type.GetType().Name
当用户连接时,我使用此键在数据库中添加,并在调用OnDisconnected
时从同一数据库中删除它。
现在,请记住,如果服务器在某些时候出现故障,则不会调用OnDisconnected
方法,因此在数据库中留下一些您认为属于用户的ConnectionId
,但实际上它们不再属于用户。
每次服务器启动时,我都会在数据库中搜索ConnnectionId
,并验证它们是否实际上是活动的(很可能不是),然后删除它们。
希望这对你有帮助。祝你好运!