/// <summary>
        /// Fill this HoxisUser with an connected user
        /// </summary>
        /// <param name="handle"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        private bool SignIn(string handle, HoxisProtocolArgs args)
        {
            Ret  ret;
            long uid = FF.StringToLong(args["uid"]);

            if (uid <= 0)
            {
                return(ResponseError(handle, C.RESP_ILLEGAL_ARGUMENT, FF.StringFormat("illegal argument: {0}", args["uid"])));
            }
            userID          = uid;
            connectionState = UserConnectionState.Default;
            if (DebugRecorder.LogEnable(_logger))
            {
                _logger.LogInfo("sign in", "");
            }
            else
            {
                _logger = new DebugRecorder(FF.StringAppend(HoxisServer.basicPath, @"logs\users\", NewUserLogName(uid)), out ret);
                if (ret.code != 0)
                {
                    Console.WriteLine(ret.desc);
                }
                else
                {
                    _logger.Begin();
                    _logger.LogInfo("sign in", "");
                }
            }
            return(ResponseSuccess(handle, "SignInCb"));
        }
 private bool SetDefaultConnectionState(string handle, HoxisProtocolArgs args)
 {
     if (connectionState == UserConnectionState.Active)
     {
         connectionState = UserConnectionState.Default;
         return(ResponseSuccess(handle, "SetDefaultConnectionStateCb"));
     }
     else if (connectionState == UserConnectionState.Default)
     {
         return(Response(handle, "SetDefaultConnectionStateCb", new KVString("code", C.RESP_SET_DEFAULT_ALREADY)));
     }
     return(ResponseError(handle, C.RESP_SET_STATE_UNABLE, FF.StringFormat("current connection state is {0}", connectionState.ToString())));
 }
Esempio n. 3
0
        // Use this for initialization
        void Start()
        {
            HoxisDirector.Ins.onResponseError        += (err, desc) => { LogAffairEntry(FF.StringFormat("response err: {0}, {1}", err, desc), LogLevel.Error); };
            HoxisDirector.Ins.onProtocolEntry        += (proto) => { LogAffairEntry(FF.StringFormat("protocol entry: {0}", FF.ObjectToJson(proto))); };
            HoxisDirector.Ins.onProtocolPost         += (proto) => { LogAffairEntry(FF.StringFormat("protocol post: {0}", FF.ObjectToJson(proto))); };
            HoxisDirector.Ins.onAffairInitError      += (ret) => { LogAffairEntry(ret.desc, LogLevel.Error); };
            HoxisDirector.Ins.onAffairConnected      += () => { LogAffairEntry(FF.StringFormat("connect to {0}", HoxisClient.Ins.serverIP)); };
            HoxisDirector.Ins.onAffairConnectError   += (ret) => { LogAffairEntry(ret.desc, LogLevel.Error); };
            HoxisDirector.Ins.onAffairClosed         += () => { LogAffairEntry("close success"); };
            HoxisDirector.Ins.onAffairClosedError    += (ret) => { LogAffairEntry(ret.desc, LogLevel.Error); };
            HoxisDirector.Ins.onAffairNetworkAnomaly += (ret) => { LogAffairEntry(ret.desc, LogLevel.Error); };

            _logPanel.GetComponent <RectTransform>().localPosition = _logPanelOffPosition;
            _logPanelOn = false;

            HoxisDirector.Ins.AwakeIns();
        }
Esempio n. 4
0
        public void LogTag(string content, string tag = "", string speaker = "", bool console = false)
        {
            string s;

            if (speaker == "")
            {
                s = FF.StringFormat("[{0}]{1}:  {2}", SF.GetDateTime(), tag, content);
            }
            else
            {
                s = FF.StringFormat("[{0}]{1}:  {2}--->{3}", SF.GetDateTime(), tag, speaker, content);
            }
            _writer.WriteLine(s);
            if (console)
            {
                Console.WriteLine(s);
            }
        }
        //public static void TestRelease(HoxisConnection conn) { Ret ret; lock (conn) _connReception.Release(conn, out ret); }

        #region management

        //public static bool ManageCluster(ManageOperation op, HoxisUser sponsor)
        //{
        //    switch (op)
        //    {
        //        case ManageOperation.Create:
        //            string cid = FF.StringAppend(sponsor.userID.ToString(), "@", SF.GetTimeStamp().ToString());
        //            if (_clusters.ContainsKey(cid)) { Console.WriteLine("[error]Create cluster: cluster {0} already exists", cid); return false; }
        //            lock (_clusters)
        //            {
        //                HoxisCluster hc = new HoxisCluster(cid);
        //                _clusters.Add(cid, hc);
        //                Ret ret;
        //                hc.UserJoin(sponsor, out ret);
        //                if (ret.code != 0) { Console.WriteLine("[warning]Create cluster: {0}", ret.desc); return false; }
        //            }
        //            break;
        //        case ManageOperation.Join:
        //            // todo Call matching sdk, get a cluster
        //            break;
        //        case ManageOperation.Leave:

        //            break;
        //        case ManageOperation.Destroy:

        //            break;
        //    }
        //    return true;
        //}

        #endregion

        private void ProcessAffair(object state)
        {
            KV <int, object> affair = (KV <int, object>)state;

            switch (affair.key)
            {
            case C.AFFAIR_RELEASE_CONNECTION:
                Ret             ret;
                HoxisConnection conn = (HoxisConnection)affair.val;
                lock (conn) { _connReception.Release(conn, out ret); }
                if (ret.code != 0)
                {
                    _logger.LogWarning(ret.desc, "Affair"); return;
                }
                break;
            }
            _logger.LogInfo(FF.StringFormat("{0} processed", affair.key), "Affair", true);
        }
        /// <summary>
        /// Get the connection state if this user has already signed in
        /// </summary>
        /// <param name="handle"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        private bool QueryConnectionState(string handle, HoxisProtocolArgs args)
        {
            long uid = FF.StringToLong(args["uid"]);

            if (uid <= 0)
            {
                return(ResponseError(handle, C.RESP_ILLEGAL_ARGUMENT, FF.StringFormat("illegal argument: {0}", args["uid"])));
            }
            HoxisUser user = HoxisServer.Ins.GetUser(uid);

            if (user == null)
            {
                return(Response(handle, "QueryConnectionStateCb", new KVString("code", C.RESP_NO_USER_INFO)));
            }
            if (user == this)
            {
                return(Response(handle, "QueryConnectionStateCb", new KVString("code", C.RESP_NO_USER_INFO)));
            }
            return(ResponseSuccess(handle, "QueryConnectionStateCb", new KVString("state", user.connectionState.ToString())));
        }
        /// <summary>
        /// **WITHIN THREAD**
        /// The entrance of protocol bytes
        /// </summary>
        /// <param name="data"></param>
        public void ProtocolEntry(byte[] data)
        {
            string        json  = FF.BytesToString(data);
            HoxisProtocol proto = FF.JsonToObject <HoxisProtocol>(json);

            switch (proto.type)
            {
            case ProtocolType.Synchronization:
                switch (proto.receiver.type)
                {
                case ReceiverType.Cluster:
                    if (realtimeData.parentCluster == null)
                    {
                        return;
                    }
                    realtimeData.parentCluster.ProtocolBroadcast(proto);
                    break;

                case ReceiverType.Team:
                    if (realtimeData.parentTeam == null)
                    {
                        return;
                    }
                    realtimeData.parentTeam.ProtocolBroadcast(proto);
                    break;

                case ReceiverType.User:
                    HoxisUser user = HoxisServer.Ins.GetUser(proto.receiver.uid);
                    // todo send
                    break;
                }
                break;

            case ProtocolType.Request:
                // Request check
                Ret ret;
                CheckRequest(proto, out ret);
                if (ret.code != 0)
                {
                    ResponseError(proto.handle, C.RESP_CHECK_FAILED, ret.desc);
                    return;
                }
                // Check ok
                if (!respTable.ContainsKey(proto.action.method))
                {
                    if (DebugRecorder.LogEnable(_logger))
                    {
                        _logger.LogError(FF.StringFormat("invalid request: {0}", proto.action.method), "", true);
                    }
                    ResponseError(proto.handle, C.RESP_CHECK_FAILED, FF.StringFormat("invalid request: {0}", proto.action.method));
                    return;
                }
                respTable[proto.action.method](proto.handle, proto.action.args);
                break;

            default:
                if (DebugRecorder.LogEnable(_logger))
                {
                    _logger.LogError(FF.StringFormat("invalid protocol type: {0}", proto.type), "");
                }
                break;
            }
        }
        /// <summary>
        /// Init the configuration, such as the ip, port, socket and arguments
        /// </summary>
        /// <param name="configPath"></param>
        public void InitializeConfig(out Ret ret, string configPath = "")
        {
            // Init config
            string path;

            if (configPath != "")
            {
                path = configPath;
            }
            else
            {
                path = FF.StringAppend(basicPath, @"..\..\DacLib\Hoxis\Configs\hoxis_server.toml");
            }
            config = new TomlConfiguration(path, out ret);
            if (ret.code != 0)
            {
                _logger.LogFatal(ret.desc, "Server", true); return;
            }
            _logger.LogInfo("read configuration success", "Server");

            // Assign ip, port and init the sokcet
            localIP = SF.GetLocalIP(out ret);
            if (ret.code != 0)
            {
                _logger.LogFatal(ret.desc, "Server"); return;
            }
            port = config.GetInt("server", "port", out ret);
            if (ret.code != 0)
            {
                _logger.LogFatal(ret.desc, "Server"); return;
            }
            _logger.LogInfo(FF.StringFormat("ip is {0}, port is {1}", localIP, port.ToString()), "Server");

            // Init connection reception
            maxConn = config.GetInt("server", "max_conn", out ret);
            if (ret.code != 0)
            {
                _logger.LogFatal(ret.desc, "Server"); return;
            }
            _connReception = new CriticalPreformPool <HoxisConnection>(maxConn);
            _logger.LogInfo(FF.StringFormat("max connections is {0}", maxConn), "Server");

            // Init affair queue
            affairQueueCapacity = config.GetInt("server", "affair_queue_capacity", out ret);
            if (ret.code != 0)
            {
                _logger.LogFatal(ret.desc, "Server"); return;
            }
            _logger.LogInfo(FF.StringFormat("affair queue capacity is {0}", affairQueueCapacity), "Server");
            affairQueueProcessQuantity = config.GetShort("server", "affair_queue_process_quantity", out ret);
            if (ret.code != 0)
            {
                _logger.LogFatal(ret.desc, "Server"); return;
            }
            _logger.LogInfo(FF.StringFormat("affair queue process quantity is {0}", affairQueueProcessQuantity), "Server");
            _affairQueue               = new FiniteProcessQueue <KV <int, object> >(affairQueueCapacity, affairQueueProcessQuantity);
            _affairQueue.onProcess    += ProcessAffair;
            affairQueueProcessInterval = config.GetInt("server", "affair_queue_process_interval", out ret);
            if (ret.code != 0)
            {
                _logger.LogFatal(ret.desc, "Server"); return;
            }
            _logger.LogInfo(FF.StringFormat("affair queue process interval is {0}ms", affairQueueProcessInterval), "Server");

            // Init heartbeat update
            heartbeatUpdateInterval = config.GetInt("server", "heartbeat_update_interval", out ret);
            if (ret.code != 0)
            {
                _logger.LogFatal(ret.desc, "Server"); return;
            }
            _logger.LogInfo(FF.StringFormat("heartbeat update interval is {0}ms", heartbeatUpdateInterval), "Server");

            // Init connection
            HoxisConnection.readBufferSize = config.GetInt("conn", "read_buffer_size", out ret);
            if (ret.code != 0)
            {
                _logger.LogFatal(ret.desc, "Server"); return;
            }
            _logger.LogInfo(FF.StringFormat("read buffer size of connection is {0}", HoxisConnection.readBufferSize), "Server");

            // Init cluster
            _clusters            = new Dictionary <string, HoxisCluster>();
            HoxisCluster.maxUser = config.GetInt("cluster", "max_user", out ret);
            if (ret.code != 0)
            {
                _logger.LogFatal(ret.desc, "Server"); return;
            }
            _logger.LogInfo(FF.StringFormat("max users of cluster is {0}", HoxisCluster.maxUser), "Server");

            // Init team
            HoxisTeam.maxUser = config.GetInt("team", "max_user", out ret);
            if (ret.code != 0)
            {
                _logger.LogFatal(ret.desc, "Server"); return;
            }
            _logger.LogInfo(FF.StringFormat("max users of team is {0}", HoxisTeam.maxUser), "Server");

            // Init user
            HoxisUser.requestTTL = config.GetLong("user", "request_ttl", out ret);
            if (ret.code != 0)
            {
                _logger.LogFatal(ret.desc, "Server"); return;
            }
            _logger.LogInfo(FF.StringFormat("request time to live is {0}ms", HoxisUser.requestTTL), "Server");
            HoxisUser.heartbeatTimeout = config.GetInt("user", "heartbeat_timeout", out ret);
            if (ret.code != 0)
            {
                _logger.LogFatal(ret.desc, "Server"); return;
            }
            _logger.LogInfo(FF.StringFormat("heartbeat timeout is {0}ms", HoxisUser.heartbeatTimeout), "Server");

            _logger.LogInfo("init success", "Server", true);
        }