Lu4
Lu4

Reputation: 15032

Sending data to individual clients instead of using Clients.All in SignalR

Abstract

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.

Example

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.

The problem (Permissions cause data scattering among users)

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:

The question

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!

Model diagram

Here is the link to an image

Image description

Upvotes: 4

Views: 1025

Answers (1)

Lars Höppner
Lars Höppner

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

Related Questions