//---------------------------------------------------------------------
        async Task _update()
        {
            float tm = (float)StopwatchUpdate.Elapsed.TotalSeconds;

            StopwatchUpdate.Restart();

            if (EtPlayer != null)
            {
                EtPlayer.update(tm);

                if (CouchbaseQue != null)
                {
                    Tm4CouchbaseQue += tm;
                    if (Tm4CouchbaseQue > 1f)
                    {
                        Tm4CouchbaseQue = 0f;
                        await CouchbaseQue.queryThenCacheAllData();
                    }

                    if (CouchbaseQue.Count > 0)
                    {
                        var que_data = await CouchbaseQue.popData();

                        if (que_data.type > 0)
                        {
                            var co_player = EtPlayer.getComponent <CellPlayer <DefPlayer> >();
                            await co_player.recvCouchbaseQueData(que_data);
                        }
                    }
                }
            }
        }
        //---------------------------------------------------------------------
        // Client->Cell的请求
        async Task <MethodData> ICellPlayer.c2sRequest(MethodData method_data)
        {
            var        co_player = EtPlayer.getComponent <CellPlayer <DefPlayer> >();
            MethodData result    = await co_player.c2sRequest(method_data);

            return(result);
        }
        //---------------------------------------------------------------------
        // Cell->Cell的请求
        Task ICellPlayer.s2sDesktop2Player(List <string> vec_param)
        {
            if (EtPlayer == null)
            {
                return(TaskDone.Done);
            }

            var co_playerdesktop = EtPlayer.getComponent <CellPlayerDesktop <DefPlayerDesktop> >();

            return(co_playerdesktop.s2sDesktop2Player(vec_param));
        }
        //---------------------------------------------------------------------
        async Task ICellPlayer.unsubPlayer(ICellPlayerObserver sub)
        {
            bool is_sub = Subscribers.IsSubscribed(sub);

            if (is_sub)
            {
                Subscribers.Unsubscribe(sub);
            }

            // 通知EtPlayer服务端:客户端断开了
            if (Subscribers.Count == 0 && EtPlayer != null)
            {
                var co_player = EtPlayer.getComponent <CellPlayer <DefPlayer> >();
                await co_player.c2sClientDeattach();

                DeactivateOnIdle();
            }
        }
        //---------------------------------------------------------------------
        Task _save()
        {
            if (EtPlayer == null)
            {
                return(TaskDone.Done);
            }

            State = EtPlayer.genEntityData4SaveDb();
            WriteStateAsync();

            var co_player = EtPlayer.getComponent <CellPlayer <DefPlayer> >();

            if (co_player.CachePlayerData.player_server_state != PlayerServerState.Offline)
            {
                string data = EbTool.jsonSerialize(co_player.CachePlayerData);
                DbClientCouchbase.Instance.asyncTouch(co_player.CachePlayerKey, TimeSpan.FromSeconds(15.0));
            }

            return(TaskDone.Done);
        }
        //---------------------------------------------------------------------
        Task ICellPlayer.subPlayer(ICellPlayerObserver sub, IPEndPoint remote_endpoint)
        {
            if (Subscribers.Count > 0)
            {
                Logger.Info("subPlayer() 重复登陆,踢出前一帐号 Subscribers.Count={0}", Subscribers.Count);

                AccountNotify account_notify;
                account_notify.id   = AccountNotifyId.Logout;
                account_notify.data = EbTool.protobufSerialize <ProtocolResult>(ProtocolResult.LogoutNewLogin);

                MethodData notify_data = new MethodData();
                notify_data.method_id = MethodType.s2cAccountNotify;
                notify_data.param1    = EbTool.protobufSerialize <AccountNotify>(account_notify);
                Subscribers.Notify((s) => s.s2cNotify(notify_data));
            }

            Subscribers.Subscribe(sub);

            var co_player = EtPlayer.getComponent <CellPlayer <DefPlayer> >();

            co_player.c2sClientAttach(remote_endpoint);

            return(TaskDone.Done);
        }