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

将普通消息与Rpc消息区分开来,目前rpcid放在协议中,下一步可能会放到消息中,还没想清楚

tanghai 9 лет назад
Родитель
Сommit
05b2758db7

+ 1 - 1
Server/App/Program.cs

@@ -27,7 +27,7 @@ namespace App
 				Game.Scene.AddComponent<EventComponent>();
 				Game.Scene.AddComponent<TimerComponent>();
 				Game.Scene.AddComponent<NetworkComponent, NetworkProtocol, string, int>(options.Protocol, options.Host, options.Port);
-				Game.Scene.AddComponent<MessageHandlerComponent, string>(options.AppType);
+				Game.Scene.AddComponent<MessageDispatherComponent, string>(options.AppType);
 				
 				// 根据不同的AppType添加不同的组件
 				switch (options.AppType)

+ 2 - 2
Server/Base/Server.Base.csproj

@@ -134,8 +134,8 @@
     <Compile Include="..\..\Unity\Assets\Plugins\Base\Message\MessageAttribute.cs">
       <Link>Message\MessageAttribute.cs</Link>
     </Compile>
-    <Compile Include="..\..\Unity\Assets\Plugins\Base\Message\OpcodeAttribute.cs">
-      <Link>Message\OpcodeAttribute.cs</Link>
+    <Compile Include="..\..\Unity\Assets\Plugins\Base\Message\MessageHandlerAttribute.cs">
+      <Link>Message\MessageHandlerAttribute.cs</Link>
     </Compile>
     <Compile Include="..\..\Unity\Assets\Plugins\Base\Message\RpcException.cs">
       <Link>Message\RpcException.cs</Link>

+ 3 - 3
Server/Controller/C2S_LoginEvent.cs

@@ -3,13 +3,13 @@ using Model;
 
 namespace Controller
 {
-	[Message(AppType.Realm)]
-	public class C2S_LoginEvent: AMEvent<C2S_Login>
+	[MessageHandler(AppType.Realm)]
+	public class C2S_LoginEvent: AMRpcEvent<C2S_Login>
 	{
 		protected override void Run(Entity scene, C2S_Login message, uint rpcId)
 		{
 			Log.Info(MongoHelper.ToJson(message));
-			scene.GetComponent<MessageComponent>().Send(rpcId, new S2C_Login {ErrorMessage = new ErrorMessage() });
+			scene.GetComponent<MessageComponent>().Reply(rpcId, new S2C_Login());
 		}
 	}
 }

+ 4 - 4
Server/Controller/C2S_SubscribeLogEvent.cs

@@ -3,16 +3,16 @@ using Model;
 
 namespace Controller
 {
-	[Message(AppType.Realm)]
-	public class C2S_SubscribeLogEvent : AMEvent<C2S_SubscribeLog>
+	[MessageHandler(AppType.Realm)]
+	public class C2S_SubscribeLogEvent : AMRpcEvent<C2S_SubscribeLog>
 	{
 		protected override void Run(Entity entity, C2S_SubscribeLog message, uint rpcId)
 		{
 			Log.Info(MongoHelper.ToJson(message));
 
-			//entity.AddComponent<LogToClientComponent>();
+			entity.AddComponent<LogToClientComponent>();
 
-			entity.GetComponent<MessageComponent>().Send(rpcId, new S2C_SubscribeLog { ErrorMessage = new ErrorMessage() });
+			entity.GetComponent<MessageComponent>().Reply(rpcId, new S2C_SubscribeLog());
 		}
 	}
 }

+ 2 - 2
Server/Model/Server.Model.csproj

@@ -50,8 +50,8 @@
     <Compile Include="..\..\Unity\Assets\Scripts\Component\MessageComponent.cs">
       <Link>Component\MessageComponent.cs</Link>
     </Compile>
-    <Compile Include="..\..\Unity\Assets\Scripts\Component\MessageHandlerComponent.cs">
-      <Link>Component\MessageHandlerComponent.cs</Link>
+    <Compile Include="..\..\Unity\Assets\Scripts\Component\MessageDispatherComponent.cs">
+      <Link>Component\MessageDispatherComponent.cs</Link>
     </Compile>
     <Compile Include="..\..\Unity\Assets\Scripts\Component\NetworkComponent.cs">
       <Link>Component\NetworkComponent.cs</Link>

+ 13 - 2
Unity/Assets/Plugins/Base/Message/AMEvent.cs

@@ -2,12 +2,23 @@
 {
 	public abstract class AMEvent<T>: IMRegister
 	{
-		protected abstract void Run(Entity scene, T message, uint rpcId);
+		protected abstract void Run(Entity scene, T message);
 
-		public void Register(IMessageHandler component)
+		public void Register(IMessageDispather component)
 		{
 			ushort opcode = component.GetOpcode(typeof (T));
 			component.RegisterHandler<T>(opcode, Run);
 		}
 	}
+
+	public abstract class AMRpcEvent<T> : IMRegister
+	{
+		protected abstract void Run(Entity scene, T message, uint rpcId);
+
+		public void Register(IMessageDispather component)
+		{
+			ushort opcode = component.GetOpcode(typeof(T));
+			component.RegisterRpcHandler<T>(opcode, Run);
+		}
+	}
 }

+ 14 - 8
Unity/Assets/Plugins/Base/Message/IErrorMessage.cs

@@ -1,16 +1,22 @@
 namespace Base
 {
-	/// <summary>
-	/// 服务端回的RPC消息需要继承这个接口
-	/// </summary>
-	public interface IErrorMessage
+	public abstract class AMessage
+	{
+	}
+
+	public abstract class ARequest : AMessage
 	{
-		ErrorMessage ErrorMessage { get; set; }
+		public uint RpcId;
 	}
-	
-	public class ErrorMessage
+
+	/// <summary>
+	/// 服务端回的RPC消息需要继承这个抽象类
+	/// </summary>
+	public abstract class AResponse: AMessage
 	{
-		public int Errno = 0;
+		public uint RpcId;
+
+		public int ErrorCode = 0;
 		public string Message = "";
 	}
 }

+ 4 - 3
Unity/Assets/Plugins/Base/Message/IMRegister.cs

@@ -2,14 +2,15 @@
 
 namespace Base
 {
-	public interface IMessageHandler
+	public interface IMessageDispather
 	{
-		void RegisterHandler<T>(ushort opcode, Action<Entity, T, uint> action);
 		ushort GetOpcode(Type type);
+		void RegisterHandler<T>(ushort opcode, Action<Entity, T> action);
+		void RegisterRpcHandler<T>(ushort opcode, Action<Entity, T, uint> action);
 	}
 
 	public interface IMRegister
 	{
-		void Register(IMessageHandler messageHandler);
+		void Register(IMessageDispather messageDispather);
 	}
 }

+ 3 - 6
Unity/Assets/Plugins/Base/Message/MessageAttribute.cs

@@ -2,16 +2,13 @@
 
 namespace Base
 {
-	/// <summary>
-	/// 搭配MessageComponent用来分发消息
-	/// </summary>
 	public class MessageAttribute : Attribute
 	{
-		public string AppType { get; private set; }
+		public ushort Opcode { get; private set; }
 
-		public MessageAttribute(string appType)
+		public MessageAttribute(ushort opcode)
 		{
-			this.AppType = appType;
+			this.Opcode = opcode;
 		}
 	}
 }

+ 17 - 0
Unity/Assets/Plugins/Base/Message/MessageHandlerAttribute.cs

@@ -0,0 +1,17 @@
+using System;
+
+namespace Base
+{
+	/// <summary>
+	/// 搭配MessageComponent用来分发消息
+	/// </summary>
+	public class MessageHandlerAttribute : Attribute
+	{
+		public string AppType { get; private set; }
+
+		public MessageHandlerAttribute(string appType)
+		{
+			this.AppType = appType;
+		}
+	}
+}

+ 2 - 2
Unity/Assets/Plugins/Base/Message/OpcodeAttribute.cs.meta → Unity/Assets/Plugins/Base/Message/MessageHandlerAttribute.cs.meta

@@ -1,6 +1,6 @@
 fileFormatVersion: 2
-guid: 485eb61dbc2b9664d80d40e19aa80c49
-timeCreated: 1476612496
+guid: fcf293ee7dda23746a98f4308723280e
+timeCreated: 1476426533
 licenseType: Pro
 MonoImporter:
   serializedVersion: 2

+ 0 - 14
Unity/Assets/Plugins/Base/Message/OpcodeAttribute.cs

@@ -1,14 +0,0 @@
-using System;
-
-namespace Base
-{
-	public class OpcodeAttribute : Attribute
-	{
-		public ushort Opcode { get; private set; }
-
-		public OpcodeAttribute(ushort opcode)
-		{
-			this.Opcode = opcode;
-		}
-	}
-}

+ 2 - 2
Unity/Assets/Res/Code.meta

@@ -1,7 +1,7 @@
 fileFormatVersion: 2
-guid: de24d6c9c5a460f48a4af1bff83d11f3
+guid: 4805d347ea85a2c4ab97f544d710a65d
 folderAsset: yes
-timeCreated: 1476243665
+timeCreated: 1476778403
 licenseType: Pro
 DefaultImporter:
   userData: 

+ 49 - 85
Unity/Assets/Scripts/Component/MessageComponent.cs

@@ -22,13 +22,12 @@ namespace Model
 	{
 		private static uint RpcId { get; set; }
 		private readonly Dictionary<uint, Action<byte[], int, int>> requestCallback = new Dictionary<uint, Action<byte[], int, int>>();
-		private readonly Dictionary<ushort, Action<byte[], int, int>> waitCallback = new Dictionary<ushort, Action<byte[], int, int>>();
 		private AChannel channel;
-		private MessageHandlerComponent messageHandler;
+		private MessageDispatherComponent messageDispather;
 		
 		public void Awake(AChannel aChannel)
 		{
-			this.messageHandler = Game.Scene.GetComponent<MessageHandlerComponent>();
+			this.messageDispather = Game.Scene.GetComponent<MessageDispatherComponent>();
 			this.channel = aChannel;
 			this.StartRecv();
 		}
@@ -81,8 +80,10 @@ namespace Model
 		private void Run(ushort opcode, byte[] messageBytes)
 		{
 			int offset = 0;
-			uint flagUInt = BitConverter.ToUInt32(messageBytes, 2);
-			bool isCompressed = (flagUInt & 0x80000000) > 0;
+			uint flag = BitConverter.ToUInt32(messageBytes, 2);
+			uint rpcFlag = flag & 0x40000000;
+			uint rpcId = flag & 0x3fffffff;
+			bool isCompressed = (flag & 0x80000000) > 0;
 			if (isCompressed) // 最高位为1,表示有压缩,需要解压缩
 			{
 				messageBytes = ZipHelper.Decompress(messageBytes, 6, messageBytes.Length - 6);
@@ -92,34 +93,41 @@ namespace Model
 			{
 				offset = 6;
 			}
-			uint rpcId = flagUInt & 0x7fffffff;
-			this.RunDecompressedBytes(opcode, rpcId, messageBytes, offset);
+			
+			this.RunDecompressedBytes(opcode, rpcId, rpcFlag, messageBytes, offset);
 		}
 
-		private void RunDecompressedBytes(ushort opcode, uint rpcId, byte[] messageBytes, int offset)
+		private void RunDecompressedBytes(ushort opcode, uint rpcId, uint rpcFlag, byte[] messageBytes, int offset)
 		{
-			Action<byte[], int, int> action;
-			if (this.requestCallback.TryGetValue(rpcId, out action))
+			if (rpcId == 0)
 			{
-				this.requestCallback.Remove(rpcId);
-				action(messageBytes, offset, messageBytes.Length - offset);
-				return;
+				this.messageDispather.Handle(this.Owner, opcode, messageBytes, offset);
 			}
 
-			if (this.waitCallback.TryGetValue(opcode, out action))
+			// rpcFlag>0 表示这是一个rpc响应消息
+			if (rpcFlag > 0)
 			{
-				this.waitCallback.Remove(opcode);
-				action(messageBytes, offset, messageBytes.Length - offset);
-				return;
+				Action<byte[], int, int> action;
+				if (this.requestCallback.TryGetValue(rpcId, out action))
+				{
+					this.requestCallback.Remove(rpcId);
+					action(messageBytes, offset, messageBytes.Length - offset);
+				}
+			}
+			else // 这是一个rpc请求消息
+			{
+				this.messageDispather.HandleRpc(this.Owner, opcode, messageBytes, offset, rpcId);
 			}
-
-			this.messageHandler.Handle(this.Owner, opcode, messageBytes, offset);
 		}
 
-
-		public Task<Response> CallAsync<Response>(object request, CancellationToken cancellationToken) where Response : IErrorMessage
+		/// <summary>
+		/// Rpc调用
+		/// </summary>
+		public Task<Response> Call<Request, Response>(Request request, CancellationToken cancellationToken) 
+			where Request : ARequest
+			where Response : AResponse
 		{
-			this.Send(++RpcId, request);
+			this.SendMessage(++RpcId, request);
 
 			var tcs = new TaskCompletionSource<Response>();
 
@@ -128,9 +136,9 @@ namespace Model
 				try
 				{
 					Response response = MongoHelper.FromBson<Response>(bytes, offset, count);
-					if (response.ErrorMessage.Errno != 0)
+					if (response.ErrorCode != 0)
 					{
-						tcs.SetException(new RpcException(response.ErrorMessage.Errno, response.ErrorMessage.Message));
+						tcs.SetException(new RpcException(response.ErrorCode, response.Message));
 						return;
 					}
 					tcs.SetResult(response);
@@ -149,21 +157,21 @@ namespace Model
 		/// <summary>
 		/// Rpc调用,发送一个消息,等待返回一个消息
 		/// </summary>
-		/// <typeparam name="Response"></typeparam>
-		/// <param name="request"></param>
-		/// <returns></returns>
-		public Task<Response> CallAsync<Response>(object request) where Response : IErrorMessage
+		public Task<Response> Call<Request, Response>(Request request) 
+			where Request: ARequest 
+			where Response : AResponse
 		{
-			this.Send(++RpcId, request);
+			request.RpcId = ++RpcId;
+			this.SendMessage(++RpcId, request);
 			var tcs = new TaskCompletionSource<Response>();
 			this.requestCallback[RpcId] = (bytes, offset, count) =>
 			{
 				try
 				{
 					Response response = MongoHelper.FromBson<Response>(bytes, offset, count);
-					if (response.ErrorMessage.Errno != 0)
+					if (response.ErrorCode != 0)
 					{
-						tcs.SetException(new RpcException(response.ErrorMessage.Errno,  response.ErrorMessage.Message));
+						tcs.SetException(new RpcException(response.ErrorCode,  response.Message));
 						return;
 					}
 					tcs.SetResult(response);
@@ -177,68 +185,24 @@ namespace Model
 			return tcs.Task;
 		}
 
-		/// <summary>
-		/// 不发送消息,直接等待返回一个消息
-		/// </summary>
-		/// <typeparam name="Response"></typeparam>
-		/// <param name="cancellationToken"></param>
-		/// <returns></returns>
-		public Task<Response> WaitAsync<Response>(CancellationToken cancellationToken) where Response : class
-		{
-			var tcs = new TaskCompletionSource<Response>();
-			ushort opcode = this.messageHandler.messageOpcode[typeof(Response)];
-			this.waitCallback[opcode] = (bytes, offset, count) =>
-			{
-				try
-				{
-					Response response = MongoHelper.FromBson<Response>(bytes, offset, count);
-					tcs.SetResult(response);
-				}
-				catch (Exception e)
-				{
-					tcs.SetException(new Exception($"Wait Error: {typeof(Response).FullName}", e));
-				}
-			};
-
-			cancellationToken.Register(() => { this.waitCallback.Remove(opcode); });
-
-			return tcs.Task;
-		}
-
-		/// <summary>
-		/// 不发送消息,直接等待返回一个消息
-		/// </summary>
-		/// <typeparam name="Response"></typeparam>
-		/// <returns></returns>
-		public Task<Response> WaitAsync<Response>() where Response : class
+		public void Send(object message)
 		{
-			var tcs = new TaskCompletionSource<Response>();
-			ushort opcode = this.messageHandler.messageOpcode[typeof(Response)];
-			this.waitCallback[opcode] = (bytes, offset, count) =>
-			{
-				try
-				{
-					Response response = MongoHelper.FromBson<Response>(bytes, offset, count);
-					tcs.SetResult(response);
-				}
-				catch (Exception e)
-				{
-					tcs.SetException(new Exception($"Wait Error: {typeof(Response).FullName}", e));
-				}
-			};
-
-			return tcs.Task;
+			this.SendMessage(0, message);
 		}
 
-		public void Send(object message)
+		public void Reply<T>(uint rpcId, T message) where T: AResponse
 		{
-			this.Send(0, message);
+			this.SendMessage(rpcId, message, false);
 		}
 
-		public void Send(uint rpcId, object message)
+		private void SendMessage(uint rpcId, object message, bool isCall = true)
 		{
-			ushort opcode = this.messageHandler.GetOpcode(message.GetType());
+			ushort opcode = this.messageDispather.GetOpcode(message.GetType());
 			byte[] opcodeBytes = BitConverter.GetBytes(opcode);
+			if (rpcId > 0 && !isCall)
+			{
+				rpcId = rpcId | 0x4fffffff;
+			}
 			byte[] seqBytes = BitConverter.GetBytes(rpcId);
 			byte[] messageBytes = MongoHelper.ToBson(message);
 			

+ 210 - 0
Unity/Assets/Scripts/Component/MessageDispatherComponent.cs

@@ -0,0 +1,210 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Base;
+using Object = Base.Object;
+
+namespace Model
+{
+	[ObjectEvent]
+	public class MessageHandlerComponentEvent : ObjectEvent<MessageDispatherComponent>, ILoader, IAwake<string>
+	{
+		public void Load()
+		{
+			this.GetValue().Load();
+		}
+
+		public void Awake(string appType)
+		{
+			this.GetValue().Awake(appType);
+		}
+	}
+
+	
+	/// <summary>
+	/// 消息分发组件
+	/// </summary>
+	public class MessageDispatherComponent: Component, IMessageDispather
+	{
+		private class MessageInfo
+		{
+			public byte[] MessageBytes;
+			public int Offset;
+			public int Count;
+			public uint RpcId;
+		}
+
+		private string AppType;
+		private Dictionary<ushort, List<Action<Entity, MessageInfo>>> events;
+		private Dictionary<ushort, List<Action<Entity, MessageInfo>>> rpcHandlers;
+		public Dictionary<Type, MessageAttribute> messageOpcode { get; private set; } = new Dictionary<Type, MessageAttribute>();
+		
+		public void Awake(string appType)
+		{
+			this.AppType = appType;
+			this.Load();
+		}
+
+		public void Load()
+		{
+			this.events = new Dictionary<ushort, List<Action<Entity, MessageInfo>>>();
+			this.rpcHandlers = new Dictionary<ushort, List<Action<Entity, MessageInfo>>>();
+			this.messageOpcode = new Dictionary<Type, MessageAttribute>();
+
+			Assembly[] assemblies = Object.ObjectManager.GetAssemblies();
+
+			foreach (Assembly assembly in assemblies)
+			{
+				Type[] types = assembly.GetTypes();
+				foreach (Type type in types)
+				{
+					object[] attrs = type.GetCustomAttributes(typeof(MessageAttribute), false);
+					if (attrs.Length == 0)
+					{
+						continue;
+					}
+
+					MessageAttribute messageAttribute = (MessageAttribute)attrs[0];
+					this.messageOpcode[type] = messageAttribute;
+				}
+			}
+
+			foreach (Assembly assembly in assemblies)
+			{
+				Type[] types = assembly.GetTypes();
+				foreach (Type type in types)
+				{
+					object[] attrs = type.GetCustomAttributes(typeof(MessageHandlerAttribute), false);
+					if (attrs.Length == 0)
+					{
+						continue;
+					}
+
+					MessageHandlerAttribute messageHandlerAttribute = (MessageHandlerAttribute)attrs[0];
+					if (messageHandlerAttribute.AppType != this.AppType)
+					{
+						continue;
+					}
+
+					object obj = Activator.CreateInstance(type);
+
+					IMRegister iMRegister = obj as IMRegister;
+					if (iMRegister == null)
+					{
+						throw new Exception($"message handler not inherit IEventSync or IEventAsync interface: {obj.GetType().FullName}");
+					}
+					iMRegister.Register(this);
+				}
+			}
+		}
+
+		public ushort GetOpcode(Type type)
+		{
+			return this.messageOpcode[type].Opcode;
+		}
+
+		public void RegisterHandler<T>(ushort opcode, Action<Entity, T> action)
+		{
+			if (!this.events.ContainsKey(opcode))
+			{
+				this.events.Add(opcode, new List<Action<Entity, MessageInfo>>());
+			}
+			List<Action<Entity, MessageInfo>> actions = this.events[opcode];
+
+			actions.Add((entity, messageInfo) =>
+			{
+				T t;
+				try
+				{
+                    t = MongoHelper.FromBson<T>(messageInfo.MessageBytes, messageInfo.Offset, messageInfo.Count);
+                }
+			    catch (Exception ex)
+			    {
+			        throw new Exception("解释消息失败:" + opcode, ex);
+			    }
+
+				action(entity, t);
+			});
+		}
+
+		public void RegisterRpcHandler<T>(ushort opcode, Action<Entity, T, uint> action)
+		{
+			if (!this.rpcHandlers.ContainsKey(opcode))
+			{
+				this.rpcHandlers.Add(opcode, new List<Action<Entity, MessageInfo>>());
+			}
+			List<Action<Entity, MessageInfo>> actions = this.rpcHandlers[opcode];
+
+			actions.Add((entity, messageInfo) =>
+			{
+				T t;
+				try
+				{
+					t = MongoHelper.FromBson<T>(messageInfo.MessageBytes, messageInfo.Offset, messageInfo.Count);
+				}
+				catch (Exception ex)
+				{
+					throw new Exception("解释消息失败:" + opcode, ex);
+				}
+
+				action(entity, t, messageInfo.RpcId);
+			});
+		}
+
+
+		public void Handle(Entity entity, ushort opcode, byte[] messageBytes, int offset)
+		{
+			List<Action<Entity, MessageInfo>> actions;
+			if (!this.events.TryGetValue(opcode, out actions))
+			{
+				Log.Error($"消息 {opcode} 没有处理");
+				return;
+			}
+
+			foreach (var ev in actions)
+			{
+				try
+				{
+					ev(entity, new MessageInfo { MessageBytes = messageBytes, Offset = offset, Count = messageBytes.Length - offset });
+				}
+				catch (Exception e)
+				{
+					Log.Error(e.ToString());
+				}
+			}
+		}
+
+		public void HandleRpc(Entity entity, ushort opcode, byte[] messageBytes, int offset, uint rpcId)
+		{
+			List<Action<Entity, MessageInfo>> actions;
+			if (!this.rpcHandlers.TryGetValue(opcode, out actions))
+			{
+				Log.Error($"Rpc消息 {opcode} 没有处理");
+				return;
+			}
+
+			foreach (var ev in actions)
+			{
+				try
+				{
+					ev(entity, new MessageInfo { MessageBytes = messageBytes, Offset = offset, Count = messageBytes.Length - offset, RpcId = rpcId });
+				}
+				catch (Exception e)
+				{
+					Log.Error(e.ToString());
+				}
+			}
+		}
+
+
+		public override void Dispose()
+		{
+			if (this.Id == 0)
+			{
+				return;
+			}
+
+			base.Dispose();
+		}
+	}
+}

+ 0 - 0
Unity/Assets/Scripts/Component/MessageHandlerComponent.cs.meta → Unity/Assets/Scripts/Component/MessageDispatherComponent.cs.meta


+ 0 - 155
Unity/Assets/Scripts/Component/MessageHandlerComponent.cs

@@ -1,155 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using Base;
-using Object = Base.Object;
-
-namespace Model
-{
-	[ObjectEvent]
-	public class MessageHandlerComponentEvent : ObjectEvent<MessageHandlerComponent>, ILoader, IAwake<string>
-	{
-		public void Load()
-		{
-			this.GetValue().Load();
-		}
-
-		public void Awake(string appType)
-		{
-			this.GetValue().Awake(appType);
-		}
-	}
-	
-	/// <summary>
-	/// 消息分发组件
-	/// </summary>
-	public class MessageHandlerComponent: Component, IMessageHandler
-	{
-		private string AppType;
-		private Dictionary<ushort, List<Action<Entity, byte[], int, int>>> events;
-		public Dictionary<Type, ushort> messageOpcode { get; private set; } = new Dictionary<Type, ushort>();
-		
-		public void Awake(string appType)
-		{
-			this.AppType = appType;
-			this.Load();
-		}
-
-		public void Load()
-		{
-			this.events = new Dictionary<ushort, List<Action<Entity, byte[], int, int>>>();
-			this.messageOpcode = new Dictionary<Type, ushort>();
-
-			Assembly[] assemblies = Object.ObjectManager.GetAssemblies();
-
-			foreach (Assembly assembly in assemblies)
-			{
-				Type[] types = assembly.GetTypes();
-				foreach (Type type in types)
-				{
-					object[] attrs = type.GetCustomAttributes(typeof(OpcodeAttribute), false);
-					if (attrs.Length == 0)
-					{
-						continue;
-					}
-
-					OpcodeAttribute opcodeAttribute = (OpcodeAttribute)attrs[0];
-					this.messageOpcode[type] = opcodeAttribute.Opcode;
-				}
-			}
-
-			foreach (Assembly assembly in assemblies)
-			{
-				Type[] types = assembly.GetTypes();
-				foreach (Type type in types)
-				{
-					object[] attrs = type.GetCustomAttributes(typeof(MessageAttribute), false);
-					if (attrs.Length == 0)
-					{
-						continue;
-					}
-
-					MessageAttribute messageAttribute = (MessageAttribute)attrs[0];
-					if (messageAttribute.AppType != this.AppType)
-					{
-						continue;
-					}
-
-					object obj = Activator.CreateInstance(type);
-
-					IMRegister iMRegister = obj as IMRegister;
-					if (iMRegister == null)
-					{
-						throw new Exception($"message handler not inherit IEventSync or IEventAsync interface: {obj.GetType().FullName}");
-					}
-					iMRegister.Register(this);
-				}
-			}
-		}
-
-		public ushort GetOpcode(Type type)
-		{
-			return this.messageOpcode[type];
-		}
-
-		public void RegisterHandler<T>(ushort opcode, Action<Entity, T, uint> action)
-		{
-			if (!this.events.ContainsKey(opcode))
-			{
-				this.events.Add(opcode, new List<Action<Entity, byte[], int, int>>());
-			}
-			List<Action<Entity, byte[], int, int>> actions = this.events[opcode];
-
-			actions.Add((entity, messageBytes, offset, count) =>
-			{
-				T t;
-				uint rpcId;
-				try
-				{
-					rpcId = BitConverter.ToUInt32(messageBytes, 2) & 0x7fffffff;
-                    t = MongoHelper.FromBson<T>(messageBytes, offset, count);
-                }
-			    catch (Exception ex)
-			    {
-			        throw new Exception("解释消息失败:" + opcode, ex);
-			    }
-
-				action(entity, t, rpcId);
-			});
-		}
-
-
-		public void Handle(Entity entity, ushort opcode, byte[] messageBytes, int offset)
-		{
-			List<Action<Entity, byte[], int, int>> actions;
-			if (!this.events.TryGetValue(opcode, out actions))
-			{
-				Log.Error($"消息 {opcode} 没有处理");
-				return;
-			}
-
-			foreach (var ev in actions)
-			{
-				try
-				{
-					ev(entity, messageBytes, offset, messageBytes.Length - offset);
-				}
-				catch (Exception e)
-				{
-					Log.Error(e.ToString());
-				}
-			}
-		}
-		
-
-		public override void Dispose()
-		{
-			if (this.Id == 0)
-			{
-				return;
-			}
-
-			base.Dispose();
-		}
-	}
-}

+ 9 - 12
Unity/Assets/Scripts/Message/Message.cs

@@ -3,25 +3,23 @@ using MongoDB.Bson.Serialization.Attributes;
 
 namespace Model
 {
-	[Opcode(1)]
+	[Message(1)]
 	[BsonIgnoreExtraElements]
-	public class C2S_Login
+	public class C2S_Login: ARequest
 	{
 		public string Account;
 		public string Password;
 	}
 
-	[Opcode(2)]
+	[Message(2)]
 	[BsonIgnoreExtraElements]
-	public class S2C_Login: IErrorMessage
+	public class S2C_Login: AResponse
 	{
-		public ErrorMessage ErrorMessage { get; set; }
-
 		public string Host;
 		public int Port;
 	}
 
-	[Opcode(3)]
+	[Message(3)]
 	[BsonIgnoreExtraElements]
 	public class S2C_ServerLog
 	{
@@ -29,16 +27,15 @@ namespace Model
 		public string Log;
 	}
 
-	[Opcode(4)]
+	[Message(4)]
 	[BsonIgnoreExtraElements]
-	public class C2S_SubscribeLog
+	public class C2S_SubscribeLog: ARequest
 	{
 	}
 
-	[Opcode(5)]
+	[Message(5)]
 	[BsonIgnoreExtraElements]
-	public class S2C_SubscribeLog: IErrorMessage
+	public class S2C_SubscribeLog: AResponse
 	{
-		public ErrorMessage ErrorMessage { get; set; }
 	}
 }

+ 3 - 3
Unity/Controller/Event/InitSceneStartEvent_InitGame.cs

@@ -12,15 +12,15 @@ namespace Controller
 	{
 		public async void Run()
 		{
-			Game.Scene.AddComponent<MessageHandlerComponent, string>("Client");
+			Game.Scene.AddComponent<MessageDispatherComponent, string>("Client");
 			NetworkComponent networkComponent = Game.Scene.AddComponent<NetworkComponent, NetworkProtocol>(NetworkProtocol.TCP);
 			Entity session = networkComponent.Get("127.0.0.1:8888");
 
 			try
 			{
 				// 订阅服务端日志, 服务端收到这个消息会将之后的日志转发给客户端
-				await session.GetComponent<MessageComponent>().CallAsync<S2C_SubscribeLog>(new C2S_SubscribeLog());
-				S2C_Login s2CLogin = await session.GetComponent<MessageComponent>().CallAsync<S2C_Login>(new C2S_Login {Account = "tanghai", Password = "1111111"});
+				await session.GetComponent<MessageComponent>().Call<C2S_SubscribeLog, S2C_SubscribeLog>(new C2S_SubscribeLog());
+				S2C_Login s2CLogin = await session.GetComponent<MessageComponent>().Call<C2S_Login, S2C_Login>(new C2S_Login {Account = "tanghai", Password = "1111111"});
 				Log.Info(MongoHelper.ToJson(s2CLogin));
 			}
 			catch (RpcException e)

+ 2 - 1
Unity/Controller/Message/S2C_ServerLogEvent.cs

@@ -3,9 +3,10 @@ using Model;
 
 namespace Controller
 {
+	[MessageHandler(AppType.Client)]
 	public class S2C_ServerLogEvent: AMEvent<S2C_ServerLog>
 	{
-		protected override void Run(Entity scene, S2C_ServerLog message, uint rpcId)
+		protected override void Run(Entity scene, S2C_ServerLog message)
 		{
 			Log.Debug(message.Log);
 		}

+ 2 - 5
Unity/Unity.CSharp.Editor.csproj

@@ -13,13 +13,11 @@
     <TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>
     <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
     <TargetFrameworkProfile>Unity Full v3.5</TargetFrameworkProfile>
-    <CompilerResponseFile>
-    </CompilerResponseFile>
+    <CompilerResponseFile></CompilerResponseFile>
     <UnityProjectType>Editor:5</UnityProjectType>
     <UnityBuildTarget>StandaloneWindows:5</UnityBuildTarget>
     <UnityVersion>5.4.2f1</UnityVersion>
-    <RootNamespace>
-    </RootNamespace>
+    <RootNamespace></RootNamespace>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugType>pdbonly</DebugType>
@@ -121,6 +119,5 @@
     <None Include="Assets\CSharp 6.0 Support\AsyncTools\Plugins\AsyncBridge.Net35.xml" />
     <None Include="Assets\CSharp 6.0 Support\AsyncTools\Plugins\System.Threading.xml" />
   </ItemGroup>
-  <ItemGroup />
   <Import Project="$(MSBuildExtensionsPath)\SyntaxTree\UnityVS\2015\UnityVS.CSharp.targets" />
 </Project>

+ 1 - 2
Unity/Unity.CSharp.Plugins.csproj

@@ -102,7 +102,7 @@
     <Compile Include="Assets\Plugins\Base\Message\AMEvent.cs" />
     <Compile Include="Assets\Plugins\Base\Message\IErrorMessage.cs" />
     <Compile Include="Assets\Plugins\Base\Message\IMRegister.cs" />
-    <Compile Include="Assets\Plugins\Base\Message\OpcodeAttribute.cs" />
+    <Compile Include="Assets\Plugins\Base\Message\MessageHandlerAttribute.cs" />
     <Compile Include="Assets\Plugins\Base\Message\MessageAttribute.cs" />
     <Compile Include="Assets\Plugins\Base\Message\RpcException.cs" />
     <Compile Include="Assets\Plugins\Base\MultiMap.cs" />
@@ -510,6 +510,5 @@
     <None Include="Assets\CSharp 6.0 Support\AsyncTools\Plugins\AsyncBridge.Net35.xml" />
     <None Include="Assets\CSharp 6.0 Support\AsyncTools\Plugins\System.Threading.xml" />
   </ItemGroup>
-  <ItemGroup />
   <Import Project="$(MSBuildExtensionsPath)\SyntaxTree\UnityVS\2015\UnityVS.CSharp.targets" />
 </Project>

+ 2 - 3
Unity/Unity.CSharp.csproj

@@ -80,12 +80,12 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Assets\Scripts\Component\ChildrenComponent.cs" />
-    <Compile Include="Assets\Scripts\Component\GameObjectComponent.cs" />
     <Compile Include="Assets\Scripts\Component\EventComponent.cs" />
+    <Compile Include="Assets\Scripts\Component\GameObjectComponent.cs" />
     <Compile Include="Assets\Scripts\Component\GlobalConfigComponent.cs" />
     <Compile Include="Assets\Scripts\Component\KVComponent.cs" />
     <Compile Include="Assets\Scripts\Component\MessageComponent.cs" />
-    <Compile Include="Assets\Scripts\Component\MessageHandlerComponent.cs" />
+    <Compile Include="Assets\Scripts\Component\MessageDispatherComponent.cs" />
     <Compile Include="Assets\Scripts\Component\NetworkComponent.cs" />
     <Compile Include="Assets\Scripts\Component\Scene.cs" />
     <Compile Include="Assets\Scripts\Component\TimeComponent.cs" />
@@ -111,6 +111,5 @@
     <None Include="Assets\CSharp 6.0 Support\AsyncTools\Plugins\AsyncBridge.Net35.xml" />
     <None Include="Assets\CSharp 6.0 Support\AsyncTools\Plugins\System.Threading.xml" />
   </ItemGroup>
-  <ItemGroup />
   <Import Project="$(MSBuildExtensionsPath)\SyntaxTree\UnityVS\2015\UnityVS.CSharp.targets" />
 </Project>