From e14fcb6974d94887f3d591ca158c0063b7aa7563 Mon Sep 17 00:00:00 2001 From: Forest Date: Sun, 30 Dec 2018 21:02:44 -0800 Subject: [PATCH] Slight optimizations to disconnect --- Hazel/Connection.cs | 14 -------------- Hazel/Udp/UdpClientConnection.cs | 21 +++++++++++++++++++-- Hazel/Udp/UdpConnection.cs | 27 ++++++++++----------------- Hazel/Udp/UdpConnectionListener.cs | 7 +++++-- Hazel/Udp/UdpServerConnection.cs | 20 +++++++++++++++----- 5 files changed, 49 insertions(+), 40 deletions(-) diff --git a/Hazel/Connection.cs b/Hazel/Connection.cs index 5a8e991..f136ffc 100644 --- a/Hazel/Connection.cs +++ b/Hazel/Connection.cs @@ -52,18 +52,6 @@ namespace Hazel public int TestLagMs = -1; - public event Action DataSentRaw; - protected void InvokeDataSentRaw(byte[] data, int length) - { - this.DataSentRaw?.Invoke(data, length); - } - - public event Action DataReceivedRaw; - protected void InvokeDataReceivedRaw(byte[] data) - { - this.DataReceivedRaw?.Invoke(data); - } - /// /// Called when the end point disconnects or an error occurs. /// @@ -319,8 +307,6 @@ namespace Hazel if (disposing) { this.DataReceived = null; - this.DataReceivedRaw = null; - this.DataSentRaw = null; this.Disconnected = null; } } diff --git a/Hazel/Udp/UdpClientConnection.cs b/Hazel/Udp/UdpClientConnection.cs index f4ccc1a..048ff60 100644 --- a/Hazel/Udp/UdpClientConnection.cs +++ b/Hazel/Udp/UdpClientConnection.cs @@ -70,9 +70,13 @@ namespace Hazel.Udp } } + + public event Action DataSentRaw; + public event Action DataReceivedRaw; + private void WriteBytesToConnectionReal(byte[] bytes, int length) { - InvokeDataSentRaw(bytes, length); + DataSentRaw?.Invoke(bytes, length); if (State != ConnectionState.Connected && State != ConnectionState.Connecting) throw new InvalidOperationException("Could not send data as this Connection is not connected and is not connecting. Did you disconnect?"); @@ -117,7 +121,7 @@ namespace Hazel.Udp protected override void WriteBytesToConnectionSync(byte[] bytes, int length) { - InvokeDataSentRaw(bytes, length); + DataSentRaw?.Invoke(bytes, length); if (State != ConnectionState.Connected && State != ConnectionState.Connecting) throw new InvalidOperationException("Could not send data as this Connection is not connected and is not connecting. Did you disconnect?"); @@ -266,10 +270,23 @@ namespace Hazel.Udp Thread.Sleep(this.TestLagMs); } + DataReceivedRaw?.Invoke(bytes); MessageReader msg = MessageReader.GetRaw(bytes, 0, bytesReceived); HandleReceive(msg, bytesReceived); } + /// + /// Sends a disconnect message to the end point. + /// + protected override void SendDisconnect() + { + try + { + WriteBytesToConnectionSync(DisconnectBytes, 1); + } + catch { } + } + /// protected override void Dispose(bool disposing) { diff --git a/Hazel/Udp/UdpConnection.cs b/Hazel/Udp/UdpConnection.cs index 89e80e5..a488cde 100644 --- a/Hazel/Udp/UdpConnection.cs +++ b/Hazel/Udp/UdpConnection.cs @@ -15,6 +15,8 @@ namespace Hazel.Udp /// public abstract partial class UdpConnection : NetworkConnection { + protected static readonly byte[] DisconnectBytes = new byte[] { (byte)UdpSendOption.Disconnect }; + /// /// Creates a new UdpConnection and initializes the keep alive timer. /// @@ -146,8 +148,6 @@ namespace Hazel.Udp /// The buffer containing the bytes received. protected internal void HandleReceive(MessageReader message, int bytesReceived) { - InvokeDataReceivedRaw(message.Buffer); - ushort id; switch (message.Buffer[0]) { @@ -174,7 +174,7 @@ namespace Hazel.Udp break; case (byte)UdpSendOption.Disconnect: - Disconnect("The remote sent a disconnect request"); + Disconnect("The remote sent a disconnect request", true); message.Recycle(); break; @@ -260,13 +260,18 @@ namespace Hazel.Udp /// /// The exception if one was the cause. public override void Disconnect(string reason) + { + this.Disconnect(reason, false); + } + + protected void Disconnect(string reason, bool skipSendDisconnect) { bool invoke = false; lock (this) { if (this.state == ConnectionState.Connected) { - this.state = ConnectionState.Disconnecting; + this.state = skipSendDisconnect ? ConnectionState.NotConnected : ConnectionState.Disconnecting; invoke = true; } } @@ -282,19 +287,7 @@ namespace Hazel.Udp this.Dispose(); } - - /// - /// Sends a disconnect message to the end point. - /// - protected override void SendDisconnect() - { - try - { - WriteBytesToConnectionSync(new byte[] { (byte)UdpSendOption.Disconnect }, 1); - } - catch { } - } - + /// protected override void Dispose(bool disposing) { diff --git a/Hazel/Udp/UdpConnectionListener.cs b/Hazel/Udp/UdpConnectionListener.cs index 75ea137..e8f4def 100644 --- a/Hazel/Udp/UdpConnectionListener.cs +++ b/Hazel/Udp/UdpConnectionListener.cs @@ -134,10 +134,12 @@ namespace Hazel.Udp /// The asyncronous operation's result. public int ActiveListeners; + public int PacketsReceived; void ReadCallback(IAsyncResult result) { Interlocked.Decrement(ref ActiveListeners); + Interlocked.Increment(ref PacketsReceived); var message = (MessageReader)result.AsyncState; int bytesReceived; @@ -170,11 +172,12 @@ namespace Hazel.Udp return; } - // Exit if no bytes read, we've closed. + // I'm a little concerned about a infinite loop here, but it seems like it's possible + // to get 0 bytes read on UDP without the socket being shut down. if (bytesReceived == 0) { message.Recycle(); - this.Logger?.Invoke("Stopped due to receiving 0 bytes"); + StartListeningForData(); return; } diff --git a/Hazel/Udp/UdpServerConnection.cs b/Hazel/Udp/UdpServerConnection.cs index a9f56b3..b0f5058 100644 --- a/Hazel/Udp/UdpServerConnection.cs +++ b/Hazel/Udp/UdpServerConnection.cs @@ -47,8 +47,6 @@ namespace Hazel.Udp /// protected override void WriteBytesToConnection(byte[] bytes, int length) { - InvokeDataSentRaw(bytes, length); - if (State != ConnectionState.Connected) throw new InvalidOperationException("Could not send data: Not connected."); @@ -58,8 +56,6 @@ namespace Hazel.Udp /// protected override void WriteBytesToConnectionSync(byte[] bytes, int length) { - InvokeDataSentRaw(bytes, length); - // No throw: As an internal interface, I want to try sending bytes whenever the I feel like it. Listener.SendDataSync(bytes, length, RemoteEndPoint); @@ -82,7 +78,20 @@ namespace Hazel.Udp { throw new HazelException("Cannot manually connect a UdpServerConnection, did you mean to use UdpClientConnection?"); } - + + + /// + /// Sends a disconnect message to the end point. + /// + protected override void SendDisconnect() + { + try + { + WriteBytesToConnection(DisconnectBytes, 1); + } + catch { } + } + protected override void Dispose(bool disposing) { Listener.RemoveConnectionTo(RemoteEndPoint); @@ -97,6 +106,7 @@ namespace Hazel.Udp } } + base.Dispose(disposing); } } -- 2.39.5