/// <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 Reconnect(string handle, HoxisProtocolArgs args)
        {
            long uid = FF.StringToLong(args["uid"]);
            List <HoxisConnection> workers = HoxisServer.Ins.GetWorkingConnections();

            foreach (HoxisConnection w in workers)
            {
                // If already signed in, response the state to let user choose if reconnecting
                if (w.user == this)
                {
                    continue;
                }
                if (w.user.userID <= 0)
                {
                    continue;
                }
                if (w.user.userID == uid)
                {
                    userID       = w.user.userID;
                    realtimeData = w.user.realtimeData;
                    Continue();
                    if (DebugRecorder.LogEnable(_logger))
                    {
                        _logger.LogInfo("reconnect", "");
                    }
                    HoxisServer.Ins.AffairEntry(C.AFFAIR_RELEASE_CONNECTION, w);
                    return(ResponseSuccess(handle, "ReconnectCb"));
                }
            }
            return(Response(handle, "ReconnectCb", new KVString("code", C.RESP_NO_USER_INFO)));
        }
 /// <summary>
 /// Get config of long type
 /// </summary>
 /// <param name="section"></param>
 /// <param name="key"></param>
 /// <param name="ret"></param>
 /// <returns></returns>
 public long GetLong(string section, string key, out Ret ret)
 {
     if (!ContainItem(section, key, out ret))
     {
         return(0);
     }
     return(FF.StringToLong(_config[section][key], out ret));
 }
        /// <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())));
        }