private void ProcessUdpTransferFrame(UdpTransferFrame frame) { this.UpdateKeepAlive(); switch (frame.Type) { case FrameType.ClientPing: this.log.Debug($"[Client:{this.state.ClientId} => Server] PING"); var cmdClientPing = new ClientPingMessage(frame.MessageBuffer); var now = TimeSpan.FromTicks(DateTime.UtcNow.Ticks); var msgServerPong = new ServerPongMessage() { ClientRequestTimestamp = cmdClientPing.ClientTimestamp, ClientResponseTimestamp = now, ServerTimestamp = now }; this.SendFrameToClient(FrameType.ServerPong, msgServerPong.Serialize()); break; case FrameType.ClientPong: this.log.Debug($"[Client:{this.state.ClientId} => Server] PONG"); var msgClientPong = new ClientPongMessage(frame.MessageBuffer); this.CalculateClientLatency(msgClientPong); break; case FrameType.Message: this.reliableClientMessaging.ProcessMessageFrame(frame); break; } }
/// <summary> /// TimeOffset = (t1 - t0) - (t2 - t3) /// Rountrip = (t3 - t0) - (t2 - t1) /// t0 is the client's timestamp of the request packet transmission, /// t1 is the server's timestamp of the request packet reception, /// t2 is the server's timestamp of the response packet transmission and /// t3 is the client's timestamp of the response packet reception. /// </summary> private void CalculateClientLatency(ClientPongMessage msg) { var t0 = msg.ServerRequestTimestamp; var t1 = msg.ClientRequestTimestamp; var t2 = msg.ClientResponseTimestamp; var t3 = TimeSpan.FromTicks(DateTime.UtcNow.Ticks); this.state.Latency = TimeSpan.FromTicks(((t1 - t0) + (t3 - t2)).Ticks / 2); }
/// <summary>Processes the UDP transfer frame.</summary> /// <param name="frame">The frame.</param> private void ProcessUdpTransferFrame(UdpTransferFrame frame) { switch (frame.Type) { case FrameType.ServerAuthenticationRequest: var msgAuthenticationRequest = new ServerAuthenticationRequest(frame.MessageBuffer); ProcessAuthenticationRequest(msgAuthenticationRequest, this.signingKeyBase64); break; case FrameType.ServerHello: SubscribeToDefaultArea(); if (OnConnected != null) { Thread connected = new Thread(() => OnConnected()); connected.Start(); } break; case FrameType.ServerPing: var msgServerPing = new ServerPingMessage(frame.MessageBuffer); var now = TimeSpan.FromTicks(DateTime.UtcNow.Ticks); var cmdClientPong = new ClientPongMessage() { ServerRequestTimestamp = msgServerPing.ServerTimestamp, ClientRequestTimestamp = now, ClientResponseTimestamp = now }; ReliableMessaging.OnSendFrame(new UdpTransferFrame(FrameType.ClientPong, cmdClientPong.Serialize())); break; case FrameType.Message: LastMessageReceived = DateTime.Now; ReliableMessaging.ProcessMessageFrame(frame); break; default: throw new NotImplementedException(frame.Type.ToString()); } }