From: Matthew Endsley Date: Sun, 28 Feb 2021 23:48:25 +0000 (-0800) Subject: Ensure Unity clients send a Disconnect packet when disposed X-Git-Tag: 1.0.0~19^2~1 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=49769557a995a963e7e933ed7cb0d69c9e42a2ce;p=rhonda%2Fimpostor.hazel.git Ensure Unity clients send a Disconnect packet when disposed --- diff --git a/Hazel.UnitTests/TestHelper.cs b/Hazel.UnitTests/TestHelper.cs index 39071c1..082854e 100644 --- a/Hazel.UnitTests/TestHelper.cs +++ b/Hazel.UnitTests/TestHelper.cs @@ -1,4 +1,4 @@ -using System; +using System; using Microsoft.VisualStudio.TestTools.UnitTesting; using Hazel; @@ -270,6 +270,43 @@ namespace Hazel.UnitTests mutex2.WaitOne(); } + /// + /// Ensures a client sends a disconnect packet to the server on Dispose. + /// + /// The listener to test. + /// The connection to test. + internal static void RunClientDisconnectOnDisposeTest(NetworkConnectionListener listener, Connection connection) + { + ManualResetEvent mutex = new ManualResetEvent(false); + ManualResetEvent mutex2 = new ManualResetEvent(false); + + listener.NewConnection += delegate (NewConnectionEventArgs args) + { + args.Connection.Disconnected += delegate (object sender2, DisconnectedEventArgs args2) + { + mutex2.Set(); + }; + + mutex.Set(); + }; + + listener.Start(); + + connection.Connect(); + + if (!mutex.WaitOne(TimeSpan.FromSeconds(1))) + { + Assert.Fail("Timeout waiting for client connection"); + } + + connection.Dispose(); + + if (!mutex2.WaitOne(TimeSpan.FromSeconds(1))) + { + Assert.Fail("Timeout waiting for client disconnect packet"); + } + } + /// /// Builds new data of increaseing value bytes. /// diff --git a/Hazel.UnitTests/UdpConnectionTests.cs b/Hazel.UnitTests/UdpConnectionTests.cs index 2421268..1b3fb27 100644 --- a/Hazel.UnitTests/UdpConnectionTests.cs +++ b/Hazel.UnitTests/UdpConnectionTests.cs @@ -444,6 +444,18 @@ namespace Hazel.UnitTests } } + /// + /// Test that a disconnect is sent when the client is disposed. + /// + public void ClientDisconnectOnDisposeTest() + { + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UdpClientConnection(new IPEndPoint(IPAddress.Loopback, 4296))) + { + TestHelper.RunClientDisconnectOnDisposeTest(listener, connection); + } + } + /// /// Tests disconnection from the server. /// diff --git a/Hazel.UnitTests/UnityUdpConnectionTests.cs b/Hazel.UnitTests/UnityUdpConnectionTests.cs index 4f989c5..83f62fc 100644 --- a/Hazel.UnitTests/UnityUdpConnectionTests.cs +++ b/Hazel.UnitTests/UnityUdpConnectionTests.cs @@ -414,6 +414,18 @@ namespace Hazel.UnitTests } } + /// + /// Test that a disconnect is sent when the client is disposed. + /// + public void ClientDisconnectOnDisposeTest() + { + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UnityUdpClientConnection(new IPEndPoint(IPAddress.Loopback, 4296))) + { + TestHelper.RunClientDisconnectOnDisposeTest(listener, connection); + } + } + /// /// Tests disconnection from the server. /// diff --git a/Hazel/Udp/UnityUdpClientConnection.cs b/Hazel/Udp/UnityUdpClientConnection.cs index 8b50180..25eb4db 100644 --- a/Hazel/Udp/UnityUdpClientConnection.cs +++ b/Hazel/Udp/UnityUdpClientConnection.cs @@ -14,6 +14,7 @@ namespace Hazel.Udp public class UnityUdpClientConnection : UdpConnection { private Socket socket; + private bool sendSynchronously = false; public UnityUdpClientConnection(IPEndPoint remoteEndPoint, IPMode ipMode = IPMode.IPv4) : base() @@ -49,14 +50,26 @@ namespace Hazel.Udp { try { - socket.BeginSendTo( - bytes, - 0, - length, - SocketFlags.None, - EndPoint, - HandleSendTo, - null); + if (this.sendSynchronously) + { + socket.SendTo( + bytes, + 0, + length, + SocketFlags.None, + EndPoint); + } + else + { + socket.BeginSendTo( + bytes, + 0, + length, + SocketFlags.None, + EndPoint, + HandleSendTo, + null); + } } catch (NullReferenceException) { } catch (ObjectDisposedException) @@ -246,6 +259,8 @@ namespace Hazel.Udp /// protected override void Dispose(bool disposing) { + this.sendSynchronously = true; + if (disposing) { SendDisconnect();