From b17950c34b0ce2c8008944ba041a101b786a9161 Mon Sep 17 00:00:00 2001 From: Forest Date: Tue, 18 Dec 2018 15:57:24 -0800 Subject: [PATCH] Allow for a little more instrumenting, maybe stop a race --- Hazel/ObjectPool.cs | 1 + Hazel/Udp/UdpConnection.Reliable.cs | 14 ++++---- Hazel/Udp/UdpConnectionListener.cs | 51 ++++++++++++++++++++--------- 3 files changed, 44 insertions(+), 22 deletions(-) diff --git a/Hazel/ObjectPool.cs b/Hazel/ObjectPool.cs index b97907c..0da7dbf 100644 --- a/Hazel/ObjectPool.cs +++ b/Hazel/ObjectPool.cs @@ -15,6 +15,7 @@ namespace Hazel { private int numberCreated; public int NumberCreated { get { return numberCreated; } } + public int NumberInUse { get { return this.inuse.Count; } } public int Size { get { return this.pool.Count; } } diff --git a/Hazel/Udp/UdpConnection.Reliable.cs b/Hazel/Udp/UdpConnection.Reliable.cs index 16554da..316990b 100644 --- a/Hazel/Udp/UdpConnection.Reliable.cs +++ b/Hazel/Udp/UdpConnection.Reliable.cs @@ -79,12 +79,12 @@ namespace Hazel.Udp /// /// Class to hold packet data /// - class Packet : IRecyclable, IDisposable + public class Packet : IRecyclable, IDisposable { /// /// Object pool for this event. /// - static readonly ObjectPool objectPool = new ObjectPool(() => new Packet()); + public static readonly ObjectPool PacketPool = new ObjectPool(() => new Packet()); /// /// Returns an instance of this object from the pool. @@ -92,7 +92,7 @@ namespace Hazel.Udp /// internal static Packet GetObject() { - return objectPool.GetObject(); + return PacketPool.GetObject(); } public ushort Id; @@ -143,7 +143,7 @@ namespace Hazel.Udp } } - objectPool.PutObject(this); + PacketPool.PutObject(this); } /// @@ -223,7 +223,7 @@ namespace Hazel.Udp if (p.Id != id) return; // Backoff retry frequency to avoid congestion - p.LastTimeout = (int)Math.Min(p.LastTimeout * 1.5f, this.disconnectTimeout / 2f); + p.LastTimeout = (int)Math.Min(p.LastTimeout * 1.25f, 2000); p.Timer.Change(p.LastTimeout, Timeout.Infinite); } @@ -240,7 +240,7 @@ namespace Hazel.Udp Trace.WriteLine("Resend."); }, - resendTimeout > 0 ? resendTimeout : (int)Math.Max(100, Math.Min(AveragePingMs * 4, 1500)), + resendTimeout > 0 ? resendTimeout : (int)Math.Max(500, Math.Min(AveragePingMs * 4, 2000)), ackCallback ); } @@ -422,7 +422,7 @@ namespace Hazel.Udp lock (PingLock) { - this.AveragePingMs = Math.Max(10, this.AveragePingMs * .7f + rt * .3f); + this.AveragePingMs = Math.Max(50, this.AveragePingMs * .7f + rt * .3f); } } diff --git a/Hazel/Udp/UdpConnectionListener.cs b/Hazel/Udp/UdpConnectionListener.cs index bcefc86..6252e58 100644 --- a/Hazel/Udp/UdpConnectionListener.cs +++ b/Hazel/Udp/UdpConnectionListener.cs @@ -23,7 +23,9 @@ namespace Hazel.Udp /// The socket listening for connections. /// Socket listener; - + + private Action Logger; + /// /// The connections we currently hold /// @@ -37,10 +39,10 @@ namespace Hazel.Udp /// The port to listen on. /// The to listen with. [Obsolete("Temporary constructor in beta only, use NetworkEndPoint constructor instead.")] - public UdpConnectionListener(IPAddress IPAddress, int port, IPMode mode = IPMode.IPv4) + public UdpConnectionListener(IPAddress IPAddress, int port, Action logger, IPMode mode = IPMode.IPv4) : this (new NetworkEndPoint(IPAddress, port, mode)) { - + this.Logger = logger; } /// @@ -163,22 +165,23 @@ namespace Hazel.Udp message.Recycle(); return; } - + //Begin receiving again StartListeningForData(); - bool aware; - bool isHello = message.Buffer[0] == (byte)UdpSendOption.Hello - && message.Length >= MinConnectionLength; + bool aware = true; + bool hasHelloByte = message.Buffer[0] == (byte)UdpSendOption.Hello; + bool isHello = hasHelloByte && message.Length >= MinConnectionLength; //If we're aware of this connection use the one already //If this is a new client then connect with them! UdpServerConnection connection; - if (!(aware = this.allConnections.TryGetValue(remoteEndPoint, out connection))) + if (!this.allConnections.TryGetValue(remoteEndPoint, out connection)) { lock (this.allConnections) { - if (!(aware = this.allConnections.TryGetValue(remoteEndPoint, out connection))) + aware = this.allConnections.TryGetValue(remoteEndPoint, out connection); + if (!aware) { //Check for malformed connection attempts if (!isHello) @@ -189,24 +192,39 @@ namespace Hazel.Udp } connection = new UdpServerConnection(this, remoteEndPoint, this.IPMode); - this.allConnections.TryAdd(remoteEndPoint, connection); + if (!this.allConnections.TryAdd(remoteEndPoint, connection)) + { + throw new Exception(); + } } } } - //Inform the connection of the buffer (new connections need to send an ack back to client) - connection.HandleReceive(message, bytesReceived); + var stopwatch = System.Diagnostics.Stopwatch.StartNew(); + try + { + //Inform the connection of the buffer (new connections need to send an ack back to client) + connection.HandleReceive(message, bytesReceived); + } + finally + { + var el = stopwatch.ElapsedMilliseconds; + if (el > 5) + { + this.Logger?.Invoke($"Long Packet {el}ms = {string.Join(" ", message.Buffer.Take(bytesReceived))}"); + } + } //If it's a new connection invoke the NewConnection event. if (!aware) { // Skip header and hello byte; - message.Offset = 4; + message.Offset = 4; message.Length = bytesReceived - 4; message.Position = 0; InvokeNewConnection(message, connection); } - else if (isHello) + else if (isHello || (!isHello && hasHelloByte)) { message.Recycle(); } @@ -287,7 +305,10 @@ namespace Hazel.Udp /// The endpoint of the virtual connection. internal void RemoveConnectionTo(EndPoint endPoint) { - this.allConnections.TryRemove(endPoint, out var conn); + lock (this.allConnections) + { + this.allConnections.TryRemove(endPoint, out var conn); + } } /// -- 2.39.5