public void SessionClosed(int ClosedByErrorCode)
        {
            if (questProcessor != null)
            {
                questProcessor.SessionClosed(ClosedByErrorCode);
            }

            RTMControlCenter.UnregisterSession(connectionId);
        }
        public Answer Kickout(Int64 connectionId, string endpoint, Quest quest)
        {
            RTMControlCenter.CloseSession(connectionId);

            if (questProcessor != null)
            {
                questProcessor.Kickout();
            }

            return(null);
        }
        public Answer Kickout(Int64 connectionId, string endpoint, Quest quest)
        {
            bool closed = RTMControlCenter.GetClientStatus(connectionId) == RTMClient.ClientStatus.Closed;

            RTMControlCenter.CloseSession(connectionId);

            if (questProcessor != null && closed == false)
            {
                questProcessor.Kickout();
            }

            return(null);
        }
Beispiel #4
0
        private void AuthFinish(bool authStatus, int errorCode)
        {
            AuthStatusInfo currInfo;
            TCPClient      client       = null;
            long           connectionId = 0;
            long           currUid;

            lock (interLocker)
            {
                if (status != ClientStatus.Connecting)
                {
                    return;
                }

                if (authStatus)
                {
                    status = ClientStatus.Connected;
                    authStatsInfo.rtmClients.Remove(rtmGate);
                }
                else
                {
                    status              = ClientStatus.Closed;
                    connectionId        = rtmGateConnectionId;
                    rtmGateConnectionId = 0;
                    client              = rtmGate;
                    rtmGate             = null;
                }

                currInfo      = authStatsInfo;
                authStatsInfo = null;
                currUid       = uid;

                syncConnectingEvent.Set();
            }

            if (currInfo != null)
            {
                currInfo.authCallback(pid, currUid, authStatus, errorCode);
            }

            if (connectionId != 0)
            {
                RTMControlCenter.UnregisterSession(connectionId);
            }

            if (client != null)
            {
                client.Close();
            }
        }
        public bool ReloginWillStart(int lastErrorCode, int retriedCount)
        {
            bool startRelogin = true;

            if (questProcessor != null)
            {
                startRelogin = questProcessor.ReloginWillStart(lastErrorCode, retriedCount);
            }

            if (startRelogin)       //-- if startRelogin == false, will call SessionClosed(), the UnregisterSession() will be called in SessionClosed().
            {
                RTMControlCenter.UnregisterSession(connectionId);
            }

            return(startRelogin);
        }
Beispiel #6
0
        private void RedirectToNewRtmGate(string endpoint, bool addressConverted)
        {
            TCPClient client = TCPClient.Create(endpoint, false);

            lock (interLocker)
            {
                rtmGate = client;
                authStatsInfo.rtmClients.Add(client);
            }
            ConfigRtmGateClient(client, (Int64 connectionId, string rtmGateEndpoint, bool connected) => {
                if (requireClose)
                {
                    AuthFinish(false, fpnn.ErrorCode.FPNN_EC_CORE_CONNECTION_CLOSED);
                    return;
                }

                if (connected)
                {
                    rtmGateConnectionId          = connectionId;
                    lastAvailableRtmGateEndpoint = endpoint;
                    RTMControlCenter.RegisterSession(rtmGateConnectionId, this);
                    Auth();
                }
                else
                {
                    if (addressConverted)
                    {
                        AuthFinish(false, fpnn.ErrorCode.FPNN_EC_CORE_INVALID_CONNECTION);
                        return;
                    }

                    if (!AdjustAuthRemainedTimeout())
                    {
                        return;
                    }


                    if (!ConvertIPv4EndpointToIPv6IPPort(endpoint, out string ipv6, out int port))
                    {
                        AuthFinish(false, fpnn.ErrorCode.FPNN_EC_CORE_INVALID_CONNECTION);
                        return;
                    }

                    RedirectToNewRtmGate(ipv6 + ":" + port, true);
                }
Beispiel #7
0
        //-------------[ Relogin interfaces ]--------------------------//
        private void StartNextRelogin()
        {
            if (autoReloginInfo.reloginCount <= regressiveStrategy.startConnectFailedCount)
            {
                StartRelogin();
                return;
            }

            int  regressiveCount = autoReloginInfo.reloginCount - regressiveStrategy.startConnectFailedCount;
            long interval        = regressiveStrategy.maxIntervalSeconds * 1000;

            if (regressiveCount < regressiveStrategy.linearRegressiveCount)
            {
                interval = interval * regressiveCount / regressiveStrategy.linearRegressiveCount;
            }

            RTMControlCenter.DelayRelogin(this, ClientEngine.GetCurrentMilliseconds() + interval);
        }
        private int SendFileWithClient(SendFileInfo info, TCPClient client)
        {
            UpdateTimeout(ref info.remainTimeout, ref info.lastActionTimestamp);
            if (info.remainTimeout <= 0)
            {
                return(fpnn.ErrorCode.FPNN_EC_CORE_TIMEOUT);
            }

            long  messageId = 0;
            Quest quest     = BuildSendFileQuest(out messageId, info);
            bool  success   = client.SendQuest(quest, (Answer answer, int errorCode) => {
                if (errorCode == fpnn.ErrorCode.FPNN_EC_OK)
                {
                    try
                    {
                        //-- long mtime = answer.Want<long>("mtime");
                        info.callback(messageId, fpnn.ErrorCode.FPNN_EC_OK);

                        RTMControlCenter.ActiveFileGateClient(info.endpoint, client);
                        return;
                    }
                    catch (Exception)
                    {
                        errorCode = fpnn.ErrorCode.FPNN_EC_CORE_INVALID_PACKAGE;
                    }
                }

                info.callback(0, errorCode);
            }, info.remainTimeout);

            if (success)
            {
                return(fpnn.ErrorCode.FPNN_EC_OK);
            }
            else
            {
                return(fpnn.ErrorCode.FPNN_EC_CORE_INVALID_CONNECTION);
            }
        }
        private static void CheckRoutineInit()
        {
            if (routineInited)
            {
                return;
            }

            lock (interLocker)
            {
                if (routineInited)
                {
                    return;
                }

                routineRunning = true;

                routineThread = new Thread(RoutineFunc)
                {
                    Name = "RTM.ControlCenter.RoutineThread",
#if UNITY_2017_1_OR_NEWER
#else
                    IsBackground = true
#endif
                };
                routineThread.Start();


                routineInited = true;
            }

#if UNITY_2017_1_OR_NEWER
            Application.quitting += () => {
                RTMControlCenter.Close();
            };
#endif
        }
Beispiel #10
0
        private void ParallelConnectToRtmGate(string endpoint, ParallelLoginStatusInfo info)
        {
            if (!AdjustAuthRemainedTimeout(info))
            {
                DecreaseParallelConnectingCount();
                return;
            }

            TCPClient client = TCPClient.Create(endpoint, false);

            lock (interLocker)
            {
                if (status != ClientStatus.Connecting)
                {
                    return;
                }

                authStatsInfo.rtmClients.Add(client);
            }
            ConfigRtmGateClient(client, (Int64 connectionId, string rtmGateEndpoint, bool connected) => {
                if (requireClose)
                {
                    DecreaseParallelConnectingCount();
                    return;
                }

                if (connected)
                {
                    lock (interLocker)
                    {
                        if (status != ClientStatus.Connecting)
                        {
                            return;
                        }

                        authStatsInfo.parallelConnectingCount -= 1;
                        if (authStatsInfo.parallelCompleted)
                        {
                            return;
                        }

                        authStatsInfo.parallelCompleted       = true;
                        authStatsInfo.remainedTimeout         = info.remainedTimeout;
                        authStatsInfo.lastActionMsecTimeStamp = info.lastActionMsecTimeStamp;

                        rtmGate = client;
                    }

                    rtmGateConnectionId          = connectionId;
                    lastAvailableRtmGateEndpoint = endpoint;
                    RTMControlCenter.RegisterSession(rtmGateConnectionId, this);
                    Auth();
                }
                else
                {
                    DecreaseParallelConnectingCount();
                }
            }, info.remainedTimeout);
            client.AsyncConnect();

            if (requireClose)
            {
                client.Close();
            }
        }
 static void NetworkStatusCallback(int networkStatus)
 {
     RTMControlCenter.NetworkChanged((NetworkType)networkStatus);
 }
Beispiel #12
0
        private void DispatchCallBack_Which_IPv4(Answer answer, int errorCode)
        {
            if (requireClose)
            {
                AuthFinish(false, fpnn.ErrorCode.FPNN_EC_CORE_CONNECTION_CLOSED);
                return;
            }

            if (errorCode == fpnn.ErrorCode.FPNN_EC_OK)
            {
                if (!AdjustAuthRemainedTimeout())
                {
                    return;
                }

                string ipv4endpoint = answer.Get <string>("endpoint", string.Empty);
                if (ipv4endpoint.Length > 0)
                {
                    TCPClient client = TCPClient.Create(ipv4endpoint, false);
                    lock (interLocker)
                    {
                        rtmGate = client;
                        authStatsInfo.rtmClients.Add(client);
                    }
                    ConfigRtmGateClient(client, (Int64 connectionId, string endpoint, bool connected) => {
                        if (requireClose)
                        {
                            AuthFinish(false, fpnn.ErrorCode.FPNN_EC_CORE_CONNECTION_CLOSED);
                            return;
                        }

                        if (connected)
                        {
                            rtmGateConnectionId          = connectionId;
                            lastAvailableRtmGateEndpoint = ipv4endpoint;
                            RTMControlCenter.RegisterSession(rtmGateConnectionId, this);
                            Auth();
                        }
                        else
                        {
                            if (!AdjustAuthRemainedTimeout())
                            {
                                return;
                            }

                            StartParallelConnect(ipv4endpoint);
                        }
                    }, authStatsInfo.remainedTimeout);
                    client.AsyncConnect();

                    if (requireClose)
                    {
                        client.Close();
                    }
                    return;
                }
                else
                {
                    StartParallelConnect(string.Empty);
                }
            }
            else
            {
                AuthFinish(false, errorCode);
            }
        }
        //-------------[ Auth(Login) processing functions ]--------------------------//
        private void AuthFinish(bool authStatus, int errorCode)
        {
            AuthStatusInfo currInfo;
            long           currUid;
            bool           isRelogin = false;
            Int64          reservedRtmGateConnectionId = 0;

            lock (interLocker)
            {
                if (status != ClientStatus.Connecting)
                {
                    return;
                }

                if (authStatus)
                {
                    status = ClientStatus.Connected;
                }
                else
                {
                    status = ClientStatus.Closed;
                    reservedRtmGateConnectionId = rtmGateConnectionId;
                    rtmGateConnectionId         = 0;
                    //-- Reserving rtmGate without closing for quick relogin.
                }

                if (autoReloginInfo != null)
                {
                    isRelogin = autoReloginInfo.canRelogin;

                    if (authStatsInfo != null)
                    {
                        autoReloginInfo.token = authStatsInfo.token;
                        autoReloginInfo.attr  = authStatsInfo.attr;
                        autoReloginInfo.lang  = authStatsInfo.lang;
                    }

                    if (authStatus && !autoReloginInfo.canRelogin)
                    {
                        autoReloginInfo.LoginSuccessful();
                    }
                }

                currInfo      = authStatsInfo;
                authStatsInfo = null;
                currUid       = uid;

                syncConnectingEvent.Set();
            }

            if (reservedRtmGateConnectionId != 0)
            {
                RTMControlCenter.UnregisterSession(reservedRtmGateConnectionId);
            }

            if (currInfo != null)
            {
                foreach (AuthDelegate callback in currInfo.authDelegates)
                {
                    callback(projectId, currUid, authStatus, errorCode);
                }
            }

            if (authStatus)
            {
                processor.BeginCheckPingInterval();
            }
        }
        private void BuildRtmGateClient(string originalEndpoint)
        {
            rtmGate = TCPClient.Create(adjustEndpoint(originalEndpoint), true);

            if (errorRecorder != null)
            {
                rtmGate.SetErrorRecorder(errorRecorder);
            }

            rtmGate.SetQuestProcessor(processor);
            rtmGate.SetConnectionConnectedDelegate((Int64 connectionId, string endpoint, bool connected) => {
                if (requireClose)
                {
                    AuthFinish(false, fpnn.ErrorCode.FPNN_EC_CORE_CONNECTION_CLOSED);
                    return;
                }

                if (connected)
                {
                    rtmGateConnectionId = connectionId;
                    RTMControlCenter.RegisterSession(rtmGateConnectionId, this);
                    Auth(true);
                }
                else
                {
                    AuthFinish(false, fpnn.ErrorCode.FPNN_EC_CORE_INVALID_CONNECTION);
                }
            });

            rtmGate.SetConnectionCloseDelegate((Int64 connectionId, string endpoint, bool causedByError) => {
                bool trigger      = false;
                bool isConnecting = false;
                bool startRelogin = false;
                lock (interLocker)
                {
                    trigger = rtmGateConnectionId == connectionId;
                    if (trigger)
                    {
                        if (status == ClientStatus.Connecting)
                        {
                            isConnecting = true;
                        }
                        else
                        {
                            status = ClientStatus.Closed;
                        }
                    }

                    if (autoReloginInfo != null)
                    {
                        startRelogin = (autoReloginInfo.disabled == false && autoReloginInfo.canRelogin);
                        autoReloginInfo.lastErrorCode = (causedByError ? fpnn.ErrorCode.FPNN_EC_CORE_CONNECTION_CLOSED : fpnn.ErrorCode.FPNN_EC_OK);
                    }
                }

                if (trigger)
                {
                    if (isConnecting)
                    {
                        AuthFinish(false, fpnn.ErrorCode.FPNN_EC_CORE_INVALID_CONNECTION);
                    }
                    else
                    {
                        if (startRelogin)
                        {
                            StartRelogin();
                        }
                        else
                        {
                            processor.SessionClosed(causedByError ? fpnn.ErrorCode.FPNN_EC_CORE_UNKNOWN_ERROR : fpnn.ErrorCode.FPNN_EC_OK);
                        }
                    }
                }
            });
        }
Beispiel #15
0
        private bool Login(AuthDelegate callback, string token, Dictionary <string, string> attr, string lang = "", int timeout = 0)
        {
            lock (interLocker)
            {
                if (status == ClientStatus.Connected)
                {
                    ClientEngine.RunTask(() =>
                    {
                        callback(projectId, uid, true, fpnn.ErrorCode.FPNN_EC_OK);
                    });

                    return(true);
                }

                if (status == ClientStatus.Connecting)
                {
                    authStatsInfo.authDelegates.Add(callback);
                    return(true);
                }

                status = ClientStatus.Connecting;
                syncConnectingEvent.Reset();

                requireClose = false;

                if (autoReloginInfo != null)
                {
                    autoReloginInfo.Login();
                }
            }

            authStatsInfo = new AuthStatusInfo
            {
                authDelegates = new HashSet <AuthDelegate>()
                {
                    callback
                },
                remainedTimeout = timeout,
            };

            authStatsInfo.token = token;
            authStatsInfo.attr  = attr;
            authStatsInfo.lang  = lang;
            authStatsInfo.lastActionMsecTimeStamp = ClientEngine.GetCurrentMilliseconds();

            if (rtmGate.IsConnected())
            {
                if (authStatsInfo.remainedTimeout == 0)
                {
                    authStatsInfo.remainedTimeout = RTMConfig.globalQuestTimeoutSeconds;
                }

                RTMControlCenter.RegisterSession(rtmGateConnectionId, this);
                Auth(false);
            }
            else
            {
                if (authStatsInfo.remainedTimeout == 0)
                {
                    authStatsInfo.remainedTimeout = ((ConnectTimeout == 0) ? RTMConfig.globalConnectTimeoutSeconds : ConnectTimeout)
                                                    + ((QuestTimeout == 0) ? RTMConfig.globalQuestTimeoutSeconds : QuestTimeout);
                }

                rtmGate.AsyncConnect();
            }

            return(true);
        }