0

I have BaseHub class that is inheriting Hub class. I overrode OnConnected and OnDisconnected methods, and they are working properly, when client and server are connected, ConnectionId is saved inside group.

public class BaseHub : Hub
{
    private readonly string _defaultGroupName = "HubUsers";

    public async Task BroadcastMessage(string methodName, params object[] parameters)
    {
        await Clients.All.SendAsync(methodName, parameters);
    }

    public async Task AddUserToGroup(string groupName)
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
    }

    public async Task RemoveUserFromGroup(string groupName)
    {
        await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
    }

    public override async Task OnConnectedAsync()
    {
        await AddUserToGroup(_defaultGroupName);
        await base.OnConnectedAsync();
    }

    public override async Task OnDisconnectedAsync(Exception exception)
    {
        await RemoveUserFromGroup(_defaultGroupName);
        await base.OnDisconnectedAsync(exception);
    }
}

When I call BroadcastMessage, my Clients is always null, thus I get exception. When I tried to call await Clients.All.SendAsync(methodName, parameters); directly inside OnConnected, Clients object was valid and my client side method was invoked. I even tried using protected IHubContext<BaseHub> _context;, then I have _context object, but 0 users insite Clients/ Groups.

BaseHub is parent class of VotingHub where I am calling BroadcastMessage

public async Task ShareResult(Guid result)
    {
        await BroadcastMessage(_receiveResult, new[] { result });
    }
Serlok
  • 432
  • 1
  • 10
  • 24
  • Similar to https://stackoverflow.com/questions/47465481/signalr-hubs-clients-are-null-when-firing-event but I've done something like this in my solution `GlobalHost.ConnectionManager.GetHubContext()`? – Alan Cheung Dec 29 '20 at 16:59
  • What exactly is null? There is no `Client`? Do you mean `Clients`? Where does the hub come from, where is it constructed? What calls `ShareResult`? Where does `_receiveResult` come from? – poke Dec 29 '20 at 19:36
  • @AlanCheung I tried with context, then I don't have connections at clients at all, but I am not sure if I registered it as transient, I will check – Serlok Dec 30 '20 at 07:20
  • @poke Yes `Clients`, my bad, Hub is registered in startup, hub is connected with FE, that part is okay, I tested it. `ShareResult` is called inside service, and `_receiveResult` is string constant that I am using as method name – Serlok Dec 30 '20 at 07:22
  • _“ShareResult is called inside service”_ – So you call this method from outside of a hub method? That won’t work. Hubs are only for _receiving_ from clients. If you want to call clients from elsewhere (e.g. MVC actions), [you will need a `IHubContext`](https://learn.microsoft.com/en-us/aspnet/core/signalr/hubcontext?view=aspnetcore-5.0). – poke Dec 30 '20 at 13:00
  • @poke true, I found that on documentation, but I didn't know that hubs are only for receiving from client, so basically I need to create helper that will allow me to send to client using IHubClient ? – Serlok Dec 30 '20 at 15:18
  • If you want to send something to clients (outside of the context of a hub action), you will need to inject a hub context via DI. – poke Dec 31 '20 at 00:29
  • @poke but can I send to clients inside Hub? I am confused now because u stated `Hubs are only for receiving from clients.`, so to be clear, can I use hub to sent to clients or only to receive from them? – Serlok Dec 31 '20 at 08:48
  • 1
    Hubs are like controllers in that they the entry point when receiving messages (like actions receive HTTP requests). If you are within the hub flow, you *can* send messages to your clients. If you are not within the hub flow however, e.g. when you received a HTTP request inside a controller action, then you will need a hub context to send messages out. – poke Dec 31 '20 at 12:08

0 Answers0