Notifications with SignalR

2

I want to create a notification system in my web app (MVC) using SignalR 2.

When someone in the app does a certain action some users (not all and not always the same) should be notified. Something similar to what we have here in the OS when someone interacts with a question. My question is this:

What would be a better strategy for sending the message to customers?

Should I store the connectionId and then return this value to who should be notified? This way the database would return the connectionId list of users that should be notified after the action.

I'm new to this and I do not know how to adapt to my business.

    
asked by anonymous 02.02.2017 / 20:11

1 answer

1

An interesting way to send notification to specific users is to use groups. For each type of notification, you create groups for each item and connect the necessary clients to those groups. A simple example:

public class MeuHub : Hub
{
    public Task EntraNoGrupo(string grupoId)
    {
        return Groups.Add(Context.ConnectionId, grupoId);
    }

    public Task SaiDoGrupo(string grupoId)
    {
        return Groups.Remove(Context.ConnectionId, grupoId);
    }

    public void NotificaGrupo(string grupoId, string mensagem)
    {
        Clients.Group(grupoId).algumMetodoNosClientes(mensagem);
    }

} 

To connect a client to a group, simply invoke the EntraNoGrupo method of your client, passing the id of that group:

hubProxy.invoke('EntraNoGrupo', '453841'); // o Id do grupo

That is, the EntraNoGrupo method is only one way for the client to be able to join a group, and this method must be called on all clients in that group.

  

For more details, read the documentation about SignalR Groups .

Now, about linking a connectionId to a user, there are a few ways you can do this, one of which you've already mentioned. To decide which is best for your scenario, see the following table:

YouareinEnglishbutIbelieveyoucanunderstand.

Single-userGroups

Foryourparticularscenario,theSingle-userGroupsoptionisnolongerpossiblebecauseitsuggeststhatyoucreateagroupforeachuser,howeverthiswillremovethepossibilityforyoutonotifydifferentclientsinthesamegroup.

InMemory

Thisismorefortrivialnotificationsandevenforthosejuststartingtoseehowitworks.Itdisruptsscalability,becausebypersistingallinservermemory,ifyouhaveafarmenvironment,eachserverhasitsownmemory,andfromtherewemayhaveproblems.Itmaynotevenbeyourcaseatthemoment,butit'salwaysinterestingtobuildthingsintothefuture(yourapplicationcangrow).

UserIDProvider

Thisissimilarto"in memory", however it supports farm environment because it makes use of cookies on the client, allowing different servers to access those cookies from the client. However, in this one the server does not maintain a list of connected users. Since you do not need to send notifications to specific users in a group, that is, the notifications will always be to the whole group (with the option to delete the client that originated the call), that case would be okay. The problem is that if the server restarts or a recycle occurs in the IIS pool, the server (s) loses all the settings of the groups.

External Persistence

This is exactly the example you cited with the database. You persist the group and connection information in a database, and you no longer lose this information after a recycle in the IIS pool, or when the user clears browser cookies, and supports farm. The only down side to this is that having to persist in a database, gets a bit slower to connect and send messages, which could also be solved with distributed caching (in a more robust architecture).

But I would not even think of caching at the first moment. Standard database, will keep the data there, doing tests. If you start having a very high flow of notifications for that particular Hub, then you start thinking about caching.

  

To see more about these connection persistence x user models, see SignalR documentation .

I hope to have clarified your doubts, and that this helps you decide which strategy to adopt for your particular case.

    
07.06.2017 / 06:41