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

enet socket应用层未处理的包缓存改成byte[],避免socket退出无法释放c++层的数据

tanghai 12 лет назад
Родитель
Сommit
853e79fdac

+ 1 - 0
CSharp/Platform/ENet/ENet.csproj

@@ -40,6 +40,7 @@
     <Compile Include="Address.cs" />
     <Compile Include="EException.cs" />
     <Compile Include="EEvent.cs" />
+    <Compile Include="ErrorCode.cs" />
     <Compile Include="EService.cs" />
     <Compile Include="Library.cs" />
     <Compile Include="NativeMethods.cs" />

+ 18 - 14
CSharp/Platform/ENet/EService.cs

@@ -43,7 +43,7 @@ namespace ENet
 		{
 			if (peerLimit > NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID)
 			{
-				throw new ArgumentOutOfRangeException("peerLimit");
+				throw new ArgumentOutOfRangeException(string.Format("peerLimit: {0}", peerLimit));
 			}
 
 			if (channelLimit > NativeMethods.ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
@@ -70,8 +70,8 @@ namespace ENet
 			uint outgoingBandwidth = 0)
 		{
 			if (peerLimit > NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID)
-			{
-				throw new ArgumentOutOfRangeException("peerLimit");
+			{
+				throw new ArgumentOutOfRangeException(string.Format("peerLimit: {0}", peerLimit));
 			}
 
 			if (channelLimit > NativeMethods.ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
@@ -281,20 +281,24 @@ namespace ENet
 
 						// 链接已经被应用层接收
 						eEvent.EventState = EventState.DISCONNECTED;
-						ESocket eSocket = this.PeersManager[eEvent.PeerPtr];
-						this.PeersManager.Remove(eSocket.PeerPtr);
-						// enet_peer_disconnect会reset Peer,这里设置为0,防止再次Dispose
-						eSocket.PeerPtr = IntPtr.Zero;
+						ESocket eSocket = this.PeersManager[eEvent.PeerPtr];
+						this.PeersManager.Remove(eEvent.PeerPtr);
 
-						// 等待接收数据中的task抛出异常
-						if (eSocket.Received != null)
+						// 等待的task将抛出异常
+						if (eSocket.Connected != null)
 						{
-							eSocket.OnReceived(eEvent);
-						}
-						else
+							eSocket.OnConnected(eEvent);
+						}
+						else if (eSocket.Received != null)
 						{
-							eSocket.OnDisconnect(eEvent);
-						}
+							eSocket.OnReceived(eEvent);
+						}
+						else if (eSocket.Disconnect != null)
+						{
+							eSocket.OnDisconnect(eEvent);
+						}
+
+						eSocket.OnError(ErrorCode.ClientDisconnect);
 						break;
 					}
 				}

+ 50 - 23
CSharp/Platform/ENet/ESocket.cs

@@ -1,9 +1,7 @@
 using System;
 using System.Collections.Generic;
-using System.Diagnostics;
 using System.Runtime.InteropServices;
 using System.Threading.Tasks;
-using Log;
 
 namespace ENet
 {
@@ -11,11 +9,12 @@ namespace ENet
 	{
 		private IntPtr peerPtr = IntPtr.Zero;
 		private readonly EService service;
-		private readonly LinkedList<EEvent> recvEEvents = new LinkedList<EEvent>();
+		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)
 		{
@@ -101,8 +100,15 @@ namespace ENet
 			{
 				throw new EException("host connect call failed.");
 			}
-			this.service.PeersManager.Add(this.peerPtr, this);
-			this.Connected = e => 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;
 		}
 
@@ -131,6 +137,11 @@ namespace ENet
 				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;
@@ -154,15 +165,11 @@ namespace ENet
 			var tcs = new TaskCompletionSource<byte[]>();
 
 			// 如果有缓存的包,从缓存中取
-			if (this.recvEEvents.Count > 0)
+			if (this.recvBuffer.Count > 0)
 			{
-				EEvent eEvent = this.recvEEvents.First.Value;
-				this.recvEEvents.RemoveFirst();
-				using (var packet = new EPacket(eEvent.PacketPtr))
-				{
-					var bytes = packet.Bytes;
-					tcs.TrySetResult(bytes);
-				}
+				var bytes = this.recvBuffer.First.Value;
+				this.recvBuffer.RemoveFirst();
+				tcs.TrySetResult(bytes);
 			}
 			// 没有缓存封包,设置回调等待
 			else
@@ -171,7 +178,7 @@ namespace ENet
 				{
 					if (eEvent.EventState == EventState.DISCONNECTED)
 					{
-						tcs.TrySetException(new EException("Peer Disconnected In Received"));
+						tcs.TrySetException(new EException("socket disconnected in receive"));
 					}
 
 					using (var packet = new EPacket(eEvent.PacketPtr))
@@ -186,23 +193,29 @@ namespace ENet
 
 		public Task<bool> DisconnectAsync(uint data = 0)
 		{
-			NativeMethods.EnetPeerDisconnect(this.peerPtr, data);
+			NativeMethods.EnetPeerDisconnect(this.peerPtr, data);
+			// EnetPeerDisconnect会reset Peer,这里设置为0,防止再次Dispose
+			this.PeerPtr = IntPtr.Zero;
 			var tcs = new TaskCompletionSource<bool>();
-			this.Disconnect = e => tcs.TrySetResult(true);
+			this.Disconnect = eEvent => tcs.TrySetResult(true);
 			return tcs.Task;
 		}
 
 		public Task<bool> DisconnectLaterAsync(uint data = 0)
 		{
-			NativeMethods.EnetPeerDisconnectLater(this.peerPtr, data);
-			var tcs = new TaskCompletionSource<bool>();
-			this.Disconnect = e => tcs.TrySetResult(true);
+			NativeMethods.EnetPeerDisconnectLater(this.peerPtr, data);
+			// EnetPeerDisconnect会reset Peer,这里设置为0,防止再次Dispose
+			this.PeerPtr = IntPtr.Zero;
+			var tcs = new TaskCompletionSource<bool>();
+			this.Disconnect = eEvent => tcs.TrySetResult(true);
 			return tcs.Task;
 		}
 
 		public void DisconnectNow(uint data)
 		{
-			NativeMethods.EnetPeerDisconnectNow(this.peerPtr, data);
+			NativeMethods.EnetPeerDisconnectNow(this.peerPtr, data);
+			// EnetPeerDisconnect会reset Peer,这里设置为0,防止再次Dispose
+			this.PeerPtr = IntPtr.Zero;
 		}
 
 		internal void OnConnected(EEvent eEvent)
@@ -219,9 +232,14 @@ namespace ENet
 
 		internal void OnReceived(EEvent eEvent)
 		{
+			// 如果应用层还未调用readasync则将包放到缓存队列
 			if (this.Received == null)
 			{
-				this.recvEEvents.AddLast(eEvent);
+				using (var packet = new EPacket(eEvent.PacketPtr))
+				{
+					var bytes = packet.Bytes;
+					this.recvBuffer.AddLast(bytes);
+				}
 			}
 			else
 			{
@@ -232,13 +250,22 @@ namespace ENet
 			}
 		}
 
-		internal void OnDisconnect(EEvent e)
+		internal void OnDisconnect(EEvent eEvent)
 		{
 			if (this.Disconnect == null)
 			{
 				return;
 			}
-			this.Disconnect(e);
+			this.Disconnect(eEvent);
+		}
+
+		internal void OnError(int errorCode)
+		{
+			if (this.Error == null)
+			{
+				return;
+			}
+			this.Error(errorCode);
 		}
 	}
 }

+ 8 - 0
CSharp/Platform/ENet/ErrorCode.cs

@@ -0,0 +1,8 @@
+
+namespace ENet
+{
+	public static class ErrorCode
+	{
+		public const int ClientDisconnect = 1;
+	}
+}