using System; namespace ET.Client { [FriendOf(typeof (PingComponent))] public static class PingComponentSystem { [Invoke(TimerInvokeType.ClientPing)] public class Ping: ATimer { protected override void Run(PingComponent self) { self.PingAsync().Coroutine(); } } [ObjectSystem] public class PingComponentAwakeSystem: AwakeSystem { protected override void Awake(PingComponent self) { self.Timer = TimerComponent.Instance.NewRepeatedTimer( Math.Max( 3000, 5 ), TimerInvokeType.ClientPing, self); } } [ObjectSystem] public class PingComponentDestroySystem: DestroySystem { protected override void Destroy(PingComponent self) { self.Ping = default; } } private static async ETTask PingAsync(this PingComponent self) { Session session = self.GetParent(); long instanceId = self.InstanceId; if (self.InstanceId != instanceId) { return; } long time1 = TimeHelper.ClientNow(); try { G2C_Ping response = await session.Call(new C2G_Ping()) as G2C_Ping; if (self.InstanceId != instanceId) { return; } long time2 = TimeHelper.ClientNow(); self.Ping = time2 - time1; TimeInfo.Instance.ServerMinusClientTime = response.Time + (time2 - time1) / 2 - time2; await TimerComponent.Instance.WaitAsync(2000); } catch (RpcException e) { // session断开导致ping rpc报错,记录一下即可,不需要打成error Log.Info($"ping error: {self.Id} {e.Error}"); } catch (Exception e) { Log.Error($"ping error: \n{e}"); } } } }