问题
I am using .Net framework 4.5.2 and I will start to make a notification system that send notifications from web application into users that are connected from windows forms desktop application .
after investigations i found that the suitable solution is using signalR as it supports filtering the notification before sending it to the connected clients .
but my concern here is that : when i created my HUB class in the web application , i implemented the method OnConnected that will detect any client who is connected to the server to recieve the notifications , i thought about collecting the connected users in dictionary (in memory) i know it is a solution that couldn't be implemented in the production as this is not reliable to set the connected users in a memory variable (dictionary) . In my case the number of connected users may be 20,000 or over and it may get larger in future . I need to know the best way to track all connected users and at the same time the bets way to handle the concurrent requests without having any scalability issues . I am new in this and i have to make my decision very fast please.
I also need to know in what is the usage of OnReconnect method which can be overidden in the hub class .
I need also to know how to handle the connection to not being lost in case if the iis restarts the internet application for any reason.
回答1:
Mapping connections to users can be done in multiple ways, depending on what you want to achieve:
In memory storage:
Best way to do that is by using a concurrent dictionary. This will allow thread safe operations, but, as you said, not the best solution for massive number of connections.
Permanent external storage
Keep your mapping in a database.
The good part: the mapping is available across multiple web servers
The bad part: a lot of stress on the database and a lot of cleanup necessary
Single-User Groups
Create one group for each user. This is the most simple and practical solution.
The good part:
~ really easy to use and implement
~ SignalR is smart enough to remove the connection from the group when disconnected
~ groups are deleted when you remove the last connection
~ if you use Identity, you can store the unique group name as a claim [1] [2] and get it inside your hub with something like:
public static class IdentityExtensions
{
public static string GetSignalRUniqueGroup(this IIdentity identity)
{
var claimsIdentity = identity as ClaimsIdentity;
var claim = claimsIdentity?.FindFirst("uniqueSignalRGroup");
if (claim == null) return null;
try
{
return claim.Value;
}
catch
{
return null;
}
}
}
The (not really that) bad part: you have to be careful with what user joins what group. !DO NOT! implement the join group functionality on the client side. Instead, use OnConnected and OnReconnected to add the connection to the group
public override Task OnConnected()
{
string userGroup = Context.User.Identity.GetSignalRUniqueGroup();
if(userGroup != null)
{
Groups.Add(Context.ConnectionId, userGroup);
}
return base.OnConnected();
}
public override Task OnReconnected()
{
string userGroup = Context.User.Identity.GetSignalRUniqueGroup();
if(userGroup != null)
{
Groups.Add(Context.ConnectionId, userGroup);
}
return base.OnReconnected();
}
public override Task OnDisconnected(bool stopCalled)
{
//You should not manually remove the user from the group when the user disconnects.
//This action is automatically performed by the SignalR framework.
return base.OnDisconnected(stopCalled);
}
For other question, you can read this: Understanding and Handling Connection Lifetime Events in SignalR
来源:https://stackoverflow.com/questions/37455608/handling-concurrent-connections-in-siganlr