using System; namespace ET { [ObjectSystem] public class ActorLocationSenderComponentAwakeSystem : AwakeSystem { public override void Awake(ActorLocationSenderComponent self) { ActorLocationSenderComponent.Instance = self; // 每10s扫描一次过期的actorproxy进行回收,过期时间是1分钟 // 可能由于bug或者进程挂掉,导致ActorLocationSender发送的消息没有确认,结果无法自动删除,每一分钟清理一次这种ActorLocationSender self.CheckTimer = TimerComponent.Instance.NewRepeatedTimer(10 * 1000, self.Check); } } [ObjectSystem] public class ActorLocationSenderComponentDestroySystem: DestroySystem { public override void Destroy(ActorLocationSenderComponent self) { ActorLocationSenderComponent.Instance = null; TimerComponent.Instance.Remove(self.CheckTimer); self.CheckTimer = 0; } } public static class ActorLocationSenderComponentSystem { public static void Check(this ActorLocationSenderComponent self) { using (ListComponent list = EntityFactory.Create>(self.Domain)) { long timeNow = TimeHelper.Now(); foreach ((long key, Entity value) in self.Children) { ActorLocationSender actorLocationMessageSender = (ActorLocationSender) value; if (timeNow > actorLocationMessageSender.LastSendOrRecvTime + ActorLocationSenderComponent.TIMEOUT_TIME) { list.List.Add(key); } } foreach (long id in list.List) { self.Remove(id); } } } private static ActorLocationSender Get(this ActorLocationSenderComponent self, long id) { if (id == 0) { throw new Exception($"actor id is 0"); } if (self.Children.TryGetValue(id, out Entity actorLocationSender)) { return (ActorLocationSender)actorLocationSender; } actorLocationSender = EntityFactory.CreateWithId(self.Domain, id); actorLocationSender.Parent = self; return (ActorLocationSender)actorLocationSender; } private static void Remove(this ActorLocationSenderComponent self, long id) { if (!self.Children.TryGetValue(id, out Entity actorMessageSender)) { return; } actorMessageSender.Dispose(); } public static void Send(this ActorLocationSenderComponent self, long entityId, IActorLocationMessage message) { ActorLocationSender actorLocationSender = self.Get(entityId); actorLocationSender.Send(message); } public static async ETTask Call(this ActorLocationSenderComponent self, long entityId, IActorLocationRequest message) { ActorLocationSender actorLocationSender = self.Get(entityId); return await actorLocationSender.Call(message); } } }