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.LastRecvTime = TimeHelper.Now();
                ActorMessageSender actorMessageSender = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(self.ActorId);
                IActorResponse     response           = await actorMessageSender.CallWithoutException(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 Game.Scene.GetComponent <LocationProxyComponent>().Get(self.Id);

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

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

                return(response);
            }
            catch (Exception e)
            {
                self.Dispose();
                throw new Exception($"{MongoHelper.ToJson(iActorRequest)}\n{e}");
            }
        }
Esempio n. 2
0
        private static async ETTask RunTask(this ActorLocationSender self, ActorTask task)
        {
            ActorMessageSender actorMessageSender = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(self.ActorId);
            IActorResponse     response;

            try
            {
                // 这里必须使用不抛异常的rpc,因为服务端handler很可能出现错误,返回一个rpc fail的错误,结果这里抛了异常
                // 这里抛了异常就会导致队列中的消息无法继续发送,导致整个actorlocationsender堵塞
                response = await actorMessageSender.CallWithoutException(task.ActorRequest);
            }
            catch (Exception e)
            {
                self.GetParent <ActorLocationSenderComponent>().Remove(self.Id);
                return;
            }


            // 发送成功
            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. 3
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, "");
                }

                ActorMessageSender actorMessageSender = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(self.ActorId);
                try
                {
                    // ERR_NotFoundActor是需要抛异常的,但是这里不能抛
                    IActorResponse response = await actorMessageSender.CallWithoutException(iActorRequest);

                    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.GetParent <ActorLocationSenderComponent>().Remove(self.Id);
                            throw new RpcException(response.Error, "");
                        }

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

                        if (self.InstanceId != instanceId)
                        {
                            throw new RpcException(ErrorCode.ERR_ActorRemove, "");
                        }
                        self.ActorId = await Game.Scene.GetComponent <LocationProxyComponent>().Get(self.Id);

                        IActorResponse iActorResponse = await Run(self, iActorRequest);

                        if (self.InstanceId != instanceId)
                        {
                            throw new RpcException(ErrorCode.ERR_ActorRemove, "");
                        }
                        return(iActorResponse);

                    case ErrorCode.ERR_ActorNoMailBoxComponent:
                        self.GetParent <ActorLocationSenderComponent>().Remove(self.Id);
                        throw new RpcException(response.Error, "");

                    default:
                        self.LastRecvTime = TimeHelper.Now();
                        self.FailTimes    = 0;
                        break;
                    }

                    return(response);
                }
                catch (Exception)
                {
                    self.GetParent <ActorLocationSenderComponent>().Remove(self.Id);
                    throw;
                }
            }
        }