ソースを参照

ENetClientServerTest提出了StartAccept(EService service)方法,可以实现不停的accept了

tanghai 12 年 前
コミット
c7cac8d116
2 ファイル変更147 行追加141 行削除
  1. 140 139
      CSharp/Platform/ENet/ESocket.cs
  2. 7 2
      CSharp/Platform/ENetTest/ENetClientServerTest.cs

+ 140 - 139
CSharp/Platform/ENet/ESocket.cs

@@ -1,21 +1,21 @@
-using System;
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
 using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
+using System.Threading.Tasks;
+
 namespace ENet
 {
 	public sealed class ESocket: IDisposable
 	{
 		private IntPtr peerPtr = IntPtr.Zero;
-		private readonly EService service;
-		private readonly LinkedList<byte[]> recvBuffer = new LinkedList<byte[]>();
-
-		public Action<EEvent> Connected { get; set; }
-		public Action<EEvent> Received { get; set; }
-		public Action<EEvent> Disconnect { get; set; }
-		public Action<int> Error { get; set; }
-
+		private readonly EService service;
+		private readonly LinkedList<byte[]> recvBuffer = new LinkedList<byte[]>();
+
+		public Action<EEvent> Connected { get; set; }
+		public Action<EEvent> Received { get; set; }
+		public Action<EEvent> Disconnect { get; set; }
+		public Action<int> Error { get; set; }
+
 		public ESocket(EService service)
 		{
 			this.service = service;
@@ -100,58 +100,59 @@ namespace ENet
 			{
 				throw new EException("host connect call failed.");
 			}
-			this.service.PeersManager.Add(this.peerPtr, this);
-			this.Connected = eEvent =>
-			{
-				if (eEvent.EventState == EventState.DISCONNECTED)
-				{
-					tcs.TrySetException(new EException("socket disconnected in connect"));
-				}
-				tcs.TrySetResult(true);
+			this.service.PeersManager.Add(this.peerPtr, this);
+			this.Connected = eEvent =>
+			{
+				if (eEvent.EventState == EventState.DISCONNECTED)
+				{
+					tcs.TrySetException(new EException("socket disconnected in connect"));
+				}
+				tcs.TrySetResult(true);
 			};
 			return tcs.Task;
 		}
 
-		public Task<bool> AcceptAsync()
-		{
-			if (this.service.PeersManager.ContainsKey(IntPtr.Zero))
-			{
-				throw new EException("do not accept twice!");
-			}
-
-			var tcs = new TaskCompletionSource<bool>();
-
-			// 如果有请求连接缓存的包,从缓存中取
-			if (this.service.ConnEEvents.Count > 0)
-			{
-				EEvent eEvent = this.service.ConnEEvents.First.Value;
-				this.service.ConnEEvents.RemoveFirst();
-
-				this.PeerPtr = eEvent.PeerPtr;
-				this.service.PeersManager.Add(this.PeerPtr, this);
-
-				tcs.TrySetResult(true);
-			}
-			else
-			{
+		public Task<bool> AcceptAsync(Action action)
+		{
+			if (this.service.PeersManager.ContainsKey(IntPtr.Zero))
+			{
+				throw new EException("do not accept twice!");
+			}
+
+			var tcs = new TaskCompletionSource<bool>();
+
+			// 如果有请求连接缓存的包,从缓存中取
+			if (this.service.ConnEEvents.Count > 0)
+			{
+				EEvent eEvent = this.service.ConnEEvents.First.Value;
+				this.service.ConnEEvents.RemoveFirst();
+
+				this.PeerPtr = eEvent.PeerPtr;
 				this.service.PeersManager.Add(this.PeerPtr, this);
-				this.Connected = eEvent =>
-				{
-					if (eEvent.EventState == EventState.DISCONNECTED)
-					{
-						tcs.TrySetException(new EException("socket disconnected in accpet"));
-					}
-
-					this.service.PeersManager.Remove(IntPtr.Zero);
-
-					this.PeerPtr = eEvent.PeerPtr;
+				action();
+				tcs.TrySetResult(true);
+			}
+			else
+			{
+				this.service.PeersManager.Add(this.PeerPtr, this);
+				this.Connected = eEvent =>
+				{
+					if (eEvent.EventState == EventState.DISCONNECTED)
+					{
+						tcs.TrySetException(new EException("socket disconnected in accpet"));
+					}
+
+					this.service.PeersManager.Remove(IntPtr.Zero);
+
+					this.PeerPtr = eEvent.PeerPtr;
 					this.service.PeersManager.Add(this.PeerPtr, this);
-					tcs.TrySetResult(true); 
-				};
+					action();
+					tcs.TrySetResult(true); 
+				};
 			}
 			return tcs.Task;
-		}
-
+		}
+
 		public void WriteAsync(byte[] data, byte channelID = 0, PacketFlags flags = PacketFlags.Reliable)
 		{
 			var packet = new EPacket(data, flags);
@@ -162,39 +163,39 @@ namespace ENet
 
 		public Task<byte[]> ReadAsync()
 		{
-			var tcs = new TaskCompletionSource<byte[]>();
-
-			// 如果有缓存的包,从缓存中取
-			if (this.recvBuffer.Count > 0)
-			{
-				var bytes = this.recvBuffer.First.Value;
-				this.recvBuffer.RemoveFirst();
-				tcs.TrySetResult(bytes);
-			}
-			// 没有缓存封包,设置回调等待
-			else
-			{
-				this.Received = eEvent => 
-				{
-					if (eEvent.EventState == EventState.DISCONNECTED)
-					{
-						tcs.TrySetException(new EException("socket disconnected in receive"));
-					}
-
-					using (var packet = new EPacket(eEvent.PacketPtr))
-					{
-						var bytes = packet.Bytes;
-						tcs.TrySetResult(bytes);
-					}
-				};
-			}
+			var tcs = new TaskCompletionSource<byte[]>();
+
+			// 如果有缓存的包,从缓存中取
+			if (this.recvBuffer.Count > 0)
+			{
+				var bytes = this.recvBuffer.First.Value;
+				this.recvBuffer.RemoveFirst();
+				tcs.TrySetResult(bytes);
+			}
+			// 没有缓存封包,设置回调等待
+			else
+			{
+				this.Received = eEvent => 
+				{
+					if (eEvent.EventState == EventState.DISCONNECTED)
+					{
+						tcs.TrySetException(new EException("socket disconnected in receive"));
+					}
+
+					using (var packet = new EPacket(eEvent.PacketPtr))
+					{
+						var bytes = packet.Bytes;
+						tcs.TrySetResult(bytes);
+					}
+				};
+			}
 			return tcs.Task;
 		}
 
 		public Task<bool> DisconnectAsync(uint data = 0)
 		{
-			NativeMethods.EnetPeerDisconnect(this.peerPtr, data);
-			// EnetPeerDisconnect会reset Peer,这里设置为0,防止再次Dispose
+			NativeMethods.EnetPeerDisconnect(this.peerPtr, data);
+			// EnetPeerDisconnect会reset Peer,这里设置为0,防止再次Dispose
 			this.PeerPtr = IntPtr.Zero;
 			var tcs = new TaskCompletionSource<bool>();
 			this.Disconnect = eEvent => tcs.TrySetResult(true);
@@ -203,69 +204,69 @@ namespace ENet
 
 		public Task<bool> DisconnectLaterAsync(uint data = 0)
 		{
-			NativeMethods.EnetPeerDisconnectLater(this.peerPtr, data);
-			// EnetPeerDisconnect会reset Peer,这里设置为0,防止再次Dispose
+			NativeMethods.EnetPeerDisconnectLater(this.peerPtr, data);
+			// EnetPeerDisconnect会reset Peer,这里设置为0,防止再次Dispose
 			this.PeerPtr = IntPtr.Zero;
-			var tcs = new TaskCompletionSource<bool>();
+			var tcs = new TaskCompletionSource<bool>();
 			this.Disconnect = eEvent => tcs.TrySetResult(true);
 			return tcs.Task;
 		}
 
 		public void DisconnectNow(uint data)
 		{
-			NativeMethods.EnetPeerDisconnectNow(this.peerPtr, data);
-			// EnetPeerDisconnect会reset Peer,这里设置为0,防止再次Dispose
+			NativeMethods.EnetPeerDisconnectNow(this.peerPtr, data);
+			// EnetPeerDisconnect会reset Peer,这里设置为0,防止再次Dispose
 			this.PeerPtr = IntPtr.Zero;
-		}
-
-		internal void OnConnected(EEvent eEvent)
-		{
-			if (this.Connected == null)
-			{
-				return;
-			}
-			Action<EEvent> localConnected = this.Connected;
-			this.Connected = null;
-			// 此调用将让await ConnectAsync返回,所以null必须在此之前设置
-			localConnected(eEvent);
-		}
-
-		internal void OnReceived(EEvent eEvent)
-		{
-			// 如果应用层还未调用readasync则将包放到缓存队列
-			if (this.Received == null)
-			{
-				using (var packet = new EPacket(eEvent.PacketPtr))
-				{
-					var bytes = packet.Bytes;
-					this.recvBuffer.AddLast(bytes);
-				}
-			}
-			else
-			{
-				Action<EEvent> localReceived = this.Received;
-				this.Received = null;
-				// 此调用将让await ReadAsync返回,所以null必须在此之前设置
-				localReceived(eEvent);	
-			}
-		}
-
-		internal void OnDisconnect(EEvent eEvent)
-		{
-			if (this.Disconnect == null)
-			{
-				return;
-			}
-			this.Disconnect(eEvent);
-		}
-
-		internal void OnError(int errorCode)
-		{
-			if (this.Error == null)
-			{
-				return;
-			}
-			this.Error(errorCode);
+		}
+
+		internal void OnConnected(EEvent eEvent)
+		{
+			if (this.Connected == null)
+			{
+				return;
+			}
+			Action<EEvent> localConnected = this.Connected;
+			this.Connected = null;
+			// 此调用将让await ConnectAsync返回,所以null必须在此之前设置
+			localConnected(eEvent);
+		}
+
+		internal void OnReceived(EEvent eEvent)
+		{
+			// 如果应用层还未调用readasync则将包放到缓存队列
+			if (this.Received == null)
+			{
+				using (var packet = new EPacket(eEvent.PacketPtr))
+				{
+					var bytes = packet.Bytes;
+					this.recvBuffer.AddLast(bytes);
+				}
+			}
+			else
+			{
+				Action<EEvent> localReceived = this.Received;
+				this.Received = null;
+				// 此调用将让await ReadAsync返回,所以null必须在此之前设置
+				localReceived(eEvent);	
+			}
+		}
+
+		internal void OnDisconnect(EEvent eEvent)
+		{
+			if (this.Disconnect == null)
+			{
+				return;
+			}
+			this.Disconnect(eEvent);
+		}
+
+		internal void OnError(int errorCode)
+		{
+			if (this.Error == null)
+			{
+				return;
+			}
+			this.Error(errorCode);
 		}
 	}
 }

+ 7 - 2
CSharp/Platform/ENetTest/ENetClientServerTest.cs

@@ -31,11 +31,16 @@ namespace ENetCSTest
 			service.Stop();
 		}
 
-		private static async void ServerEvent(EService service, Barrier barrier)
+		private static void ServerEvent(EService service, Barrier barrier)
 		{
 			barrier.SignalAndWait();
+			StartAccept(service);
+		}
+
+		private static async void StartAccept(EService service)
+		{
 			var eSocket = new ESocket(service);
-			await eSocket.AcceptAsync();
+			await eSocket.AcceptAsync(() => StartAccept(service));
 			// Client断开,Server端收到Disconnect事件,结束Server线程
 			eSocket.Disconnect += ev => service.Stop();