Search code examples
c#asp.net-coresignalrsignalr-hubasp.net-core-signalr

Using a base class in SignalR


Using SignalR, I have the following Hub classes below and here I want to collect shared methods in a Base Hub class:


HubBase

public class HubBase : Hub
{
    public readonly static ConnectionMapping<string> _connections =
        new ConnectionMapping<string>();

    public override Task OnConnected()
        string name = Context.User.Identity.Name;
        _connections.Add(name, Context.ConnectionId);
        return base.OnConnected();
    }

    public override Task OnDisconnected(bool stopCalled)
    {
        string name = Context.User.Identity.Name;
        _connections.Remove(name, Context.ConnectionId);
        return base.OnDisconnected(stopCalled);
    }

    public override Task OnReconnected()
    {
        string name = Context.User.Identity.Name;
        if (!_connections.GetConnections(name).Contains(Context.ConnectionId))
        {
            _connections.Add(name, Context.ConnectionId);
        }
        return base.OnReconnected();
    }


    public void SendChatMessage(string who, string message)
    {
        string name = Context.User.Identity.Name;
        foreach (var connectionId in _connections.GetConnections(who))
        {
            Clients.Client(connectionId).addChatMessage(name + ": " + message);
        }
    }
}


StockHub

public class StockHub : HubBase
{
    private static IHubContext context = GlobalHost
       .ConnectionManager.GetHubContext<StockHub>();

    public static void SendStockData(object data) {
        context.Clients.All.sendStockData(data);
    }
}


StockHub

public class ChatHub : HubBase
{
    private static IHubContext context = GlobalHost
       .ConnectionManager.GetHubContext<ChatHub>();

    public static void SendMessage(string message) {
        context.Clients.All.sendMessage(message);
    }
}


My questions are:

1- As the HubBase is inherited by Stock and Chat hub classes, I think all the connected clients to one of those methods will be added connected users in the HubBase. So, when I broadcast data to the clients who connected to StockHub, I will also broadcast data to the other clients who connected to ChatHub. Is that true?

2- How can I fix this problem without defining all the connection classes in Stock and Chat hub instead of Base hub (HubBase)?

As it is not logical to define these shared methods for all of the hub classes, I need to discriminate the user who connect to StockHub. How can I do this?

3- In addition to that, I am wondering what if I do not use none of these connection methods and any base class (define each hub classes separately with no relation), and use Clients.All method in order to broadcast data, in this case will the broadcast only goes only to the clients who connected my hub? If so, for this scenario there is no need to use connection methods (assuming that I broadcast to all of the clients connected to StockHub). Is that true?


Solution

  • SignalR allows messages to be sent to all connections associated with a specific user, as well as to named groups of connections.

    Groups in SignalR : it is manages the Users and Groups for you which associated with Hub

    public async Task AddToGroup(string groupName)
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
    
        await Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId} has joined the group {groupName}.");
    }
    
    public async Task RemoveFromGroup(string groupName)
    {
        await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
    
        await Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId} has left the group {groupName}.");
    }
    

    read more about here

    Hope it helps you.