浏览代码

收消息时不再需要new一块byte[],大大减少了gc

tanghai 8 年之前
父节点
当前提交
33de82a615

+ 1 - 1
Unity/Assets/Scripts/Base/Network/AChannel.cs

@@ -68,7 +68,7 @@ namespace Model
 		/// <summary>
 		/// 接收消息
 		/// </summary>
-		public abstract Task<byte[]> Recv();
+		public abstract Task<Packet> Recv();
 
 		public virtual void Dispose()
 		{

+ 11 - 8
Unity/Assets/Scripts/Base/Network/KNet/KChannel.cs

@@ -20,7 +20,7 @@ namespace Model
 		private bool isConnected;
 		private readonly IPEndPoint remoteEndPoint;
 
-		private TaskCompletionSource<byte[]> recvTcs;
+		private TaskCompletionSource<Packet> recvTcs;
 
 		private uint lastRecvTime;
 
@@ -190,9 +190,11 @@ namespace Model
 
 				if (this.recvTcs != null)
 				{
-					byte[] packet = this.parser.GetPacket();
-					if (packet != null)
+					bool isOK = this.parser.Parse();
+					if (isOK)
 					{
+						Packet packet = this.parser.GetPacket();
+
 						var tcs = this.recvTcs;
 						this.recvTcs = null;
 						tcs.SetResult(packet);
@@ -246,20 +248,21 @@ namespace Model
 			}
 		}
 
-		public override Task<byte[]> Recv()
+		public override Task<Packet> Recv()
 		{
 			if (this.Id == 0)
 			{
-				throw new Exception("TChannel已经被Dispose, 不能接收消息");
+				throw new Exception("KChannel已经被Dispose, 不能接收消息");
 			}
 
-			byte[] packet = this.parser.GetPacket();
-			if (packet != null)
+			bool isOK = this.parser.Parse();
+			if (isOK)
 			{
+				Packet packet = this.parser.GetPacket();
 				return Task.FromResult(packet);
 			}
 
-			recvTcs = new TaskCompletionSource<byte[]>();
+			recvTcs = new TaskCompletionSource<Packet>();
 			return recvTcs.Task;
 		}
 	}

+ 28 - 16
Unity/Assets/Scripts/Base/Network/TNet/PacketParser.cs

@@ -8,14 +8,31 @@ namespace Model
 		PacketBody
 	}
 
+	public struct Packet
+	{
+		public byte[] Bytes { get; set; }
+		public int Length { get; set; }
+
+		public Packet(int length)
+		{
+			this.Length = 0;
+			this.Bytes = new byte[length];
+		}
+
+		public Packet(byte[] bytes)
+		{
+			this.Bytes = bytes;
+			this.Length = bytes.Length;
+		}
+	}
+
 	internal class PacketParser
 	{
 		private readonly TBuffer buffer;
 
 		private ushort packetSize;
-		private readonly byte[] packetSizeBuffer = new byte[2];
 		private ParserState state;
-		private byte[] packet;
+		private Packet packet = new Packet(8 * 1024);
 		private bool isOK;
 
 		public PacketParser(TBuffer buffer)
@@ -23,11 +40,11 @@ namespace Model
 			this.buffer = buffer;
 		}
 
-		private void Parse()
+		public bool Parse()
 		{
 			if (this.isOK)
 			{
-				return;
+				return true;
 			}
 
 			bool finish = false;
@@ -42,8 +59,8 @@ namespace Model
 						}
 						else
 						{
-							this.buffer.RecvFrom(this.packetSizeBuffer);
-							this.packetSize = BitConverter.ToUInt16(this.packetSizeBuffer, 0);
+							this.buffer.RecvFrom(this.packet.Bytes, 2);
+							this.packetSize = BitConverter.ToUInt16(this.packet.Bytes, 0);
 							if (packetSize > 60000)
 							{
 								throw new Exception($"packet too large, size: {this.packetSize}");
@@ -58,8 +75,8 @@ namespace Model
 						}
 						else
 						{
-							this.packet = new byte[this.packetSize];
-							this.buffer.RecvFrom(this.packet);
+							this.buffer.RecvFrom(this.packet.Bytes, this.packetSize);
+							this.packet.Length = this.packetSize;
 							this.isOK = true;
 							this.state = ParserState.PacketSize;
 							finish = true;
@@ -67,18 +84,13 @@ namespace Model
 						break;
 				}
 			}
+			return this.isOK;
 		}
 
-		public byte[] GetPacket()
+		public Packet GetPacket()
 		{
-			this.Parse();
-			if (!this.isOK)
-			{
-				return null;
-			}
-			byte[] result = this.packet;
 			this.isOK = false;
-			return result;
+			return this.packet;
 		}
 	}
 }

+ 5 - 5
Unity/Assets/Scripts/Base/Network/TNet/TBuffer.cs

@@ -92,16 +92,16 @@ namespace Model
 			}
 		}
 
-		public void RecvFrom(byte[] buffer)
+		public void RecvFrom(byte[] buffer, int count)
 		{
-			if (this.Count < buffer.Length)
+			if (this.Count < count)
 			{
-				throw new Exception($"bufferList size < n, bufferList: {this.Count} buffer length: {buffer.Length}");
+				throw new Exception($"bufferList size < n, bufferList: {this.Count} buffer length: {buffer.Length} {count}");
 			}
 			int alreadyCopyCount = 0;
-			while (alreadyCopyCount < buffer.Length)
+			while (alreadyCopyCount < count)
 			{
-				int n = buffer.Length - alreadyCopyCount;
+				int n = count - alreadyCopyCount;
 				if (ChunkSize - this.FirstIndex > n)
 				{
 					Array.Copy(this.bufferQueue.First(), this.FirstIndex, buffer, alreadyCopyCount, n);

+ 10 - 7
Unity/Assets/Scripts/Base/Network/TNet/TChannel.cs

@@ -18,7 +18,7 @@ namespace Model
 		private bool isSending;
 		private readonly PacketParser parser;
 		private bool isConnected;
-		private TaskCompletionSource<byte[]> recvTcs;
+		private TaskCompletionSource<Packet> recvTcs;
 
 		/// <summary>
 		/// connect
@@ -199,9 +199,11 @@ namespace Model
 
 					if (this.recvTcs != null)
 					{
-						byte[] packet = this.parser.GetPacket();
-						if (packet != null)
+						bool isOK = this.parser.Parse();
+						if (isOK)
 						{
+							Packet packet = this.parser.GetPacket();
+
 							var tcs = this.recvTcs;
 							this.recvTcs = null;
 							tcs.SetResult(packet);
@@ -222,20 +224,21 @@ namespace Model
 			}
 		}
 
-		public override Task<byte[]> Recv()
+		public override Task<Packet> Recv()
 		{
 			if (this.Id == 0)
 			{
 				throw new Exception("TChannel已经被Dispose, 不能接收消息");
 			}
 
-			byte[] packet = this.parser.GetPacket();
-			if (packet != null)
+			bool isOK = this.parser.Parse();
+			if (isOK)
 			{
+				Packet packet = this.parser.GetPacket();
 				return Task.FromResult(packet);
 			}
 
-			recvTcs = new TaskCompletionSource<byte[]>();
+			recvTcs = new TaskCompletionSource<Packet>();
 			return recvTcs.Task;
 		}
 	}

+ 8 - 6
Unity/Assets/Scripts/Base/Network/UNet/UChannel.cs

@@ -11,8 +11,8 @@ namespace Model
 	{
 		private readonly USocket socket;
 
-		private TaskCompletionSource<byte[]> recvTcs;
-
+		private TaskCompletionSource<Packet> recvTcs;
+		
 		/// <summary>
 		/// connect
 		/// </summary>
@@ -74,7 +74,7 @@ namespace Model
 			this.socket.SendAsync(buffer);
 		}
 
-		public override Task<byte[]> Recv()
+		public override Task<Packet> Recv()
 		{
 			if (this.Id == 0)
 			{
@@ -84,10 +84,11 @@ namespace Model
 			var recvQueue = this.socket.RecvQueue;
 			if (recvQueue.Count > 0)
 			{
-				return Task.FromResult(recvQueue.Dequeue());
+				byte[] recvByte = recvQueue.Dequeue();
+				return Task.FromResult(new Packet(recvByte));
 			}
 
-			recvTcs = new TaskCompletionSource<byte[]>();
+			recvTcs = new TaskCompletionSource<Packet>();
 			return recvTcs.Task;
 		}
 
@@ -95,7 +96,8 @@ namespace Model
 		{
 			var tcs = this.recvTcs;
 			this.recvTcs = null;
-			tcs?.SetResult(this.socket.RecvQueue.Dequeue());
+			byte[] recvByte = this.socket.RecvQueue.Dequeue();
+			tcs?.SetResult(new Packet(recvByte));
 		}
 	}
 }

+ 8 - 13
Unity/Assets/Scripts/Entity/Session.cs

@@ -47,10 +47,10 @@ namespace Model
 					return;
 				}
 
-				byte[] messageBytes;
+				Packet packet;
 				try
 				{
-					messageBytes = await channel.Recv();
+					packet = await this.channel.Recv();
 					if (this.Id == 0)
 					{
 						return;
@@ -62,17 +62,17 @@ namespace Model
 					continue;
 				}
 
-				if (messageBytes.Length < 2)
+				if (packet.Length < 2)
 				{
 					Log.Error($"message error length < 2, ip: {this.RemoteAddress}");
 					this.network.Remove(this.Id);
 					return;
 				}
 
-				ushort opcode = BitConverter.ToUInt16(messageBytes, 0);
+				ushort opcode = BitConverter.ToUInt16(packet.Bytes, 0);
 				try
 				{
-					this.Run(opcode, messageBytes);
+					this.RunDecompressedBytes(opcode, packet.Bytes, 2, packet.Length);
 				}
 				catch (Exception e)
 				{
@@ -81,12 +81,7 @@ namespace Model
 			}
 		}
 
-		private void Run(ushort opcode, byte[] messageBytes)
-		{
-			this.RunDecompressedBytes(opcode, messageBytes, 2);
-		}
-
-		private void RunDecompressedBytes(ushort opcode, byte[] messageBytes, int offset)
+		private void RunDecompressedBytes(ushort opcode, byte[] messageBytes, int offset, int count)
 		{
 			object message;
 			Opcode op;
@@ -95,7 +90,7 @@ namespace Model
 			{
 				op = (Opcode)opcode;
 				Type messageType = this.network.Entity.GetComponent<OpcodeTypeComponent>().GetType(op);
-				message = this.network.MessagePacker.DeserializeFrom(messageType, messageBytes, offset, messageBytes.Length - offset);
+				message = this.network.MessagePacker.DeserializeFrom(messageType, messageBytes, offset, count - offset);
 			}
 			catch (Exception e)
 			{
@@ -311,7 +306,7 @@ namespace Model
 			if (this.network.AppType == AppType.AllServer)
 			{
 				Session session = this.network.GetComponent<NetInnerComponent>().Get(this.RemoteAddress.ToString());
-				session.RunDecompressedBytes(op, messageBytes, 0);
+				session.RunDecompressedBytes(op, messageBytes, 0, messageBytes.Length);
 				return;
 			}
 #endif