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}"); } }
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; } }
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; } } }