Search code examples
signalrsignalr-hubsignalr.clientasp.net-core-signalr

Pushing message to groups in SignalR


Just trying to wrap my mind around handling pushing data to some users through SignalR.

Say, in a private chat situation, Person A sends a message to Person B. If I'm understanding the concept correctly, I need to create a Group for each user who logged into the system. This way, when the new message from Person A comes in, in my SignalR Hub, I'd send the message to the group for Person B which only has only one user in it i.e. Person B.

In this approach, I'd essentially create a unique Group for each user so that I have the flexibility to push data to each unique user. I could use the UserId as the Group Id.

Is this the way to handle pushing data selectively to each unique user?


Solution

  • You can grab client Ids manully like so and then send them using the hubcontext to avoid creating a lot of groups (you just need to implement a menthod which get you're connections from your resource in my case im using dtos)

    I'm assuming your hubs have some type of connection manager, here's a sample of one from the docs

    In my case I have a dynamic configuration which I use to configure my hubs using the Type of DTO, and I send hubs using a generic hub base here is a sample implementation:

    Warning: things may slightly be different I'm using .Net-Core in this example

    //NOTE: THub must be the one Registered with MapHubs in the Startup 
    //class or your connections won't be there because Hubs are not contravarient
    public abstract class HubBase<TDTO, THub> : Hub
        Where THub: HubBase<TDTO, THub>
    {
        protected IHubContext<THub> hubContext;
        HubBase(IHubContext<THub> hubContext)
        {
           this._hubContext = hubContext;
        }
    
        protected abstract List<string> GetConnectionsByDto(TDTO dto)
    
        protected async Task SendFilteredAsync(string eventName, TDTO dto)
        {
            var clientIds = await this.GetConnectionsByDto(dto);
    
            if (false == clientIds.Any())
            {
                return;
            }
    
            var broadcastTasks = clientIds.Select(async clientId =>
                                        await this._hubContext.Clients.Client(clientId).SendAsync(eventName, dto));
    
            await Task.WhenAll(broadcastTasks);
        }
    }