public void Execute(Entity entity, int index, ref PingClientConnectionComponentData connection) { if (!serverEP.IsValid) { connection.connection.Disconnect(driver); commandBuffer.DestroyEntity(entity); return; } DataStreamReader strm; NetworkEvent.Type cmd; while ((cmd = connection.connection.PopEvent(driver, out strm)) != NetworkEvent.Type.Empty) { if (cmd == NetworkEvent.Type.Connect) { pendingPings[0] = new PendingPing { id = pingStats[0], time = fixedTime }; var pingData = new DataStreamWriter(4, Allocator.Temp); pingData.Write(pingStats[0]); connection.connection.Send(driver, pingData); pingStats[0] = pingStats[0] + 1; } else if (cmd == NetworkEvent.Type.Data) { pingStats[1] = (int)((fixedTime - pendingPings[0].time) * 1000); connection.connection.Disconnect(driver); commandBuffer.DestroyEntity(entity); } else if (cmd == NetworkEvent.Type.Disconnect) { commandBuffer.DestroyEntity(entity); } } }
public void Execute() { // If we should be sending pings but we do not have an active connection we create one if (!connection[0].IsCreated) { connection[0] = driver.Connect(serverEp); } NetworkEvent.Type cmd; // Process all events on the connection. If the connection is invalid it will return Empty immediately while ((cmd = connection[0].PopEvent(driver, out var pingStream)) != NetworkEvent.Type.Empty) { switch (cmd) { case NetworkEvent.Type.Connect: // When we get the connect message we can start sending data to the server // Set the ping id to a sequence number for the new ping we are about to send pendingPings[0] = new PendingPing { id = numPings[0], time = DateTime.UtcNow.Ticks }; // Create a 4 byte data stream which we can store our ping sequence number in var pingData = new DataStreamWriter(4, Allocator.Temp); pingData.Write(numPings[0]); connection[0].Send(driver, pingData); // Update the number of sent pings numPings[0] = numPings[0] + 1; break; case NetworkEvent.Type.Data: lastPing[0] = (ushort)((DateTime.UtcNow.Ticks - pendingPings[0].time) / TimeSpan.TicksPerMillisecond); // Validate data from pong matches ping // TODO: Change if we ever support more than 1 pending ping var readerCtx = default(DataStreamReader.Context); var id = pingStream.ReadInt(ref readerCtx); var pingId = numPings[0] - 1; if (id != pingId) { Debug.LogWarning($"Received pong from server, but got wrong sequence number (Expected {pingId} but got {id})"); } connection[0].Disconnect(driver); connection[0] = default; break; case NetworkEvent.Type.Disconnect: // If the server disconnected us we clear out connection connection[0] = default; break; } } }
void FixedUpdate() { // Update the ping client UI with the ping statistics computed by teh job scheduled previous frame since that // is now guaranteed to have completed PingClientUIBehaviour.UpdateStats(m_numPingsSent, m_lastPingTime); // Update the NetworkDriver. It schedules a job so we must wait for that job with Complete m_ClientDriver.ScheduleUpdate().Complete(); // If the client ui indicates we should be sending pings but we do not have an active connection we create one if (PingClientUIBehaviour.ServerEndPoint.IsValid && !m_clientToServerConnection.IsCreated) { m_clientToServerConnection = m_ClientDriver.Connect(PingClientUIBehaviour.ServerEndPoint); } // If the client ui indicates we should not be sending pings but we do have a connection we close that connection if (!PingClientUIBehaviour.ServerEndPoint.IsValid && m_clientToServerConnection.IsCreated) { m_clientToServerConnection.Disconnect(m_ClientDriver); m_clientToServerConnection = default(NetworkConnection); } DataStreamReader strm; NetworkEvent.Type cmd; // Process all events on the connection. If the connection is invalid it will return Empty immediately while ((cmd = m_clientToServerConnection.PopEvent(m_ClientDriver, out strm)) != NetworkEvent.Type.Empty) { if (cmd == NetworkEvent.Type.Connect) { // When we get the connect message we can start sending data to the server // Set the ping id to a sequence number for the new ping we are about to send m_pendingPing = new PendingPing { id = m_numPingsSent, time = Time.fixedTime }; // Create a 4 byte data stream which we can store our ping sequence number in if (m_ClientDriver.BeginSend(m_clientToServerConnection, out var pingData) == 0) { pingData.WriteInt(m_numPingsSent); m_ClientDriver.EndSend(pingData); } // Update the number of sent pings ++m_numPingsSent; } else if (cmd == NetworkEvent.Type.Data) { // When the pong message is received we calculate the ping time and disconnect m_lastPingTime = (int)((Time.fixedTime - m_pendingPing.time) * 1000); m_clientToServerConnection.Disconnect(m_ClientDriver); m_clientToServerConnection = default(NetworkConnection); } else if (cmd == NetworkEvent.Type.Disconnect) { // If the server disconnected us we clear out connection m_clientToServerConnection = default(NetworkConnection); } } }
void ClientUpdate() { // Update the NetworkDriver. It schedules a job so we must wait for that job with Complete m_ClientDriver.ScheduleUpdate().Complete(); // If the client ui indicates we should be sending pings but we do not have an active connection we create one if (!m_clientToServerConnection.IsCreated) { var serverEP = NetworkEndPoint.LoopbackIpv4; serverEP.Port = ServerPort; m_clientToServerConnection = m_ClientDriver.Connect(serverEP); } DataStreamReader strm; NetworkEvent.Type cmd; // Process all events on the connection. If the connection is invalid it will return Empty immediately while ((cmd = m_clientToServerConnection.PopEvent(m_ClientDriver, out strm)) != NetworkEvent.Type.Empty) { if (cmd == NetworkEvent.Type.Connect) { // When we get the connect message we can start sending data to the server // Set the ping id to a sequence number for the new ping we are about to send m_pendingPing = new PendingPing { id = m_numPingsSent, time = Time.fixedTime }; // Create a 4 byte data stream which we can store our ping sequence number in if (m_ClientDriver.BeginSend(m_clientToServerConnection, out var pingData) == 0) { pingData.WriteInt(m_numPingsSent); m_ClientDriver.EndSend(pingData); } // Update the number of sent pings ++m_numPingsSent; } else if (cmd == NetworkEvent.Type.Data) { // When the pong message is received we calculate the ping time and disconnect m_lastPingTime = (int)((Time.fixedTime - m_pendingPing.time) * 1000); m_clientToServerConnection.Disconnect(m_ClientDriver); m_clientToServerConnection = default(NetworkConnection); UnityEngine.Debug.Log($"Ping: {m_lastPingTime}"); } else if (cmd == NetworkEvent.Type.Disconnect) { // If the server disconnected us we clear out connection m_clientToServerConnection = default(NetworkConnection); } } }
public void Execute() { // If the client ui indicates we should be sending pings but we do not have an active connection we create one if (serverEP.IsValid && !connection[0].IsCreated) { connection[0] = driver.Connect(serverEP); } // If the client ui indicates we should not be sending pings but we do have a connection we close that connection if (!serverEP.IsValid && connection[0].IsCreated) { connection[0].Disconnect(driver); connection[0] = default(NetworkConnection); } DataStreamReader strm; NetworkEvent.Type cmd; // Process all events on the connection. If the connection is invalid it will return Empty immediately while ((cmd = connection[0].PopEvent(driver, out strm)) != NetworkEvent.Type.Empty) { if (cmd == NetworkEvent.Type.Connect) { // When we get the connect message we can start sending data to the server // Set the ping id to a sequence number for the new ping we are about to send pendingPings[0] = new PendingPing { id = pingStats[0], time = fixedTime }; // Create a 4 byte data stream which we can store our ping sequence number in var pingData = new DataStreamWriter(4, Allocator.Temp); pingData.Write(pingStats[0]); connection[0].Send(driver, pingData); pingData.Dispose(); // Update the number of sent pings pingStats[0] = pingStats[0] + 1; } else if (cmd == NetworkEvent.Type.Data) { // When the pong message is received we calculate the ping time and disconnect pingStats[1] = (int)((fixedTime - pendingPings[0].time) * 1000); connection[0].Disconnect(driver); connection[0] = default(NetworkConnection); } else if (cmd == NetworkEvent.Type.Disconnect) { // If the server disconnected us we clear out connection connection[0] = default(NetworkConnection); } } }
public void Execute() { if (serverEP.IsValid && connections.Length == 0) { commandBuffer.CreateEntity(); commandBuffer.AddComponent(new PingClientConnectionComponentData { connection = driver.Connect(serverEP) }); } if (!serverEP.IsValid && connections.Length > 0) { for (int con = 0; con < connections.Length; ++con) { connections[con].connection.Disconnect(driver); commandBuffer.DestroyEntity(connectionEntities[con]); } return; } for (int con = 0; con < connections.Length; ++con) { DataStreamReader strm; NetworkEvent.Type cmd; while ((cmd = connections[con].connection.PopEvent(driver, out strm)) != NetworkEvent.Type.Empty) { if (cmd == NetworkEvent.Type.Connect) { pendingPings[0] = new PendingPing { id = pingStats[0], time = fixedTime }; var pingData = new DataStreamWriter(4, Allocator.Temp); pingData.Write(pingStats[0]); connections[con].connection.Send(driver, pingData); pingData.Dispose(); pingStats[0] = pingStats[0] + 1; } else if (cmd == NetworkEvent.Type.Data) { pingStats[1] = (int)((fixedTime - pendingPings[0].time) * 1000); connections[con].connection.Disconnect(driver); commandBuffer.DestroyEntity(connectionEntities[con]); } else if (cmd == NetworkEvent.Type.Disconnect) { commandBuffer.DestroyEntity(connectionEntities[con]); } } } }
public void Execute() { DataStreamReader strm; NetworkEvent.Type cmd; // Process all events on the connection. If the connection is invalid it will return Empty immediately while ((cmd = connection[0].PopEvent(driver, out strm)) != NetworkEvent.Type.Empty) { if (cmd == NetworkEvent.Type.Connect) { // When we get the connect message we can start sending data to the server // Set the ping id to a sequence number for the new ping we are about to send pendingPings[0] = new PendingPing { id = pingStats[0], time = fixedTime }; // Create a 4 byte data stream which we can store our ping sequence number in if (driver.BeginSend(connection[0], out var pingData) == 0) { pingData.WriteInt(pingStats[0]); driver.EndSend(pingData); } // Update the number of sent pings pingStats[0] = pingStats[0] + 1; } else if (cmd == NetworkEvent.Type.Data) { // When the pong message is received we calculate the ping time and disconnect pingStats[1] = (int)((fixedTime - pendingPings[0].time) * 1000); connection[0].Disconnect(driver); connection[0] = default(NetworkConnection); } else if (cmd == NetworkEvent.Type.Disconnect) { // If the server disconnected us we clear out connection connection[0] = default(NetworkConnection); } } }
protected override void OnUpdate() { if (!m_DriverSystem.ClientDriver.IsCreated) { return; } PingClientUIBehaviour.UpdateStats(m_PingStats[0], m_PingStats[1]); if (PingClientUIBehaviour.ServerEndPoint.IsValid && m_ConnectionGroup.IsEmptyIgnoreFilter) { Dependency.Complete(); var ent = EntityManager.CreateEntity(); EntityManager.AddComponentData(ent, new PingClientConnectionComponentData { connection = m_DriverSystem.ClientDriver.Connect(PingClientUIBehaviour.ServerEndPoint) }); return; } var driver = m_DriverSystem.ClientDriver; var serverEP = PingClientUIBehaviour.ServerEndPoint; var pendingPings = m_PendingPings; var pingStats = m_PingStats; var frameTime = Time.ElapsedTime; var commandBuffer = m_Barrier.CreateCommandBuffer(); Entities.ForEach((Entity entity, ref PingClientConnectionComponentData connection) => { if (!serverEP.IsValid) { connection.connection.Disconnect(driver); commandBuffer.DestroyEntity(entity); return; } DataStreamReader strm; NetworkEvent.Type cmd; while ((cmd = connection.connection.PopEvent(driver, out strm)) != NetworkEvent.Type.Empty) { if (cmd == NetworkEvent.Type.Connect) { pendingPings[0] = new PendingPing { id = pingStats[0], time = frameTime }; if (driver.BeginSend(connection.connection, out var pingData) == 0) { pingData.WriteInt(pingStats[0]); driver.EndSend(pingData); } pingStats[0] = pingStats[0] + 1; } else if (cmd == NetworkEvent.Type.Data) { pingStats[1] = (int)((frameTime - pendingPings[0].time) * 1000); connection.connection.Disconnect(driver); commandBuffer.DestroyEntity(entity); } else if (cmd == NetworkEvent.Type.Disconnect) { commandBuffer.DestroyEntity(entity); } } }).Schedule(); m_Barrier.AddJobHandleForProducer(Dependency); m_ServerConnectionGroup.AddDependency(Dependency); }
private void PingClients() { if ((DateTime.UtcNow - m_LastPing).TotalMilliseconds > PingInterval) { return; } if (UseCustomPingHandler) { var toDisconnect = new List <PendingPing>(); foreach (var pendingPing in m_PendingPings) { TimeSpan ping = DateTime.UtcNow - pendingPing.SendTime; if (ping > ClientTimeOut) { toDisconnect.Add(pendingPing); } bool isConnected = ((NetworkPeer)pendingPing.NetworkPeer).EnetPeer.State == PeerState.Connected; if (isConnected) { Disconnect(pendingPing.NetworkPeer, "Timeout."); } } m_PendingPings.RemoveAll(d => toDisconnect.Contains(d)); foreach (var client in GetPeers()) { ulong currentPingId = m_NextPingId; PendingPing pendingPing = new PendingPing { SendTime = DateTime.UtcNow, NetworkPeer = client, PingId = currentPingId }; m_PendingPings.Add(pendingPing); Send(client, new PingPacket { PingId = currentPingId }); m_NextPingId++; } } else { #if LOG_NETWORK foreach (var peer in GetPeers()) { var enetPeer = ((NetworkPeer)peer).EnetPeer; m_Logger.LogDebug($"{peer} ping: {enetPeer.RoundTripTime}ms"); } #endif } m_LastPing = DateTime.UtcNow; }