public async Task HubMessage(string json)
        {
            var lobby = _lobbys.GetLobbyByConnectionId(ConnectionId);

            if (lobby != null && lobby.CurrentGame != null)
            {
                var message = JObject.Parse(json);

                var system = message["system"];
                var admin  = message["admin"];
                var client = message["client"];

                try
                {
                    if (system != null)
                    {
                        _logger.Debug($"system: {system}");
                        await lobby.CurrentGame.OnReceiveSystemMessage(system, ConnectionId);
                    }

                    if (admin != null && _lobbys.PlayerIsPresenter(ConnectionId))
                    {
                        _logger.Debug($"admin: {admin.ToString(Formatting.None)}");
                        await lobby.CurrentGame.OnReceivePresenterMessage(admin, ConnectionId);
                    }

                    if (client != null)
                    {
                        _logger.Debug($"client: {client.ToString(Formatting.None)}");
                        await lobby.CurrentGame.OnReceivePlayerMessage(client, ConnectionId);
                    }
                }
                catch (Exception e)
                {
                    // TODO: this occurs because a presenter is sending a message to a game that
                    // hasn't yet been selected. Race condition during EndToEndTests
                    _logger.Error(e.Message);
                }
            }
        }