Reputation: 15032
Hi, I'm working on an application which uses SignalR to send data updates to client. Data access is controlled via permissions, each data record (Item
) contains a reference to one permission. Users are associated with roles, each role is associated with a set of permissions. Any given user is allowed to see only records that reference permissions that are found in his (user's) roles.
Suppose you have 500 permissions in the system randomly distributed among 50 roles, also there is 1000 users that are online and randomly associated with those 50 roles which are defined in the system. Therefore some users will contain unique set of permissions, there may also be users that have identical set of roles and therefore identical sets of permissions.
Suppose one of the users changes 800
records and each of those records will reference one of 500 permissions defined in the system.
Now to inform users of that change, a message should be sent to each respectful user containing a set of records that a user is eligible to see. This means that depending on a set of permissions the user has, he may receive either:
Will I suffer from performance degradation if I will send messages to each client individually like that:
var data = GetData();
var users = GetConnectedUsers();
foreach (var user in users)
{
var filteredData = FilterByPermissions(user, data);
foreach (var connectionId in user.Connections)
{
Clients.Client(connectionId).onData(filteredData);
}
}
I was previously looking to NodeJS implementation of socket.io and it was doing ordinary foreach to send out data, if I understand correctly than in SignalR Clients.All
under the hood performs the same foreach loop that I'm trying to do.
Is it OK to do so? Rather than using Clients.All.onData(...)
? I've read about some problems with such approach related to a case when application is hosted on a WebFarm.
Will I get performance benefits from using SignalR groups? I think it is possible to put each user into groups based on permissions he has. Will it be ok if a user will be associated with 100-150 SignalR groups. If true it will be a problem because it's more favourable to send out the whole bunch of data to a user in one message rather than splitting it into 100-150 messages which are sent more efficiently via groups.
Thank you in advance!
Upvotes: 4
Views: 1025
Reputation: 18402
Your understanding re connection handling is correct; SignalR will handle each client connection individually and sequentially. Since it's HTTP-based, it can't multicast.
So in many cases, there won't be a big performance penalty when looping over a list of clients compared to using Clients.All
or Clients.Group(name)
. Groups are mainly a matter of convenience, so using your own implementation for addressing a subset of clients should be fine.
One difference is that if you're addressing each client individually, the data will get serialized each time, which might be relevant especially if you're sending the same data with a lot of records to a lot of users. So, depending on how many users you typically send to and how long the data takes to serialize, you may be better off using groups. If the data is unique per user and there's typically only one connection per user, then obviously it won't make a difference.
Upvotes: 1