public void StartConnection(UdpSession session, ClientConnectionToken token, Action onConnectSuccess, Action <ClientConnectFailReason> onConnectFail)
        {
            StopAllCoroutines();

            networkingMode = NetworkingMode.Client;
            state          = State.Connecting;
            token.Version  = Version;

            StartCoroutine(ConnectClientRoutine(session, token, onConnectSuccess, onConnectFail));
        }
        private IEnumerator ConnectClientRoutine(UdpSession session, ClientConnectionToken token, Action onConnectSuccess, Action <ClientConnectFailReason> onConnectFail)
        {
            if (BoltNetwork.IsRunning && !BoltNetwork.IsClient)
            {
                BoltLauncher.Shutdown();

                yield return(new WaitUntil(NetworkIsInactive));
            }

            if (!BoltNetwork.IsClient)
            {
                state = State.Starting;

                BoltLauncher.StartClient();
                yield return(new WaitUntil(NetworkIsIdle));
            }

            if (!BoltNetwork.IsClient)
            {
                onConnectFail?.Invoke(ClientConnectFailReason.FailedToConnectToMaster);
                yield break;
            }

            state = State.Connecting;
            connectionAttemptInfo.Reset();
            BoltNetwork.Connect(session, token);

            while (true)
            {
                connectionAttemptInfo.TimeSinceAttempt += Time.deltaTime;

                if (connectionAttemptInfo.TimeSinceAttempt > MaxConnectionAttemptTime)
                {
                    onConnectFail?.Invoke(ClientConnectFailReason.ConnectionTimeout);

                    state = BoltNetwork.IsRunning ? State.Active : State.Inactive;

                    yield break;
                }

                if (connectionAttemptInfo.IsRefused)
                {
                    onConnectFail?.Invoke(connectionAttemptInfo.RefuseReason.ToConnectFailReason());
                    yield break;
                }

                if (connectionAttemptInfo.IsFailed)
                {
                    onConnectFail?.Invoke(ClientConnectFailReason.FailedToConnectToSession);
                    yield break;
                }

                if (connectionAttemptInfo.IsConnected)
                {
                    onConnectSuccess?.Invoke();
                    yield break;
                }

                yield return(null);
            }
        }
 public void StartConnection(UdpSession session, ClientConnectionToken token, Action onConnectSuccess, Action <ClientConnectFailReason> onConnectFail)
 {
     underlyingController.StartConnection(session, token, onConnectSuccess, onConnectFail);
 }