Просмотр исходного кода

ENetCS accept只能处理为回调事件,否则无法循环accept. 单元测试,通过

tanghai 13 лет назад
Родитель
Сommit
60804d7fb6

+ 4 - 3
CSharp/Platform/ENetCS/ClientHost.cs

@@ -49,7 +49,7 @@ namespace ENet
 
 		public void RunOnce(int timeout = 0)
 		{
-			this.OnExecuteEvents();
+			this.OnEvents();
 
 			if (this.Service(timeout) < 0)
 			{
@@ -82,8 +82,9 @@ namespace ENet
 						var peer = this.PeersManager[ev.PeerPtr];
 						PeerEvent peerEvent = peer.PeerEvent;
 
-						this.PeersManager.Remove(ev.PeerPtr);
-						peer.Dispose();
+						this.PeersManager.Remove(peer.PeerPtr);
+						// enet_peer_disconnect会reset Peer,这里设置为0,防止再次Dispose
+						peer.PeerPtr = IntPtr.Zero;
 
 						if (peerEvent.Received != null)
 						{

+ 2 - 2
CSharp/Platform/ENetCS/Host.cs

@@ -80,7 +80,7 @@ namespace ENet
 
 		public void Broadcast(byte channelID, ref Packet packet)
 		{
-			NativeMethods.enet_host_broadcast(this.host, channelID, packet.NativePtr);
+			NativeMethods.enet_host_broadcast(this.host, channelID, packet.PacketPtr);
 		}
 
 		public void CompressWithRangeEncoder()
@@ -127,7 +127,7 @@ namespace ENet
 			}
 		}
 
-		protected void OnExecuteEvents()
+		protected void OnEvents()
 		{
 			Action local = null;
 			lock (this.eventsLock)

+ 6 - 1
CSharp/Platform/ENetCS/Packet.cs

@@ -1,6 +1,7 @@
 using System;
 using System.IO;
 using System.Runtime.InteropServices;
+using Log;
 
 namespace ENet
 {
@@ -60,12 +61,16 @@ namespace ENet
 			}
 		}
 
-		public IntPtr NativePtr
+		public IntPtr PacketPtr
 		{
 			get
 			{
 				return this.packet;
 			}
+			set
+			{
+				this.packet = value;
+			}
 		}
 
 		public uint Length

+ 31 - 20
CSharp/Platform/ENetCS/Peer.cs

@@ -8,11 +8,11 @@ namespace ENet
 	public sealed class Peer: IDisposable
 	{
 		private readonly PeerEvent peerEvent = new PeerEvent();
-		private IntPtr peer;
+		private IntPtr peerPtr;
 
-		public Peer(IntPtr peer)
+		public Peer(IntPtr peerPtr)
 		{
-			this.peer = peer;
+			this.peerPtr = peerPtr;
 		}
 
 		~Peer()
@@ -28,28 +28,39 @@ namespace ENet
 
 		private void Dispose(bool disposing)
 		{
-			if (this.peer == IntPtr.Zero)
+			if (this.peerPtr == IntPtr.Zero)
 			{
 				return;
 			}
+			NativeMethods.enet_peer_reset(this.peerPtr);
+			this.peerPtr = IntPtr.Zero;
+		}
 
-			NativeMethods.enet_peer_reset(this.peer);
-			this.peer = IntPtr.Zero;
+		public IntPtr PeerPtr
+		{
+			get
+			{
+				return this.peerPtr;
+			}
+			set
+			{
+				this.peerPtr = value;
+			}
 		}
 
 		private ENetPeer Struct
 		{
 			get
 			{
-				if (this.peer == IntPtr.Zero)
+				if (this.peerPtr == IntPtr.Zero)
 				{
 					return new ENetPeer();
 				}
-				return (ENetPeer) Marshal.PtrToStructure(this.peer, typeof (ENetPeer));
+				return (ENetPeer) Marshal.PtrToStructure(this.peerPtr, typeof (ENetPeer));
 			}
 			set
 			{
-				Marshal.StructureToPtr(value, this.peer, false);
+				Marshal.StructureToPtr(value, this.peerPtr, false);
 			}
 		}
 
@@ -65,7 +76,7 @@ namespace ENet
 		{
 			get
 			{
-				if (this.peer == IntPtr.Zero)
+				if (this.peerPtr == IntPtr.Zero)
 				{
 					return PeerState.Uninitialized;
 				}
@@ -75,25 +86,25 @@ namespace ENet
 
 		public void Ping()
 		{
-			NativeMethods.enet_peer_ping(this.peer);
+			NativeMethods.enet_peer_ping(this.peerPtr);
 		}
 
 		public void ConfigureThrottle(uint interval, uint acceleration, uint deceleration)
 		{
-			NativeMethods.enet_peer_throttle_configure(this.peer, interval, acceleration, deceleration);
+			NativeMethods.enet_peer_throttle_configure(this.peerPtr, interval, acceleration, deceleration);
 		}
 
 		public void Send(byte channelID, byte[] data)
 		{
-			using (var packet = new Packet(data))
-			{
-				this.Send(channelID, packet);
-			}
+			var packet = new Packet(data);
+			this.Send(channelID, packet);
 		}
 
 		public void Send(byte channelID, Packet packet)
 		{
-			NativeMethods.enet_peer_send(this.peer, channelID, packet.NativePtr);
+			NativeMethods.enet_peer_send(this.peerPtr, channelID, packet.PacketPtr);
+			// enet_peer_send函数会自动删除packet,设置为0,防止Dispose或者析构函数再次删除
+			packet.PacketPtr = IntPtr.Zero;
 		}
 
 		public Task<Packet> ReceiveAsync()
@@ -113,23 +124,23 @@ namespace ENet
 
 		public Task<bool> DisconnectAsync(uint data = 0)
 		{
+			NativeMethods.enet_peer_disconnect(this.peerPtr, data);
 			var tcs = new TaskCompletionSource<bool>();
 			this.PeerEvent.Disconnect += e => tcs.TrySetResult(true);
-			NativeMethods.enet_peer_disconnect(this.peer, data);
 			return tcs.Task;
 		}
 
 		public Task<bool> DisconnectLaterAsync(uint data = 0)
 		{
+			NativeMethods.enet_peer_disconnect_later(this.peerPtr, data);
 			var tcs = new TaskCompletionSource<bool>();
 			this.PeerEvent.Disconnect += e => tcs.TrySetResult(true);
-			NativeMethods.enet_peer_disconnect_later(this.peer, data);
 			return tcs.Task;
 		}
 
 		public void DisconnectNow(uint data)
 		{
-			NativeMethods.enet_peer_disconnect_now(this.peer, data);
+			NativeMethods.enet_peer_disconnect_now(this.peerPtr, data);
 		}
 	}
 }

+ 14 - 19
CSharp/Platform/ENetCS/ServerHost.cs

@@ -6,9 +6,10 @@ namespace ENet
 {
 	public sealed class ServerHost : Host
 	{
-		private Action<Event> acceptEvent;
+		private Action<Peer> acceptEvent;
 
-		public ServerHost(Address address, uint peerLimit = NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID,
+		public ServerHost(Address address, 
+				uint peerLimit = NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID,
 				uint channelLimit = 0, uint incomingBandwidth = 0,
 				uint outgoingBandwidth = 0, bool enableCrc = true)
 		{
@@ -34,25 +35,17 @@ namespace ENet
 			}
 		}
 
-		public Task<Peer> AcceptAsync()
+		public Action<Peer> AcceptEvent
 		{
-			if (this.acceptEvent != null)
+			set
 			{
-				throw new ENetException(0, "don't accept twice, when last accept not return!");
+				this.acceptEvent = value;
 			}
-			var tcs = new TaskCompletionSource<Peer>();
-			this.acceptEvent += e =>
-			{
-				var peer = new Peer(e.PeerPtr);
-				this.PeersManager.Add(e.PeerPtr, peer);
-				tcs.TrySetResult(peer);
-			};
-			return tcs.Task;
 		}
 
 		public void RunOnce(int timeout = 0)
 		{
-			this.OnExecuteEvents();
+			this.OnEvents();
 
 			if (this.Service(timeout) < 0)
 			{
@@ -66,11 +59,13 @@ namespace ENet
 				{
 					case EventType.Connect:
 					{
-						if (this.acceptEvent != null)
+						if (this.acceptEvent == null)
 						{
-							this.acceptEvent(ev);
-							this.acceptEvent = null;
+							throw new ENetException(4, "No Accept Event!");
 						}
+						var peer = new Peer(ev.PeerPtr);
+						this.PeersManager.Add(peer.PeerPtr, peer);
+						this.acceptEvent(peer);
 						break;
 					}
 					case EventType.Receive:
@@ -88,7 +83,8 @@ namespace ENet
 						PeerEvent peerEvent = peer.PeerEvent;
 
 						this.PeersManager.Remove(ev.PeerPtr);
-						peer.Dispose();
+						// enet_peer_disconnect会reset Peer,这里设置为0,防止再次Dispose
+						peer.PeerPtr = IntPtr.Zero;
 						
 						if (peerEvent.Received != null)
 						{
@@ -98,7 +94,6 @@ namespace ENet
 						{
 							peerEvent.OnDisconnect(ev);
 						}
-						
 						break;
 					}
 				}

+ 33 - 51
CSharp/Platform/ENetCSTest/ENetClientServerTest.cs

@@ -1,8 +1,6 @@
-using System;
-using System.Threading;
+using System.Threading;
 using ENet;
 using Helper;
-using Log;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 
 namespace ENetCSTest
@@ -10,60 +8,40 @@ namespace ENetCSTest
 	[TestClass]
 	public class ENetClientServerTest
 	{
-		private static async void Client(ClientHost host, Address address)
+		private static async void ClientEvent(ClientHost host, Address address)
 		{
-			try
+			using (var peer = await host.ConnectAsync(address))
 			{
-				Logger.Debug("Client Connect");
-				var peer = await host.ConnectAsync(address);
-				Logger.Debug("Client Connect OK");
-				var sPacket = new Packet("0123456789".ToByteArray(), PacketFlags.Reliable);
-				peer.Send(0, sPacket);
-				Logger.Debug("Client Send OK");
-				var rPacket = await peer.ReceiveAsync();
-				Logger.Debug("Client Receive OK");
+				using (var sPacket = new Packet("0123456789".ToByteArray(), PacketFlags.Reliable))
+				{
+					peer.Send(0, sPacket);
+				}
 
-				CollectionAssert.AreEqual("9876543210".ToByteArray(), rPacket.Bytes);
+				using (var rPacket = await peer.ReceiveAsync())
+				{
+					CollectionAssert.AreEqual("9876543210".ToByteArray(), rPacket.Bytes);
+				}
 
 				await peer.DisconnectLaterAsync();
-				Logger.Debug("Client Disconnect OK");
-			}
-			catch (ENetException e)
-			{
-				Assert.Fail("Client ENetException: {0}", e.Message);
-			}
-			finally
-			{
-				host.Stop();
 			}
+			host.Stop();
 		}
 
-		private static async void Server(ServerHost host)
+		private static async void OnAccept(ServerHost host, Peer peer)
 		{
-			try
+			using (var rPacket = await peer.ReceiveAsync())
 			{
-				Logger.Debug("Server Accept");
-				var peer = await host.AcceptAsync();
-				Logger.Debug("Server Accept OK");
-				var rPacket = await peer.ReceiveAsync();
-				Logger.Debug("Server Receive OK");
-
 				CollectionAssert.AreEqual("0123456789".ToByteArray(), rPacket.Bytes);
-
-				var sPacket = new Packet("9876543210".ToByteArray(), PacketFlags.Reliable);
-				peer.Send(0, sPacket);
-				Logger.Debug("Server Send OK");
-				await peer.DisconnectLaterAsync();
-				Logger.Debug("Server Disconnected OK");
-			}
-			catch (ENetException e)
-			{
-				Assert.Fail("Server ENetException: {0}", e.Message);
 			}
-			finally
+
+			using(var sPacket = new Packet("9876543210".ToByteArray(), PacketFlags.Reliable))
 			{
-				host.Stop();
+				peer.Send(0, sPacket);
+				host.Flush();
 			}
+
+			// Client断开,Server端收到Disconnect事件,结束Server线程
+			peer.PeerEvent.Disconnect += (ev) => host.Stop();
 		}
 
 		[TestMethod]
@@ -73,16 +51,20 @@ namespace ENetCSTest
 			var clientHost = new ClientHost();
 			var serverHost = new ServerHost(address);
 
-			var server = new Thread(() => serverHost.Start(10));
-			var client = new Thread(() => clientHost.Start(10));
+			// accept回调事件
+			serverHost.AcceptEvent = peer => OnAccept(serverHost, peer);
+
+			var serverThread = new Thread(() => serverHost.Start(10));
+			var clientThread = new Thread(() => clientHost.Start(10));
+
+			serverThread.Start();
+			clientThread.Start();
 
-			serverHost.Events += () => Server(serverHost);
-			clientHost.Events += () => Client(clientHost, address);
-			server.Start();
-			client.Start();
+			// 往client host线程增加事件,client线程连接server
+			clientHost.Events += () => ClientEvent(clientHost, address);
 
-			server.Join();
-			client.Join();
+			serverThread.Join();
+			clientThread.Join();
 		}
 	}
 }

+ 12 - 2
CSharp/Platform/Log/Logger.cs

@@ -17,9 +17,19 @@
 			globalLogger.Trace(message);
 		}
 
-		public static void Debug(string message)
+		public static void Trace(string format, params object[] args)
 		{
-			globalLogger.Debug(message);
+			globalLogger.Trace(string.Format(format, args));
+		}
+
+		public static void Debug(string format)
+		{
+			globalLogger.Debug(format);
+		}
+
+		public static void Debug(string format, params object[] args)
+		{
+			globalLogger.Debug(string.Format(format, args));
 		}
 	}
 }