From: Forest Date: Sat, 22 Dec 2018 22:03:36 +0000 (-0800) Subject: This is what I'm using now, 1100 users on my single core, but after moving to multico... X-Git-Tag: 1.0.0~66 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=42bedeb26d3d5603c29a068590c85a4d8f8bdbfe;p=rhonda%2Fimpostor.hazel.git This is what I'm using now, 1100 users on my single core, but after moving to multicore, I'm seeing a lot of lock contention, not sure if Hazel or my game server code --- diff --git a/Hazel/Udp/UdpClientConnection.cs b/Hazel/Udp/UdpClientConnection.cs index 257e782..0752d2c 100644 --- a/Hazel/Udp/UdpClientConnection.cs +++ b/Hazel/Udp/UdpClientConnection.cs @@ -25,6 +25,8 @@ namespace Hazel.Udp /// byte[] dataBuffer = new byte[ushort.MaxValue]; + Timer reliablePacketTimer; + /// /// Creates a new UdpClientConnection. /// @@ -46,6 +48,8 @@ namespace Hazel.Udp socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp); socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, false); //TODO these lines shouldn't be needed anymore } + + reliablePacketTimer = new Timer((s) => ManageReliablePackets(s), null, 50, Timeout.Infinite); } ~UdpClientConnection() @@ -60,12 +64,14 @@ namespace Hazel.Udp { ThreadPool.QueueUserWorkItem(a => { Thread.Sleep(this.TestLagMs); WriteBytesToConnectionReal(bytes, length); }); } - - WriteBytesToConnectionReal(bytes, length); + else + { + WriteBytesToConnectionReal(bytes, length); + } } private void WriteBytesToConnectionReal(byte[] bytes, int length) - { + { InvokeDataSentRaw(bytes, length); if (State != ConnectionState.Connected && State != ConnectionState.Connecting) @@ -83,14 +89,13 @@ namespace Hazel.Udp { try { - lock (socket) - socket.EndSendTo(result); + socket.EndSendTo(result); } - catch (ObjectDisposedException e) + catch (ObjectDisposedException) { HandleDisconnect("Could not send as the socket was disposed of."); } - catch (SocketException e) + catch (SocketException) { HandleDisconnect("Could not send data as a SocketException occured."); } @@ -103,13 +108,13 @@ namespace Hazel.Udp //User probably called Disconnect in between this method starting and here so report the issue throw new InvalidOperationException("Could not send data as this Connection is not connected. Did you disconnect?"); } - catch (SocketException e) + catch (SocketException) { HandleDisconnect("Could not send data as a SocketException occured."); - throw e; + throw; } } - + /// public override void Connect(byte[] bytes = null, int timeout = 5000) { @@ -129,8 +134,8 @@ namespace Hazel.Udp /// public override void ConnectAsync(byte[] bytes = null, int timeout = 5000) { - if (State != ConnectionState.NotConnected) - throw new InvalidOperationException("Cannot connect as the Connection is already connected."); + if (State != ConnectionState.NotConnected) + throw new InvalidOperationException("Cannot connect as the Connection is already connected."); State = ConnectionState.Connecting; @@ -278,7 +283,9 @@ namespace Hazel.Udp socket = null; } + this.reliablePacketTimer.Dispose(); + base.Dispose(disposing); } } -} +} \ No newline at end of file diff --git a/Hazel/Udp/UdpConnection.KeepAlive.cs b/Hazel/Udp/UdpConnection.KeepAlive.cs index a9a5f11..8227a6f 100644 --- a/Hazel/Udp/UdpConnection.KeepAlive.cs +++ b/Hazel/Udp/UdpConnection.KeepAlive.cs @@ -38,7 +38,7 @@ namespace Hazel.Udp ResetKeepAliveTimer(); } } - int keepAliveInterval = 10000; + int keepAliveInterval = 3000; public int KeepAlivesSent; diff --git a/Hazel/Udp/UdpConnection.Reliable.cs b/Hazel/Udp/UdpConnection.Reliable.cs index 6c6597e..23be344 100644 --- a/Hazel/Udp/UdpConnection.Reliable.cs +++ b/Hazel/Udp/UdpConnection.Reliable.cs @@ -47,7 +47,9 @@ namespace Hazel.Udp /// The packet id that was received last. /// volatile ushort reliableReceiveLast = 0; - + + public int DuplicateRecieves; + /// /// Has the connection received anything yet /// @@ -215,6 +217,7 @@ namespace Hazel.Udp if (p.Acknowledged) return 0; p.LastSend = DateTime.Now; + p.LastTimeout = (int)Math.Min(p.LastTimeout * 1.5f, 3000); Packet self; if (p.Stopwatch.ElapsedMilliseconds > this.disconnectTimeout) @@ -229,8 +232,6 @@ namespace Hazel.Udp return 0; } - // Backoff retry frequency to avoid congestion - p.LastTimeout = (int)Math.Min(p.LastTimeout * 1.25f, 1000); try { @@ -319,6 +320,7 @@ namespace Hazel.Udp } else { + Interlocked.Increment(ref this.DuplicateRecieves); message.Recycle(); } diff --git a/Hazel/Udp/UdpConnectionListener.cs b/Hazel/Udp/UdpConnectionListener.cs index 3459a06..0c2239a 100644 --- a/Hazel/Udp/UdpConnectionListener.cs +++ b/Hazel/Udp/UdpConnectionListener.cs @@ -27,9 +27,7 @@ namespace Hazel.Udp /// The socket listening for connections. /// Socket listener; - - private Action Logger; - + Timer reliablePacketTimer; /// @@ -43,9 +41,8 @@ namespace Hazel.Udp /// Creates a new UdpConnectionListener for the given , port and . /// /// The endpoint to listen on. - public UdpConnectionListener(NetworkEndPoint endPoint, Action logger = null) + public UdpConnectionListener(NetworkEndPoint endPoint) { - this.Logger = logger; this.EndPoint = endPoint.EndPoint; this.IPMode = endPoint.IPMode; @@ -70,6 +67,8 @@ namespace Hazel.Udp public float AveragePacketsTime = 1; public int PacketsResent = 0; + public int KeepAlives = 0; + public int DuplicateRecieves = 0; Stopwatch stopwatch = new Stopwatch(); private void ManageReliablePackets(object state) @@ -77,7 +76,10 @@ namespace Hazel.Udp stopwatch.Restart(); foreach (var kvp in this.allConnections) { - PacketsResent += kvp.Value.ManageReliablePackets(state); + var sock = kvp.Value; + PacketsResent += sock.ManageReliablePackets(state); + KeepAlives += Interlocked.Exchange(ref sock.KeepAlivesSent, 0); + DuplicateRecieves += Interlocked.Exchange(ref sock.DuplicateRecieves, 0); } this.AveragePacketsTime = this.AveragePacketsTime * .7f + stopwatch.ElapsedMilliseconds * .3f; @@ -128,7 +130,7 @@ namespace Hazel.Udp return; } } - + /// /// Called when data has been received by the listener. /// @@ -223,20 +225,8 @@ namespace Hazel.Udp } } - 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))}"); - } - } + //Inform the connection of the buffer (new connections need to send an ack back to client) + connection.HandleReceive(message, bytesReceived); //If it's a new connection invoke the NewConnection event. if (!aware) @@ -329,10 +319,7 @@ namespace Hazel.Udp /// The endpoint of the virtual connection. internal void RemoveConnectionTo(EndPoint endPoint) { - lock (this.allConnections) - { - this.allConnections.TryRemove(endPoint, out var conn); - } + this.allConnections.TryRemove(endPoint, out var conn); } ///