void SendMatchRequest(string mmServiceURL, CancellationToken token = default)
        {
            OnStateChanged(MatchmakingState.Matchmaking);

            // Merge cancellation token w/ timeout
            if (matchmakingTimeoutMs > 0)
            {
                var timeoutCts = new CancellationTokenSource((int)matchmakingTimeoutMs);
                m_MatchCts = CancellationTokenSource.CreateLinkedTokenSource(token, timeoutCts.Token);
            }

            m_Matchmaking = new MatchmakingWrapper(mmServiceURL);

            //TODO Do we get more server info than the IP?
            m_Matchmaking.Start(serverEndpoint =>
            {
                if (string.IsNullOrEmpty(serverEndpoint))
                {
                    Debug.LogError("Matchmaking Failed - No server connection information returned");
                    OnStateChanged(MatchmakingState.Idle);
                    return;
                }

                // Success!
                GotServerEndpoint(serverEndpoint);
                OnStateChanged(MatchmakingState.Idle);
            }, token);
        }
        IEnumerator DoMatchmakingAsync()
        {
            // Create timeout cancellation token
            var token = CancellationToken.None;

            if (MatchmakingTimeoutMs > 0)
            {
                token = new CancellationTokenSource((int)MatchmakingTimeoutMs).Token;
            }

            var matchmaking = new MatchmakingWrapper(m_MatchmakingServer);

            yield return(matchmaking.StartEnumerator(serverEndpoint =>
            {
                if (string.IsNullOrEmpty(serverEndpoint))
                {
                    Debug.Log("Matchmaking failed, aborting headless run and shutting down ping client.");
                    ShutDown(ExitCode.Error);
                }

                // Success!
                m_CustomIp = serverEndpoint;
            }, token));
        }