From: Forest Date: Fri, 20 Jul 2018 18:06:19 +0000 (-0700) Subject: Change the RUDP retry logic to be time based, improve disconnect reason reporting X-Git-Tag: 1.0.0~85 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=5e4a0a8b6a28b3b3a604d6926f879d7091345a86;p=rhonda%2Fimpostor.hazel.git Change the RUDP retry logic to be time based, improve disconnect reason reporting --- diff --git a/Hazel/Udp/UdpClientConnection.cs b/Hazel/Udp/UdpClientConnection.cs index 1bd5a79..56b9688 100644 --- a/Hazel/Udp/UdpClientConnection.cs +++ b/Hazel/Udp/UdpClientConnection.cs @@ -203,7 +203,7 @@ namespace Hazel.Udp //Exit if no bytes read, we've failed. if (bytesReceived == 0) { - HandleDisconnect(); + HandleDisconnect(new HazelException("Recieved 0 bytes")); return; } diff --git a/Hazel/Udp/UdpConnection.Reliable.cs b/Hazel/Udp/UdpConnection.Reliable.cs index e1c98e5..b407ed5 100644 --- a/Hazel/Udp/UdpConnection.Reliable.cs +++ b/Hazel/Udp/UdpConnection.Reliable.cs @@ -17,11 +17,10 @@ namespace Hazel.Udp /// /// For reliable delivery data is resent at specified intervals unless an acknowledgement is received from the /// receiving device. The ResendTimeout specifies the interval between the packets being resent, each time a packet - /// is resent the interval is doubled for that packet until the number of resends exceeds the - /// value. + /// is resent the interval is increased for that packet until the duration exceeds the value. /// /// - /// Setting this to its default of 0 will mean the timout is 4 times the value of the average ping, usually + /// Setting this to its default of 0 will mean the timeout is 2 times the value of the average ping, usually /// resulting in a more dynamic resend that responds to endpoints on slower or faster connections. /// /// @@ -73,8 +72,8 @@ namespace Hazel.Udp /// connection will be marked as disconnected and the Disconnected event /// will be invoked. /// - public int ResendsBeforeDisconnect { get { return resendsBeforeDisconnect; } set { resendsBeforeDisconnect = value; } } - private volatile int resendsBeforeDisconnect = 3; + public int DisconnectTimeout { get { return disconnectTimeout; } set { disconnectTimeout = value; } } + private volatile int disconnectTimeout = 2500; /// /// Class to hold packet data @@ -186,15 +185,17 @@ namespace Hazel.Udp buffer, (Packet p) => { - //Double packet timeout lock (p.Timer) { if (!p.Acknowledged) { - p.Timer.Change(p.LastTimeout *= 2, Timeout.Infinite); - if (++p.Retransmissions > ResendsBeforeDisconnect) + // Backoff retry frequency to avoid congestion + p.LastTimeout = (int)Math.Min(p.LastTimeout * 1.5f, this.disconnectTimeout / 2f); + p.Timer.Change(p.LastTimeout, Timeout.Infinite); + + if (p.Stopwatch.ElapsedMilliseconds > this.disconnectTimeout) { - HandleDisconnect(); + HandleDisconnect(new HazelException($"Reliable packet {id} was not ack'd after {p.Retransmissions} resends")); //Set acknowledged so we dont change the timer again p.Acknowledged = true; @@ -208,6 +209,7 @@ namespace Hazel.Udp try { WriteBytesToConnection(p.Data, sendLength); + p.Retransmissions++; } catch (InvalidOperationException e) { @@ -217,7 +219,7 @@ namespace Hazel.Udp Trace.WriteLine("Resend."); }, - resendTimeout > 0 ? resendTimeout : (AveragePingMs != 0 ? (int)AveragePingMs * 4 : 200), + resendTimeout > 0 ? resendTimeout : (AveragePingMs != 0 ? (int)AveragePingMs * 2 : 200), ackCallback ); diff --git a/Hazel/Udp/UdpConnection.cs b/Hazel/Udp/UdpConnection.cs index 19434ea..4329fdf 100644 --- a/Hazel/Udp/UdpConnection.cs +++ b/Hazel/Udp/UdpConnection.cs @@ -184,7 +184,7 @@ namespace Hazel.Udp break; case (byte)UdpSendOption.Disconnect: - HandleDisconnect(); + HandleDisconnect(new HazelException("The remote sent a disconnect request")); break; //Handle fragmented messages