Search code examples
c#signalrsignalr-hub

Communication between different SignalR hubs?


I'm trying to make a game that uses a similar setup to Jackbox games. It basically means that you have a host client that mobile clients can access by going to https://jackbox.tv and put in a room code + a player name. No downloads required on the phone.

Here is my setup:

  • Unity Host Client - Will be used to establish a room. (C#, .NET 2.0 Standard)
  • React Native Player Client - Is what players will use to interact with the game. (JavaScript, Expo)
  • Server Client - A server that will link games and players together using SignalR as the backend technology. (C#, .NET 5)

The problem I have right now is that I don't quite know how to make my two hubs talk to each other. The two hubs are:

  • HostHub - This is where the Unity Clients connect so the server knows what games are available and with what players.
  • GameHub - This is where the Player Clients connect and will be assigned to rooms.

I have a Singleton instance of a ServerManager on the Server Client which is used to save Game and Player objects as well as retrieving them (I will add proper persistence management later).

So when I try to use C# events like this in my Host- or GameHub:

...
ServerManager.Instance.OnPlayerJoinedRoom += ServerManager_OnPlayerJoinedRoom;
...

private void ServerManager_OnPlayerJoinedRoom(object sender, (string, string, string) info)
{
    IClientProxy host = Clients.Client(info.Item1);
    host.SendAsync("PlayerJoined", Extensions.ParamArray(info.Item2, info.Item3));
}

I get an error that says Clients is Disposed so I can't access it. I found out this is because these are very light objects that have a very short lifespan before they are disposed of, by design.

So what else can I do to make Hubs communicate with each other or is this just not the approach for SignalR?


Solution

  • Register multiple endpoints in OWIN startup:

    app.UseEndpoints(ep => { ep.MapHub<HostHub>("/hostHub"); ep.MapHub<GameHub>("/gameHub"); }
    

    Then in your client (ie: JavaScript) just connect with the desired endpoint:

    var conn = new signalR.HubConnectionBuilder().withUrl('https://localhost:5000/gameHub');
    

    All hubs share the same "/signalr" endpoint