简体   繁体   English

SignalR:使用多个集线器管理OnDisconnect()

[英]SignalR: Managing OnDisconnect() with multiple hubs

I have a SignalR application which manages users and connections, User / Room, with a database. 我有一个SignalR应用程序,可以管理用户和数据库的用户和连接。 I followed the following article (under Permanent, external storage -> Database ) 我关注了以下文章(在“ 永久外部存储 -> 数据库”下

http://www.asp.net/signalr/overview/guide-to-the-api/mapping-users-to-connections http://www.asp.net/signalr/overview/guide-to-the-api/mapping-users-to-connections

As someone logs in, I insert their entry into a Room table, and remove it as they leave. 当有人登录时,我将其条目插入“房间”表,并在离开时将其删除。

I now have two hubs, "Chat" and "Game". 我现在有两个中心,“聊天”和“游戏”。

Lets say for example UserA into both Chat and Game hub. 例如,让用户A进入聊天和游戏中心。 I create 2 entries into both a Chat table and Game table. 我在“聊天”表和“游戏”表中都创建了2个条目。 However, if UserA does a 'non-graceful' close of a single hub (ie. close tab), I am not able to pick which room/hub UserA disconnected from. 但是,如果UserA对单个集线器进行了“非正常”关闭(即“关闭”选项卡),我将无法选择UserA断开连接的房间/集线器。 (OnDisconnect does not allow me to capture these details). (OnDisconnect不允许我捕获这些详细信息)。 This forces me to remove all occurrences of UserA across all tables he is found in on my database 这迫使我删除在数据库中找到的所有表中所有出现的UserA

Now how is it possible for me to know which hub UserA exited from so that I may only remove his entry for that particular room. 现在,我怎么可能知道从哪个集线器UserA退出,所以我只能删除他在那个特定房间的条目。 (eg UserA is in both Game Room and Chat Room . He closes the Game Room window. Application needs to only remove his entry from Game Room table.) (例如,用户A在游戏室聊天室中 。他关闭游戏室窗口。应用程序只需从游戏室表中删除其条目。)

Any input, suggestions is much appreciated. 任何意见,建议,不胜感激。

In every method that is called in your SignalR Hub you have access to the unique ConnectionId through this.Context.ConnectionId . 在SignalR Hub调用的每个方法中,您都可以通过this.Context.ConnectionId来访问唯一的ConnectionId You should link this id to the user. 您应该将此ID链接到用户。

Once in the OnDisconnected handler, use that ConnectionId to know which user has left. 进入OnDisconnected处理程序后,使用该ConnectionId知道哪个用户离开了。

And according to this article : 并根据这篇文章

The connection ID is a GUID that is assigned by SignalR (you can't specify the value in your own code). 连接ID是SignalR分配的GUID(您无法在自己的代码中指定值)。 There is one connection ID for each connection, and the same connection ID is used by all Hubs if you have multiple Hubs in your application. 每个连接只有一个连接ID,如果您的应用程序中有多个集线器,则所有集线器都使用相同的连接ID。

What I do is when the user connects, in the OnConnected method I simply add their ConnectionId to a key in the database that is similar to: 我要做的是,当用户连接时,在OnConnected方法中,我只需将其ConnectionId添加到数据库中的键中,该键类似于:

UserId:HubName:ConnectionId

The HubName part I get through reflection: Type.GetType().Name 我通过反射得到的HubName部分: Type.GetType().Name

I use this key to add in the database when the user connects and remove it from the same database when OnDisconnected gets called. 我使用此密钥在用户连接时添加数据库,并在调用OnDisconnected时将其从同一数据库中删除。

Now, keep in mind that if the server fails at some point, the OnDisconnected method doesn't get called, so you are left in the database with some ConnectionId 's that you think belong to a user, but they actually no longer do. 现在,请记住,如果服务器在某个时刻出现故障,则不会调用OnDisconnected方法,因此您会在数据库中留下一些您认为属于用户的ConnectionId ,但实际上不再使用它们。

Every time the server starts, I would search the database for ConnnectionId 's and verify if they are actually active (most probably not) and delete them. 每次服务器启动时,我都会在数据库中搜索ConnnectionId ,并验证它们是否实际上处于活动状态(很可能不是活动状态)并删除它们。

Hope this helps. 希望这可以帮助。 Best of luck! 祝你好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM