Search code examples
signalrsignalr-hubsignalr.clientsignalr-2

SignalR needs to target specific games with Game ID and not all live games


I didnt think about this but this code is sending the game model to all clients. I need to use the GameID from this controller action and only target the clients watching that game. How do I do that?

Publish Controller Action

public UpdateGameResponse UpdateGame(int gameId)
        {

...

 var model = Game.Create(XDocument.Load(httpRequest.Files[0].InputStream)).Parse();


         GlobalHost.ConnectionManager.GetHubContext<GameCastHub>().Clients.All.receiveUpdates(Newtonsoft.Json.JsonConvert.SerializeObject(model));

}

Hub

 [HubName("gamecastHub")]
    public class GameCastHub : Hub
    {
    }

Client

  var connected = false;
                var gamecastHub = $.connection.gamecastHub;

                if (gamecastHub) {

                    gamecastHub.client.receiveUpdates = function (updates) {
                        console.log('New updates received');
                        processUpdates(updates);
                    };

                    connectLiveUpdates();

                    $.connection.hub.connectionSlow(function () {
                        console.log('Live updates connection running slow');
                    });

                    $.connection.hub.disconnected(function () {
                        connected = false;
                        console.log('Live updates disconnected');
                        setTimeout(connectLiveUpdates, 10000);
                    });

                    $.connection.hub.reconnecting(function () {
                        console.log('Live updates reconnecting...');
                    });

                    $.connection.hub.reconnected(function () {
                        connected = false;
                        console.log('Live updates reconnected');
                    });
                }

Solution

  • I suggest using either the connection Id associated with each connection to the hub or creating groups. Note: Each GameID must have its own connection to the hub in order to use the connection Id solution.

    I prefer to use groups from personal experience but either way can be done.

    To create a group in the hub you will need to create a method in your hub class.

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

    Secondly, you will need a JS function on the client side to call the hub function.

    $.connection.hub.invoke("setGroup", groupName).catch(err => console.error(err.toString()));
    

    In your case, you can place your gameID as the groupname and then call GlobalHost.ConnectionManager.GetHubContext<GameCastHub>().Clients.Groups(gameID).receiveUpdates(Newtonsoft.Json.JsonConvert.SerializeObject(model));

    To retrieve the connection Id:

    var _connectionId = $.connection.hub.id;
    

    Then send the connection Id to the server, and proceed to using the call GlobalHost.ConnectionManager.GetHubContext<GameCastHub>().Clients.Clients.Client(_connectionId).receiveUpdates(Newtonsoft.Json.JsonConvert.SerializeObject(model)); to call that specific connection.