public async Task CreateOrJoinGame(string gameId, string userId, string userName) { if (string.IsNullOrEmpty(gameId) || string.IsNullOrEmpty(userId)) { throw new Exception("GroupId or user is empty"); } Log.Logger.LogInformation($"User {userId} requesting to join game {gameId}"); GameTableEntity game = GameTable.GetGameObject(gameId); if (game == null) { // Join game as admin game = await GameTable.CreateGame(gameId, userId, userName); } else { // If game has ended or started, there's no join (spectator mode) if (!game.GameEnded && !game.GameStarted) { await GameTable.AddUserToGame(userId, userName, game); } } this.SetGameMetadata(userId, gameId); // Add to group and update game metadata for everyone and send notification await Groups.AddToGroupAsync(Context.ConnectionId, gameId); await Clients.Group(gameId).SendAsync("GameMetadataUpdate", JsonConvert.SerializeObject(game)); await Clients.Group(gameId).SendAsync("PlayerJoined", userId); }