Sfoglia il codice sorgente

protobuf使用MergeFrom,OpcodeTypeComponent缓存消息,反序列化从OpcodeTypeComponent获取消息实力,不用再new消息,减少gc

tanghai 7 anni fa
parent
commit
a51c11f2e1

+ 6 - 1
Server/Model/Base/Helper/MongoHelper.cs

@@ -52,7 +52,7 @@ namespace ETModel
 		{
 			return obj.ToBson();
 		}
-
+		
 		public static object FromBson(Type type, byte[] bytes)
 		{
 			return BsonSerializer.Deserialize(bytes, type);
@@ -66,6 +66,11 @@ namespace ETModel
 			}
 		}
 		
+		public static object FromBson(object instance, Stream stream)
+		{
+			return BsonSerializer.Deserialize(stream, instance.GetType());
+		}
+		
 		public static object FromStream(Type type, Stream stream)
 		{
 			return BsonSerializer.Deserialize(stream, type);

+ 5 - 0
Server/Model/Module/Message/MongoPacker.cs

@@ -19,5 +19,10 @@ namespace ETModel
 		{
 			return MongoHelper.FromStream(type, stream);
 		}
+
+		public object DeserializeFrom(object instance, MemoryStream stream)
+		{
+			return MongoHelper.FromBson(instance, stream);
+		}
 	}
 }

+ 2 - 2
Unity/Assets/Scripts/Module/Message/ClientDispatcher.cs

@@ -16,8 +16,8 @@ namespace ETModel
 				}
 
 				OpcodeTypeComponent opcodeTypeComponent = session.Network.Entity.GetComponent<OpcodeTypeComponent>();
-				Type responseType = opcodeTypeComponent.GetType(packet.Opcode);
-				message = session.Network.MessagePacker.DeserializeFrom(responseType, packet.Stream);
+				object instance = opcodeTypeComponent.GetInstance(packet.Opcode);
+				message = session.Network.MessagePacker.DeserializeFrom(instance, packet.Stream);
 			}
 			catch (Exception e)
 			{

+ 1 - 0
Unity/Assets/Scripts/Module/Message/IMessagePacker.cs

@@ -8,5 +8,6 @@ namespace ETModel
 		byte[] SerializeToByteArray(object obj);
 		object DeserializeFrom(Type type, byte[] bytes, int index, int count);
 		object DeserializeFrom(Type type, MemoryStream stream);
+		object DeserializeFrom(object instance, MemoryStream stream);
 	}
 }

+ 22 - 2
Unity/Assets/Scripts/Module/Message/OpcodeTypeComponent.cs

@@ -8,16 +8,30 @@ namespace ETModel
 	{
 		public override void Awake(OpcodeTypeComponent self)
 		{
-			self.Awake();
+			self.Load();
+		}
+	}
+	
+	[ObjectSystem]
+	public class OpcodeTypeComponentLoadSystem : LoadSystem<OpcodeTypeComponent>
+	{
+		public override void Load(OpcodeTypeComponent self)
+		{
+			self.Load();
 		}
 	}
 
 	public class OpcodeTypeComponent : Component
 	{
 		private readonly DoubleMap<ushort, Type> opcodeTypes = new DoubleMap<ushort, Type>();
+		
+		private readonly Dictionary<ushort, object> typeMessages = new Dictionary<ushort, object>();
 
-		public void Awake()
+		public void Load()
 		{
+			this.opcodeTypes.Clear();
+			this.typeMessages.Clear();
+			
 			List<Type> types = Game.EventSystem.GetTypes();
 			foreach (Type type in types)
 			{
@@ -34,6 +48,7 @@ namespace ETModel
 				}
 
 				this.opcodeTypes.Add(messageAttribute.Opcode, type);
+				this.typeMessages.Add(messageAttribute.Opcode, Activator.CreateInstance(type));
 			}
 		}
 
@@ -46,6 +61,11 @@ namespace ETModel
 		{
 			return this.opcodeTypes.GetValueByKey(opcode);
 		}
+		
+		public object GetInstance(ushort opcode)
+		{
+			return this.typeMessages[opcode];
+		}
 
 		public override void Dispose()
 		{

+ 13 - 2
Unity/Assets/Scripts/Module/Message/ProtobufHelper.cs

@@ -14,7 +14,6 @@ namespace ETModel
 		
 		public static object FromBytes(Type type, byte[] bytes, int index, int count)
 		{
-			// 这个message可以从池中获取,减少gc
 			object message = Activator.CreateInstance(type);
 			((Google.Protobuf.IMessage)message).MergeFrom(bytes, index, count);
 			ISupportInitialize iSupportInitialize = message as ISupportInitialize;
@@ -28,7 +27,6 @@ namespace ETModel
 		
 		public static object FromStream(Type type, MemoryStream stream)
 		{
-			// 这个message可以从池中获取,减少gc
 			object message = Activator.CreateInstance(type);
 			((Google.Protobuf.IMessage)message).MergeFrom(stream.GetBuffer(), (int)stream.Position, (int)stream.Length);
 			ISupportInitialize iSupportInitialize = message as ISupportInitialize;
@@ -39,5 +37,18 @@ namespace ETModel
 			iSupportInitialize.EndInit();
 			return message;
 		}
+		
+		public static object FromStream(object message, MemoryStream stream)
+		{
+			// 这个message可以从池中获取,减少gc
+			((Google.Protobuf.IMessage)message).MergeFrom(stream.GetBuffer(), (int)stream.Position, (int)stream.Length);
+			ISupportInitialize iSupportInitialize = message as ISupportInitialize;
+			if (iSupportInitialize == null)
+			{
+				return message;
+			}
+			iSupportInitialize.EndInit();
+			return message;
+		}
 	}
 }

+ 5 - 0
Unity/Assets/Scripts/Module/Message/ProtobufPacker.cs

@@ -19,5 +19,10 @@ namespace ETModel
 		{
 			return ProtobufHelper.FromStream(type, stream);
 		}
+
+		public object DeserializeFrom(object instance, MemoryStream stream)
+		{
+			return ProtobufHelper.FromStream(instance, stream);
+		}
 	}
 }

+ 2 - 2
Unity/Assets/Scripts/Module/Message/Session.cs

@@ -129,8 +129,8 @@ namespace ETModel
 			try
 			{
 				OpcodeTypeComponent opcodeTypeComponent = this.Network.Entity.GetComponent<OpcodeTypeComponent>();
-				Type responseType = opcodeTypeComponent.GetType(opcode);
-				message = this.Network.MessagePacker.DeserializeFrom(responseType, packet.Stream);
+				object instance = opcodeTypeComponent.GetInstance(opcode);
+				message = this.Network.MessagePacker.DeserializeFrom(instance, packet.Stream);
 				//Log.Debug($"recv: {JsonHelper.ToJson(message)}");
 			}
 			catch (Exception e)

+ 22 - 2
Unity/Hotfix/Module/Message/OpcodeTypeComponent.cs

@@ -9,16 +9,30 @@ namespace ETHotfix
 	{
 		public override void Awake(OpcodeTypeComponent self)
 		{
-			self.Awake();
+			self.Load();
+		}
+	}
+	
+	[ObjectSystem]
+	public class OpcodeTypeComponentLoadSystem : LoadSystem<OpcodeTypeComponent>
+	{
+		public override void Load(OpcodeTypeComponent self)
+		{
+			self.Load();
 		}
 	}
 
 	public class OpcodeTypeComponent : Component
 	{
 		private readonly DoubleMap<ushort, Type> opcodeTypes = new DoubleMap<ushort, Type>();
+		
+		private readonly Dictionary<ushort, object> typeMessages = new Dictionary<ushort, object>();
 
-		public void Awake()
+		public void Load()
 		{
+			this.opcodeTypes.Clear();
+			this.typeMessages.Clear();
+			
 			List<Type> types = ETModel.Game.Hotfix.GetHotfixTypes();
 			foreach (Type type in types)
 			{
@@ -34,6 +48,7 @@ namespace ETHotfix
 					continue;
 				}
 				this.opcodeTypes.Add(messageAttribute.Opcode, type);
+				this.typeMessages.Add(messageAttribute.Opcode, Activator.CreateInstance(type));
 			}
 		}
 
@@ -46,6 +61,11 @@ namespace ETHotfix
 		{
 			return this.opcodeTypes.GetValueByKey(opcode);
 		}
+		
+		public object GetInstance(ushort opcode)
+		{
+			return this.typeMessages[opcode];
+		}
 
 		public override void Dispose()
 		{

+ 2 - 2
Unity/Hotfix/Module/Message/Session.cs

@@ -54,8 +54,8 @@ namespace ETHotfix
 			byte flag = packet.Flag;
 
 			OpcodeTypeComponent opcodeTypeComponent = Game.Scene.GetComponent<OpcodeTypeComponent>();
-			Type responseType = opcodeTypeComponent.GetType(opcode);
-			object message = this.session.Network.MessagePacker.DeserializeFrom(responseType, packet.Stream);
+			object instance = opcodeTypeComponent.GetInstance(opcode);
+			object message = this.session.Network.MessagePacker.DeserializeFrom(instance, packet.Stream);
 
 			if ((flag & 0x01) > 0)
 			{