]> git.deb.at Git - rhonda/impostor.hazel.git/commitdiff
Add the ability to send extra data along side a disconnect message
authorForest <chocozilla@gmail.com>
Thu, 20 Jun 2019 21:13:36 +0000 (14:13 -0700)
committerForest <chocozilla@gmail.com>
Thu, 20 Jun 2019 21:13:36 +0000 (14:13 -0700)
Hazel.UnitTests/UdpConnectionTests.cs
Hazel/Connection.cs
Hazel/ConnectionState.cs
Hazel/DisconnectedEventArgs.cs
Hazel/MessageWriter.cs
Hazel/NetworkConnection.cs
Hazel/Udp/UdpClientConnection.cs
Hazel/Udp/UdpConnection.cs
Hazel/Udp/UdpServerConnection.cs

index d363a235071703b6d761ef54e7e6343ef9bd816a..efd485752d21d3b096d4260bc7f3683f111d69d2 100644 (file)
@@ -64,7 +64,7 @@ namespace Hazel.UnitTests
                 connection.Connect();
                 connection.Dispose();
 
-                Thread.Sleep(50);
+                Thread.Sleep(100);
 
                 Assert.IsTrue(serverConnected);
                 Assert.IsTrue(serverDisconnected);
index f30d948054209cb4ebfb355b5eb3e482578f7c0c..3615c51064085c0829c1285b44f9599e2a09309e 100644 (file)
@@ -202,11 +202,6 @@ namespace Hazel
         /// </remarks>
         public abstract void ConnectAsync(byte[] bytes = null, int timeout = 5000);
 
-        /// <summary>
-        ///     Sends a disconnect message to the end point.
-        /// </summary>
-        protected abstract void SendDisconnect();
-
         /// <summary>
         ///     Invokes the DataReceived event.
         /// </summary>
@@ -235,19 +230,19 @@ namespace Hazel
         ///     Invokes the Disconnected event.
         /// </summary>
         /// <param name="e">The exception, if any, that occured to cause this.</param>
+        /// <param name="reader">Extra disconnect data</param>
         /// <remarks>
         ///     Invokes the <see cref="Disconnected"/> event to alert subscribres this connection has been disconnected either 
         ///     by the end point or because an error occured. If an error occured the error should be passed in in order to 
         ///     pass to the subscribers, otherwise null can be passed in.
         /// </remarks>
-        protected void InvokeDisconnected(string e)
+        protected void InvokeDisconnected(string e, MessageReader reader)
         {
             //Make a copy to avoid race condition between null check and invocation
             EventHandler<DisconnectedEventArgs> handler = Disconnected;
             if (handler != null)
             {
-                DisconnectedEventArgs args = DisconnectedEventArgs.GetObject();
-                args.Set(e);
+                DisconnectedEventArgs args = new DisconnectedEventArgs(e, reader);
                 handler.Invoke(this, args);
             }
         }
@@ -270,7 +265,7 @@ namespace Hazel
         /// For times when you want to force the disconnect handler to fire as well as close it.
         /// If you only want to close it, just use Dispose.
         /// </summary>
-        public abstract void Disconnect(string reason);
+        public abstract void Disconnect(string reason, MessageWriter writer = null, bool fireEvent = true);
         
         /// <summary>
         ///     Disposes of this NetworkConnection.
index 5036b90bf13a4743c6b82fa131aa33c5379c94ac..5d3f5c909ecc50c7e399800a2088fe7ee9f14b0e 100644 (file)
@@ -24,10 +24,5 @@ namespace Hazel
         ///     The Connection is connected and data can be transfered.
         /// </summary>
         Connected,
-
-        /// <summary>
-        ///     The Connection is currently disconnecting.
-        /// </summary>
-        Disconnecting
     }
 }
index 58969c4291019c40d1b9a944059c7f7fbf1347b8..3d87d66a499c7cea145b7e29f638fbdeb7b680a7 100644 (file)
@@ -18,15 +18,6 @@ namespace Hazel
     /// <threadsafety static="true" instance="true"/>
     public class DisconnectedEventArgs : EventArgs
     {
-        /// <summary>
-        ///     Returns an instance of this object from the pool.
-        /// </summary>
-        /// <returns>A new or recycled DisconnectedEventArgs object.</returns>
-        internal static DisconnectedEventArgs GetObject()
-        {
-            return new DisconnectedEventArgs();
-        }
-
         /// <summary>
         ///     The exception, if any, that caused the disconnect.
         /// </summary>
@@ -36,23 +27,13 @@ namespace Hazel
         ///     that caused it or a <see cref="HazelException"/> with the details of the exception, if the disconnection 
         ///     wasn't caused by an error then this will contain null.
         /// </remarks>
-        public string Reason { get; private set; }
+        public readonly string Reason;
 
-        /// <summary>
-        ///     Private constructor for object pool.
-        /// </summary>
-        DisconnectedEventArgs()
-        {
-
-        }
+        public readonly MessageReader Message;
 
-        /// <summary>
-        ///     Sets the given exception for the arguments.
-        /// </summary>
-        /// <param name="e">The exception if the cause.</param>
-        internal void Set(string reason)
+        public DisconnectedEventArgs(string reason, MessageReader reader)
         {
-            this.Reason = reason;
+
         }
     }
 }
index 37d9c94e523609d335e03265e5144b5a078f70f6..95b01436f6b27cf780e3c15bea48bdf2d827e5a2 100644 (file)
@@ -43,13 +43,13 @@ namespace Hazel
             {
                 switch (this.SendOption)
                 {
-                    case Hazel.SendOption.Reliable:
+                    case SendOption.Reliable:
                         {
                             byte[] output = new byte[this.Length - 3];
                             System.Buffer.BlockCopy(this.Buffer, 3, output, 0, this.Length - 3);
                             return output;
                         }
-                    case Hazel.SendOption.None:
+                    case SendOption.None:
                         {
                             byte[] output = new byte[this.Length - 1];
                             System.Buffer.BlockCopy(this.Buffer, 1, output, 0, this.Length - 1);
index c6426fc051df08d6e3b14d172cd29aacc203e79b..ba818229d47acdd6336ebd1c2ed918d75246c90b 100644 (file)
@@ -35,27 +35,23 @@ namespace Hazel
             }
         }
 
+        /// <summary>
+        ///     Sends a disconnect message to the end point.
+        /// </summary>
+        protected abstract bool SendDisconnect(MessageWriter writer);
+
+
         /// <summary>
         ///     Called when the socket has been disconnected at the remote host.
         /// </summary>
         /// <param name="e">The exception if one was the cause.</param>
-        public override void Disconnect(string reason)
+        public override void Disconnect(string reason, MessageWriter writer = null, bool fireEvent = true)
         {
-            bool invoke = false;
-            lock (this)
-            {
-                if (this._state == ConnectionState.Connected)
-                {
-                    this._state = ConnectionState.Disconnecting;
-                    invoke = true;
-                }
-            }
-
-            if (invoke)
+            if (this.SendDisconnect(writer) && fireEvent)
             {
                 try
                 {
-                    InvokeDisconnected(reason);
+                    InvokeDisconnected(reason, null);
                 }
                 catch { }
             }
index a09f83040eee0750dfba0ae80221ff8b8a062e9f..7d155f2aed92b2ce4c4be18b35968eba810cfdff 100644 (file)
@@ -262,19 +262,37 @@ namespace Hazel.Udp
 
         /// <summary>
         ///     Sends a disconnect message to the end point.
+        ///     You may include optional disconnect data. The SendOption must be unreliable.
         /// </summary>
-        protected override void SendDisconnect()
+        protected override bool SendDisconnect(MessageWriter data = null)
         {
+            lock (this)
+            {
+                if (this._state != ConnectionState.Connected) return false;
+                this._state = ConnectionState.NotConnected;
+            }
+
+            var bytes = EmptyDisconnectBytes;
+            if (data != null && data.Length > 0)
+            {
+                if (data.SendOption != SendOption.None) throw new ArgumentException("Disconnect messages can only be unreliable.");
+
+                bytes = data.ToByteArray(true);
+                bytes[0] = (byte)UdpSendOption.Disconnect;
+            }
+
             try
             {
                 socket.SendTo(
-                    DisconnectBytes,
+                    bytes,
                     0,
-                    1,
+                    bytes.Length,
                     SocketFlags.None,
                     RemoteEndPoint);
             }
             catch { }
+
+            return true;
         }
 
         /// <inheritdoc />
@@ -282,12 +300,7 @@ namespace Hazel.Udp
         {
             if (disposing)
             {
-                if (this._state == ConnectionState.Connected
-                    || this._state == ConnectionState.Disconnecting)
-                {
-                    this._state = ConnectionState.NotConnected;
-                    SendDisconnect();
-                }
+                SendDisconnect();
             }
 
             if (this.socket != null)
index c1e6cf4f7327b411d85a1606bc4d75f90cfa6a17..8889a1fe98beddd75c05d04a9155ab23d8101410 100644 (file)
@@ -1,11 +1,4 @@
 using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading;
 
 namespace Hazel.Udp
 {
@@ -15,7 +8,7 @@ namespace Hazel.Udp
     /// <inheritdoc />
     public abstract partial class UdpConnection : NetworkConnection
     {
-        protected static readonly byte[] DisconnectBytes = new byte[] { (byte)UdpSendOption.Disconnect };
+        protected static readonly byte[] EmptyDisconnectBytes = new byte[] { (byte)UdpSendOption.Disconnect };
 
         /// <summary>
         ///     Creates a new UdpConnection and initializes the keep alive timer.
index 1d01c7606db39a1fc7ca2cb4185e0dd16c0645f6..9dad8c73020ef7f4dd8331598e3e7f83056f090e 100644 (file)
@@ -59,17 +59,33 @@ namespace Hazel.Udp
             throw new InvalidOperationException("Cannot manually connect a UdpServerConnection, did you mean to use UdpClientConnection?");
         }
 
-
         /// <summary>
         ///     Sends a disconnect message to the end point.
         /// </summary>
-        protected override void SendDisconnect()
+        protected override bool SendDisconnect(MessageWriter data = null)
         {
+            lock (this)
+            {
+                if (this._state != ConnectionState.Connected) return false;
+                this._state = ConnectionState.NotConnected;
+            }
+            
+            var bytes = EmptyDisconnectBytes;
+            if (data != null && data.Length > 0)
+            {
+                if (data.SendOption != SendOption.None) throw new ArgumentException("Disconnect messages can only be unreliable.");
+
+                bytes = data.ToByteArray(true);
+                bytes[0] = (byte)UdpSendOption.Disconnect;
+            }
+
             try
             {
-                Listener.SendDataSync(DisconnectBytes, 1, RemoteEndPoint);
+                Listener.SendDataSync(bytes, bytes.Length, RemoteEndPoint);
             }
             catch { }
+
+            return true;
         }
 
         protected override void Dispose(bool disposing)
@@ -78,12 +94,7 @@ namespace Hazel.Udp
 
             if (disposing)
             {
-                if (this._state == ConnectionState.Connected
-                    || this._state == ConnectionState.Disconnecting)
-                {
-                    this._state = ConnectionState.NotConnected;
-                    SendDisconnect();
-                }
+                SendDisconnect();
             }