Esempio n. 1
0
        private static async ETTask <IActorResponse> RunInner(this ActorLocationSender self, IActorRequest iActorRequest)
        {
            try
            {
                if (self.ActorId == 0)
                {
                    Log.Info($"actor send message fail, actorid: {self.Id}");
                    self.Dispose();
                    return(new ActorResponse()
                    {
                        Error = ErrorCode.ERR_ActorNotOnline
                    });
                }

                self.LastSendOrRecvTime = TimeHelper.Now();
                IActorResponse response = await ActorMessageSenderComponent.Instance.CallWithoutException(self.ActorId, iActorRequest);

                switch (response.Error)
                {
                case ErrorCode.ERR_NotFoundActor:
                {
                    // 如果没找到Actor,重试
                    ++self.FailTimes;
                    if (self.FailTimes > ActorLocationSender.MaxFailTimes)
                    {
                        Log.Info($"actor send message fail, actorid: {self.Id}");
                        self.Dispose();
                        return(response);
                    }

                    // 等待0.5s再发送
                    long instanceId = self.InstanceId;
                    await TimerComponent.Instance.WaitAsync(500);

                    if (self.InstanceId != instanceId)
                    {
                        throw new RpcException(ErrorCode.ERR_ActorRemove, $"{MongoHelper.ToJson(iActorRequest)}");
                    }
                    self.ActorId = await LocationProxyComponent.Instance.Get(self.Id);

                    return(await self.RunInner(iActorRequest));
                }
                }

                self.LastSendOrRecvTime = TimeHelper.Now();
                self.FailTimes          = 0;

                return(response);
            }
            catch (RpcException)
            {
                self.Dispose();
                throw;
            }
            catch (Exception e)
            {
                self.Dispose();
                throw new Exception($"{MongoHelper.ToJson(iActorRequest)}\n{e}");
            }
        }
        public static async void UpdateAsync(this ActorLocationSender self)
        {
            try
            {
                long instanceId = self.InstanceId;
                while (true)
                {
                    if (self.InstanceId != instanceId)
                    {
                        return;
                    }
                    ActorTask actorTask = await self.GetAsync();

                    if (self.InstanceId != instanceId)
                    {
                        return;
                    }
                    if (actorTask.ActorRequest == null)
                    {
                        return;
                    }

                    await self.RunTask(actorTask);
                }
            }
            catch (Exception e)
            {
                Log.Error(e);
            }
        }
        public static async void DisconnectPlayer(Player player)
        {
            if (player == null)
            {
                return;
            }

            Log.Info($"DisconnectPlayer Start, uid:{player.uid}");

            // 向MapServer發送斷線訊息
            if (player.InRoom())
            {
                ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(player.mapUnitId);
                actorLocationSender.Send(new L2M_SessionDisconnect());

                // Player移除mapUnitId
                player.LeaveRoom();
            }

            player.isOnDisconnectingStage = true;
            // 更新Player
            await Game.Scene.GetComponent <PlayerComponent>().Update(player);

            Log.Info($"DisconnectPlayer End, uid:{player.uid}");
        }
Esempio n. 4
0
 public static async ETTask GetActorId(this ActorLocationSender self)
 {
     using (await CoroutineLockComponent.Instance.Wait(self.Id))
     {
         self.ActorId = await Game.Scene.GetComponent <LocationProxyComponent>().Get(self.Id);
     }
 }
Esempio n. 5
0
        public static ActorLocationSender ActorLocation(long unitId)
        {
            /// 得到 ActorLocat
            ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(unitId);

            return(actorLocationSender);
        }
Esempio n. 6
0
        /// <summary>
        /// 处理发送消息
        /// </summary>
        /// <param name="self"></param>
        /// <param name="task"></param>
        /// <returns></returns>
        private static async Task RunTask(this ActorLocationSender self, ActorTask task)
        {
            //获得和其他服务器通讯的会话
            ActorMessageSender actorMessageSender = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(self.ActorId);
            //发送一个rpc消息
            IActorResponse response = await actorMessageSender.Call(task.ActorRequest);

            // 发送成功
            switch (response.Error)
            {
            case ErrorCode.ERR_NotFoundActor:
                // 如果没找到Actor,重试
                ++self.FailTimes;

                // 失败MaxFailTimes次则清空actor发送队列,返回失败
                if (self.FailTimes > ActorLocationSender.MaxFailTimes)
                {
                    // 失败直接删除actorproxy
                    Log.Info($"actor send message fail, actorid: {self.Id}");
                    self.RunError(response.Error);
                    self.GetParent <ActorLocationSenderComponent>().Remove(self.Id);                           //从字典中移除这个会话通道
                    return;
                }

                // 等待0.5s再发送
                await Game.Scene.GetComponent <TimerComponent>().WaitAsync(500);

                self.ActorId = await Game.Scene.GetComponent <LocationProxyComponent>().Get(self.Id);                        //重新获得map服务器地址

                self.Address = StartConfigComponent.Instance
                               .Get(IdGenerater.GetAppIdFromId(self.ActorId))
                               .GetComponent <InnerConfig>().IPEndPoint;                         //得到IP
                self.AllowGet();
                return;

            case ErrorCode.ERR_ActorNoMailBoxComponent:
                self.RunError(response.Error);
                self.GetParent <ActorLocationSenderComponent>().Remove(self.Id);
                return;

            default:                                  //发送成功
                self.LastSendTime = TimeHelper.Now(); //记录最后发送时间
                self.FailTimes    = 0;
                self.WaitingTasks.Dequeue();          //出栈

                if (task.Tcs == null)
                {
                    return;
                }

                IActorLocationResponse actorLocationResponse = response as IActorLocationResponse;
                if (actorLocationResponse == null)
                {
                    task.Tcs.SetException(new Exception($"actor location respose is not IActorLocationResponse, but is: {response.GetType().Name}"));
                }
                task.Tcs.SetResult(actorLocationResponse);                          //返回PRC消息回应
                return;
            }
        }
Esempio n. 7
0
        private static async ETVoid DestroyAsync(SessionPlayerComponent self)
        {
            // 发送断线消息
            ActorLocationSender actorLocationSender = await Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(self.Player.UnitId);

            actorLocationSender.Send(new G2M_SessionDisconnect()).Coroutine();
            Game.Scene.GetComponent <PlayerComponent>()?.Remove(self.Player.Id);
        }
        /// <summary>
        /// 死亡判断 后结算
        /// </summary>
        /// <param name="unit"></param>
        public static void RemoveUnit(this AttackComponent self)
        {
            Console.WriteLine(" AttackComponentHelper-172- type: " + self.GetParent <Unit>().UnitType + " 删除单元 Unit。");

            ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(self.GetParent <Unit>().Id);

            actorLocationSender.Send(new Death_Map());
        }
Esempio n. 9
0
        public override void Destroy(SessionPlayerComponent self)
        {
            // 发送断线消息 根据账号里的角色单元ID  获得 与MAP服务器通讯的 会话ActorMessageSender
            ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(self.Player.UnitId);

            actorLocationSender.Send(new G2M_SessionDisconnect());               //给map服务器发送断线消息
            Game.Scene.GetComponent <PlayerComponent>()?.Remove(self.Player.Id); //移除用户管理中的账号
        }
        public override void Destroy(SessionPlayerComponent self)
        {
            // 发送断线消息
            ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(self.Player.UnitId);

            _ = actorLocationSender.Send(new G2M_SessionDisconnect());
            Game.Scene.GetComponent <PlayerComponent>()?.Remove(self.Player.Id);
        }
        public async void Dispatch(Session session, ushort opcode, object message)
        {
            try
            {
                switch (message)
                {
                case IActorLocationRequest actorLocationRequest:     // gate session收到actor rpc消息,先向actor 发送rpc请求,再将请求结果返回客户端
                {
                    long actorId = session.GetComponent <SessionUserComponent>().User.ActorID;
                    ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(actorId);

                    int       rpcId    = actorLocationRequest.RpcId; // 这里要保存客户端的rpcId
                    IResponse response = await actorLocationSender.Call(actorLocationRequest);

                    response.RpcId = rpcId;

                    session.Reply(response);
                    return;
                }

                case IActorLocationMessage actorLocationMessage:
                {
                    long actorId = session.GetComponent <SessionUserComponent>().User.ActorID;
                    ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(actorId);
                    actorLocationSender.Send(actorLocationMessage);
                    return;
                }

                case IActorRequest iActorRequest:
                {
                    long actorId = session.GetComponent <SessionUserComponent>().User.ActorID;
                    ActorMessageSender actorSender = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(actorId);

                    int       rpcId    = iActorRequest.RpcId; // 这里要保存客户端的rpcId
                    IResponse response = await actorSender.Call(iActorRequest);

                    response.RpcId = rpcId;

                    session.Reply(response);
                    return;
                }

                case IActorMessage iactorMessage:
                {
                    long actorId = session.GetComponent <SessionUserComponent>().User.ActorID;
                    ActorMessageSender actorSender = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(actorId);
                    actorSender.Send(iactorMessage);
                    return;
                }
                }

                Game.Scene.GetComponent <MessageDispatherComponent>().Handle(session, new MessageInfo(opcode, message));
            }
            catch (Exception e)
            {
                Log.Error(e);
            }
        }
Esempio n. 12
0
        private static async ETTask RunTask(this ActorLocationSender self, ActorTask task)
        {
            ActorMessageSender actorMessageSender = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(self.ActorId);
            IActorResponse     response           = await actorMessageSender.Call(task.ActorRequest);

            // 发送成功
            switch (response.Error)
            {
            case ErrorCode.ERR_NotFoundActor:
                // 如果没找到Actor,重试
                ++self.FailTimes;

                // 失败MaxFailTimes次则清空actor发送队列,返回失败
                if (self.FailTimes > ActorLocationSender.MaxFailTimes)
                {
                    // 失败直接删除actorproxy
                    Log.Info($"actor send message fail, actorid: {self.Id}");
                    self.RunError(response.Error);
                    self.GetParent <ActorLocationSenderComponent>().Remove(self.Id);
                    return;
                }

                // 等待0.5s再发送
                await Game.Scene.GetComponent <TimerComponent>().WaitAsync(500);

                self.ActorId = await Game.Scene.GetComponent <LocationProxyComponent>().Get(self.Id);

                self.AllowGet();
                return;

            case ErrorCode.ERR_ActorNoMailBoxComponent:
                self.RunError(response.Error);
                self.GetParent <ActorLocationSenderComponent>().Remove(self.Id);
                return;

            default:
                self.LastRecvTime = TimeHelper.Now();
                self.FailTimes    = 0;
                self.WaitingTasks.Dequeue();

                // 如果所有的发送消息都得到了返回,发送任务完成,那么删除这个ActorLocationSender,及时回收发送对象
                if (self.WaitingTasks.Count == 0)
                {
                    self.GetParent <ActorLocationSenderComponent>().Remove(self.Id);
                }

                if (task.Tcs != null)
                {
                    IActorLocationResponse actorLocationResponse = response as IActorLocationResponse;
                    if (actorLocationResponse == null)
                    {
                        task.Tcs.SetException(new Exception($"actor location respose is not IActorLocationResponse, but is: {response.GetType().Name}"));
                    }
                    task.Tcs.SetResult(actorLocationResponse);
                }
                return;
            }
        }
Esempio n. 13
0
        public static async ETVoid Send(this ActorLocationSender self, IActorLocationMessage request)
        {
            if (request == null)
            {
                throw new Exception($"actor location send message is null");
            }

            await Run(self, request);
        }
Esempio n. 14
0
        /// <summary>
        /// 发送巡逻目标点坐标 消息
        /// </summary>
        /// <param name="self"></param>
        static void SendPatrolPosition(this PatrolComponent self)
        {
            /// 休息时间到 开始发送巡逻目标点坐标 消息
            self.patrolMap = self.GetPatrolMap();
            self.goalPoint = self.patrolPoint;
            ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(self.GetParent <Unit>().Id);

            actorLocationSender.Send(self.patrolMap);
        }
 public static void RunError(this ActorLocationSender self, int errorCode)
 {
     while (self.WaitingTasks.Count > 0)
     {
         ActorTask actorTask = self.WaitingTasks.Dequeue();
         actorTask.Tcs?.SetException(new RpcException(errorCode, ""));
     }
     self.WaitingTasks.Clear();
 }
Esempio n. 16
0
        public static async ETTask <IActorLocationResponse> Call(this ActorLocationSender self, IActorLocationRequest request)
        {
            if (request == null)
            {
                throw new Exception($"actor location call message is null");
            }

            return(await Run(self, request) as IActorLocationResponse);
        }
Esempio n. 17
0
        public static void Send(this ActorLocationSender self, IActorLocationMessage request)
        {
            if (request == null)
            {
                throw new Exception($"actor location send message is null");
            }

            self.Run(request).Coroutine();
        }
        public static void Send(this ActorLocationSender self, IActorLocationMessage request)
        {
            if (request == null)
            {
                throw new Exception($"actor location send message is null");
            }
            ActorTask task = new ActorTask(request);

            self.Add(task);
        }
Esempio n. 19
0
 /// <summary>
 /// 发送追击目标坐标 消息
 /// </summary>
 /// <param name="self"></param>
 public static void SendSeePosition(this SeekComponent self)
 {
     // 发送一次目标点坐标 消息
     self.seeMap = self.GetSeeMap();
     if (self.seeMap != null)
     {
         ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get((self.Parent as Unit).Id);
         actorLocationSender.Send(self.seeMap);
     }
 }
Esempio n. 20
0
        /// <summary>
        /// 从队列里面取出一个消息进行处理
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        private static Task <ActorTask> GetAsync(this ActorLocationSender self)
        {
            if (self.WaitingTasks.Count > 0)
            {
                ActorTask task = self.WaitingTasks.Peek();
                return(Task.FromResult(task));                  //创建一个带返回值的、已完成的异步任务,其参数是取出的Task。
            }

            self.Tcs = new TaskCompletionSource <ActorTask>(); //如果棧里面有消息 这里是不会执行的,只有当站里面没有消息,程序就会在这里等待 知道加入了新的消息 继续
            return(self.Tcs.Task);                             //检测当前是否可以取堆栈里面缓存的消息
        }
        private static Task <ActorTask> GetAsync(this ActorLocationSender self)
        {
            if (self.WaitingTasks.Count > 0)
            {
                ActorTask task = self.WaitingTasks.Peek();
                return(Task.FromResult(task));
            }

            self.Tcs = new TaskCompletionSource <ActorTask>();
            return(self.Tcs.Task);
        }
        public static Task <IActorLocationResponse> Call(this ActorLocationSender self, IActorLocationRequest request)
        {
            if (request == null)
            {
                throw new Exception($"actor location call message is null");
            }
            TaskCompletionSource <IActorLocationResponse> tcs = new TaskCompletionSource <IActorLocationResponse>();
            ActorTask task = new ActorTask(request, tcs);

            self.Add(task);
            return(task.Tcs.Task);
        }
Esempio n. 23
0
        public async ETVoid DispatchAsync(Session session, ushort opcode, object message)
        {
            // 根据消息接口判断是不是Actor消息,不同的接口做不同的处理
            switch (message)
            {
            case IActorLocationRequest actorLocationRequest:                     // gate session收到actor rpc消息,先向actor 发送rpc请求,再将请求结果返回客户端
            {
                long unitId = session.GetComponent <SessionPlayerComponent>().Player.MapInstanceId;
                ActorLocationSender actorLocationSender = await Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(unitId);

                int       rpcId      = actorLocationRequest.RpcId;              // 这里要保存客户端的rpcId
                long      instanceId = session.InstanceId;
                IResponse response   = await actorLocationSender.Call(actorLocationRequest);

                response.RpcId = rpcId;

                // session可能已经断开了,所以这里需要判断
                if (session.InstanceId == instanceId)
                {
                    session.Reply(response);
                }

                break;
            }

            case IActorLocationMessage actorLocationMessage:
            {
                long unitId = session.GetComponent <SessionPlayerComponent>().Player.MapInstanceId;
                ActorLocationSender actorLocationSender = await Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(unitId);

                actorLocationSender.Send(actorLocationMessage).Coroutine();
                break;
            }

            case IActorRequest actorRequest:                      // 分发IActorRequest消息,目前没有用到,需要的自己添加
            {
                break;
            }

            case IActorMessage actorMessage:                      // 分发IActorMessage消息,目前没有用到,需要的自己添加
            {
                break;
            }

            default:
            {
                // 非Actor消息
                Game.Scene.GetComponent <MessageDispatcherComponent>().Handle(session, new MessageInfo(opcode, message));
                break;
            }
            }
        }
        public async void Dispatch(Session session, ushort opcode, object message)
        {
            try
            {
                switch (message)
                {
                case IFrameMessage iFrameMessage:                         // 如果是帧消息,构造成OneFrameMessage发给对应的unit
                {
                    long unitId = session.GetComponent <SessionPlayerComponent>().Player.UnitId;
                    ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(unitId);

                    // 这里设置了帧消息的id,防止客户端伪造
                    iFrameMessage.Id = unitId;

                    OneFrameMessage oneFrameMessage = new OneFrameMessage
                    {
                        Op = opcode, AMessage = ByteString.CopyFrom(session.Network.MessagePacker.SerializeTo(iFrameMessage))
                    };
                    actorLocationSender.Send(oneFrameMessage);
                    return;
                }

                case IActorLocationRequest actorLocationRequest:                         // gate session收到actor rpc消息,先向actor 发送rpc请求,再将请求结果返回客户端
                {
                    long unitId = session.GetComponent <SessionPlayerComponent>().Player.UnitId;
                    ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(unitId);

                    int       rpcId    = actorLocationRequest.RpcId;                    // 这里要保存客户端的rpcId
                    IResponse response = await actorLocationSender.Call(actorLocationRequest);

                    response.RpcId = rpcId;

                    session.Reply(response);
                    return;
                }

                case IActorLocationMessage actorLocationMessage:
                {
                    long unitId = session.GetComponent <SessionPlayerComponent>().Player.UnitId;
                    ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(unitId);
                    actorLocationSender.Send(actorLocationMessage);
                    return;
                }
                }

                Game.Scene.GetComponent <MessageDispatherComponent>().Handle(session, new MessageInfo(opcode, message));
            }
            catch (Exception e)
            {
                Log.Error(e);
            }
        }
        public override void Destroy(SessionPlayerComponent self)
        {
            // 发送断线消息
            long id = self.Player.UnitId == 0L? self.Player.TankId : self.Player.UnitId;

            if (id != 0)
            {
                ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(id);
                //actorLocationSender.Send(new G2M_SessionDisconnect());
                actorLocationSender.Send(new G2B_SessionDisconnect());
            }
            Game.Scene.GetComponent <PlayerComponent>()?.Remove(self.Player.Id);
        }
        public override void Destroy(SessionPlayerComponent self)
        {
            // 发送断线消息
            ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(self.Player.UnitId);

            actorLocationSender.Send(new G2M_SessionDisconnect());

            ///20190621  下线或断线后,自动删除unit
            Game.Scene.GetComponent <UnitComponent>()?.Remove(self.Player.UnitId);

            ///20190804  下线或断线后,不自动删除Player
            //Game.Scene.GetComponent<PlayerComponent>()?.Remove(self.Player.Id);
        }
Esempio n. 27
0
        private static async ETTask <IActorResponse> Run(this ActorLocationSender self, IActorRequest iActorRequest)
        {
            long instanceId = self.InstanceId;

            using (await CoroutineLockComponent.Instance.Wait(self.Id))
            {
                if (self.InstanceId != instanceId)
                {
                    throw new RpcException(ErrorCode.ERR_ActorRemove, $"{MongoHelper.ToJson(iActorRequest)}");
                }

                return(await self.RunInner(iActorRequest));
            }
        }
        private static void AllowGet(this ActorLocationSender self)
        {
            if (self.Tcs == null || self.WaitingTasks.Count <= 0)
            {
                return;
            }

            ActorTask task = self.WaitingTasks.Peek();

            var t = self.Tcs;

            self.Tcs = null;
            t.SetResult(task);
        }
        private static void Add(this ActorLocationSender self, ActorTask task)
        {
            if (self.IsDisposed)
            {
                throw new Exception("ActorLocationSender Disposed! dont hold ActorMessageSender");
            }

            self.WaitingTasks.Enqueue(task);
            // failtimes > 0表示正在重试,这时候不能加到正在发送队列
            if (self.FailTimes == 0)
            {
                self.AllowGet();
            }
        }
Esempio n. 30
0
        /// <summary>
        /// /检测当前是否可以取堆栈里面缓存的消息
        /// </summary>
        /// <param name="self"></param>
        private static void AllowGet(this ActorLocationSender self)
        {
            ///没有缓存消息 跳出  表示不可以取棧里数据
            if (self.Tcs == null || self.WaitingTasks.Count <= 0)
            {
                return;
            }

            ActorTask task = self.WaitingTasks.Peek();               //取出第一个 但不移除

            var t = self.Tcs;

            self.Tcs = null;
            t.SetResult(task);              //设置了值 说明可以取了
        }