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

1.增加ActorManager,用来管理所有Acotr,
2.增加Actor消息分发组件,分发Actor消息

tanghai 8 лет назад
Родитель
Сommit
2d6115bd7e

+ 12 - 2
Server/App/Program.cs

@@ -27,7 +27,8 @@ namespace App
 				LogManager.Configuration.Variables["appId"] = startConfig.AppId.ToString();
 
 				Log.Info("server start........................");
-				
+
+				Game.Scene.AddComponent<OpcodeTypeComponent>();
 				Game.Scene.AddComponent<MessageDispatherComponent, AppType>(startConfig.AppType);
 
 				// 根据不同的AppType添加不同的组件
@@ -42,11 +43,17 @@ namespace App
 						Game.Scene.AddComponent<AppManagerComponent>();
 						break;
 					case AppType.Realm:
+						Game.Scene.AddComponent<ActorMessageDispatherComponent>();
+						Game.Scene.AddComponent<ActorManagerComponent>();
+						Game.Scene.AddComponent<ActorComponent>();
 						Game.Scene.AddComponent<NetInnerComponent, string, int>(innerConfig.Host, innerConfig.Port);
 						Game.Scene.AddComponent<NetOuterComponent, string, int>(outerConfig.Host, outerConfig.Port);
 						Game.Scene.AddComponent<RealmGateAddressComponent>();
 						break;
 					case AppType.Gate:
+						Game.Scene.AddComponent<ActorMessageDispatherComponent>();
+						Game.Scene.AddComponent<ActorManagerComponent>();
+						Game.Scene.AddComponent<ActorComponent>();
 						Game.Scene.AddComponent<NetInnerComponent, string, int>(innerConfig.Host, innerConfig.Port);
 						Game.Scene.AddComponent<NetOuterComponent, string, int>(outerConfig.Host, outerConfig.Port);
 						Game.Scene.AddComponent<GateSessionKeyComponent>();
@@ -56,9 +63,12 @@ namespace App
 						Game.Scene.AddComponent<LocationComponent>();
 						break;
 					case AppType.AllServer:
+						Game.Scene.AddComponent<LocationComponent>();
+						Game.Scene.AddComponent<ActorMessageDispatherComponent>();
+						Game.Scene.AddComponent<ActorManagerComponent>();
+						Game.Scene.AddComponent<ActorComponent>();
 						Game.Scene.AddComponent<NetInnerComponent, string, int>(innerConfig.Host, innerConfig.Port);
 						Game.Scene.AddComponent<NetOuterComponent, string, int>(outerConfig.Host, outerConfig.Port);
-						Game.Scene.AddComponent<LocationComponent>();
 						Game.Scene.AddComponent<AppManagerComponent>();
 						Game.Scene.AddComponent<RealmGateAddressComponent>();
 						Game.Scene.AddComponent<GateSessionKeyComponent>();

+ 57 - 0
Server/Model/Component/ActorComponent.cs

@@ -0,0 +1,57 @@
+using System;
+using Base;
+
+namespace Model
+{
+	[ObjectEvent]
+	public class ActorComponentEvent : ObjectEvent<ActorComponent>, IAwake
+	{
+		public void Awake()
+		{
+			this.Get().Awake();
+		}
+	}
+
+	/// <summary>
+	/// 挂上这个组件表示该Entity是一个Actor, 它会将Entity位置注册到Location Server
+	/// </summary>
+	public class ActorComponent: Component
+	{
+		private long actorId;
+
+		public async void Awake()
+		{
+			try
+			{
+				this.actorId = this.Owner.Id;
+				Game.Scene.GetComponent<ActorManagerComponent>().Add(this.Owner);
+				await Game.Scene.GetComponent<LocationProxyComponent>().Add(this.actorId);
+			}
+			catch (Exception e)
+			{
+				Log.Error(e.ToString());
+			}
+		}
+
+		public override async void Dispose()
+		{
+			try
+			{
+				if (this.Id == 0)
+				{
+					return;
+				}
+
+				base.Dispose();
+
+				Game.Scene.GetComponent<ActorManagerComponent>().Remove(actorId);
+
+				await Game.Scene.GetComponent<LocationProxyComponent>().Remove(this.actorId);
+			}
+			catch (Exception e)
+			{
+				Log.Error(e.ToString());
+			}
+		}
+	}
+}

+ 51 - 0
Server/Model/Component/ActorManagerComponent.cs

@@ -0,0 +1,51 @@
+using System.Collections.Generic;
+
+namespace Model
+{
+	[ObjectEvent]
+	public class ActorManagerComponentEvent : ObjectEvent<ActorManagerComponent>, IAwake
+	{
+		public void Awake()
+		{
+			this.Get().Awake();
+		}
+	}
+
+	/// <summary>
+	/// 用来管理该服务器上所有的Actor对象
+	/// </summary>
+	public class ActorManagerComponent : Component
+	{
+		private readonly Dictionary<long, Entity> dictionary = new Dictionary<long, Entity>();
+
+		public void Awake()
+		{
+			
+		}
+
+		public void Add(Entity entity)
+		{
+			dictionary.Add(entity.Id, entity);
+		}
+
+		public void Remove(long id)
+		{
+			this.dictionary.Remove(id);
+		}
+
+		public Entity Get(long id)
+		{
+			this.dictionary.TryGetValue(id, out Entity entity);
+			return entity;
+		}
+
+		public override void Dispose()
+		{
+			if (this.Id == 0)
+			{
+				return;
+			}
+			base.Dispose();
+		}
+	}
+}

+ 89 - 0
Server/Model/Component/ActorMessageDispatherComponent.cs

@@ -0,0 +1,89 @@
+using System;
+using System.Collections.Generic;
+using Base;
+
+namespace Model
+{
+	[ObjectEvent]
+	public class ActorMessageDispatherComponentEvent : ObjectEvent<ActorMessageDispatherComponent>, IAwake<AppType>, ILoad
+	{
+		public void Awake(AppType appType)
+		{
+			this.Get().Awake(appType);
+		}
+
+		public void Load()
+		{
+			this.Get().Load();
+		}
+	}
+
+	/// <summary>
+	/// Actor消息分发组件
+	/// </summary>
+	public class ActorMessageDispatherComponent : Component
+	{
+		private AppType AppType;
+		private Dictionary<Type, IMActorHandler> handlers;
+		
+		public void Awake(AppType appType)
+		{
+			this.AppType = appType;
+			this.Load();
+		}
+
+		public void Load()
+		{
+			this.handlers = new Dictionary<Type, IMActorHandler>();
+
+			Type[] types = DllHelper.GetMonoTypes();
+
+			foreach (Type type in types)
+			{
+				object[] attrs = type.GetCustomAttributes(typeof(ActorMessageHandlerAttribute), false);
+				if (attrs.Length == 0)
+				{
+					continue;
+				}
+
+				ActorMessageHandlerAttribute messageHandlerAttribute = (ActorMessageHandlerAttribute)attrs[0];
+				if (!messageHandlerAttribute.Type.Is(this.AppType))
+				{
+					continue;
+				}
+
+				object obj = Activator.CreateInstance(type);
+
+				IMActorHandler imHandler = obj as IMActorHandler;
+				if (imHandler == null)
+				{
+					throw new Exception($"message handler not inherit AMEvent or AMRpcEvent abstract class: {obj.GetType().FullName}");
+				}
+
+				Type messageType = imHandler.GetMessageType();
+				handlers.Add(messageType, imHandler);
+			}
+		}
+
+		public void Handle(Session session, MessageInfo messageInfo)
+		{
+			if (!this.handlers.TryGetValue(messageInfo.Message.GetType(), out IMActorHandler handler))
+			{
+				Log.Error($"not found message handler: {messageInfo.Message.GetType()}");
+				return;
+			}
+			Entity entity = this.GetComponent<ActorManagerComponent>().Get(((AActorMessage)messageInfo.Message).Id);
+			handler.Handle(session, entity, messageInfo);
+		}
+
+		public override void Dispose()
+		{
+			if (this.Id == 0)
+			{
+				return;
+			}
+
+			base.Dispose();
+		}
+	}
+}

+ 15 - 15
Server/Model/Component/LocationComponent.cs

@@ -19,11 +19,11 @@ namespace Model
 
 	public sealed class LocationLockTask : LocationTask
 	{
-		private readonly string key;
+		private readonly long key;
 
 		private readonly TaskCompletionSource<bool> tcs;
 
-		public LocationLockTask(string key)
+		public LocationLockTask(long key)
 		{
 			this.key = key;
 			this.tcs = new TaskCompletionSource<bool>();
@@ -53,11 +53,11 @@ namespace Model
 
 	public sealed class LocationQueryTask : LocationTask
 	{
-		private readonly string key;
+		private readonly long key;
 
 		private readonly TaskCompletionSource<string> tcs;
 
-		public LocationQueryTask(string key)
+		public LocationQueryTask(long key)
 		{
 			this.key = key;
 			this.tcs = new TaskCompletionSource<string>();
@@ -87,29 +87,29 @@ namespace Model
 
 	public class LocationComponent : Component
 	{
-		private readonly Dictionary<string, string> locations = new Dictionary<string, string>();
+		private readonly Dictionary<long, string> locations = new Dictionary<long, string>();
 
-		private readonly HashSet<string> lockSet = new HashSet<string>();
+		private readonly HashSet<long> lockSet = new HashSet<long>();
 
-		private readonly Dictionary<string, Queue<LocationTask>> taskQueues = new Dictionary<string,Queue<LocationTask>>();
+		private readonly Dictionary<long, Queue<LocationTask>> taskQueues = new Dictionary<long, Queue<LocationTask>>();
 
-		public void Add(string key, string address)
+		public void Add(long key, string address)
 		{
 			this.locations[key] = address;
 		}
 
-		public void Remove(string key)
+		public void Remove(long key)
 		{
 			this.locations.Remove(key);
 		}
 
-		public string Get(string key)
+		public string Get(long key)
 		{
 			this.locations.TryGetValue(key, out string location);
 			return location;
 		}
 
-		public void Lock(string key)
+		public void Lock(long key)
 		{
 			if (this.lockSet.Contains(key))
 			{
@@ -118,7 +118,7 @@ namespace Model
 			this.lockSet.Add(key);
 		}
 
-		public void UnLock(string key)
+		public void UnLock(long key)
 		{
 			this.lockSet.Remove(key);
 
@@ -144,7 +144,7 @@ namespace Model
 			}
 		}
 
-		public Task<bool> LockAsync(string key)
+		public Task<bool> LockAsync(long key)
 		{
 			if (!this.lockSet.Contains(key))
 			{
@@ -157,7 +157,7 @@ namespace Model
 			return task.Task;
 		}
 
-		public Task<string> GetAsync(string key)
+		public Task<string> GetAsync(long key)
 		{
 			if (!this.lockSet.Contains(key))
 			{
@@ -170,7 +170,7 @@ namespace Model
 			return task.Task;
 		}
 
-		public void AddTask(string key, LocationTask task)
+		public void AddTask(long key, LocationTask task)
 		{
 			if (!this.taskQueues.TryGetValue(key, out Queue<LocationTask> tasks))
 			{

+ 44 - 0
Server/Model/Component/LocationProxyComponent.cs

@@ -0,0 +1,44 @@
+using System.Threading.Tasks;
+
+namespace Model
+{
+	[ObjectEvent]
+	public class LocationProxyComponentEvent : ObjectEvent<LocationProxyComponent>, IAwake
+	{
+		public void Awake()
+		{
+			this.Get().Awake();
+		}
+	}
+
+	public class LocationProxyComponent : Component
+	{
+		public string LocationAddress;
+
+		public void Awake()
+		{
+			this.LocationAddress = Game.Scene.GetComponent<StartConfigComponent>().LocationConfig.GetComponent<InnerConfig>().Address;
+		}
+
+		public async Task Add(long key)
+		{			
+			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(this.LocationAddress);
+			await session.Call<ObjectAddRequest, ObjectAddResponse>(new ObjectAddRequest() { Key = key });
+		}
+
+		public async Task Remove(long key)
+		{
+			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(this.LocationAddress);
+			await session.Call<ObjectRemoveRequest, ObjectRemoveResponse>(new ObjectRemoveRequest() { Key = key });
+		}
+		
+		public override void Dispose()
+		{
+			if (this.Id == 0)
+			{
+				return;
+			}
+			base.Dispose();
+		}
+	}
+}

+ 6 - 46
Server/Model/Component/MessageDispatherComponent.cs

@@ -24,9 +24,7 @@ namespace Model
 	public class MessageDispatherComponent : Component
 	{
 		private AppType AppType;
-		private Dictionary<ushort, List<IMHandler>> handlers;
-		private Dictionary<Type, MessageAttribute> messageOpcode { get; set; }
-		private Dictionary<ushort, Type> opcodeType { get; set; }
+		private Dictionary<Type, List<IMHandler>> handlers;
 
 		public void Awake(AppType appType)
 		{
@@ -36,24 +34,9 @@ namespace Model
 
 		public void Load()
 		{
-			this.handlers = new Dictionary<ushort, List<IMHandler>>();
-			this.messageOpcode = new Dictionary<Type, MessageAttribute>();
-			this.opcodeType = new Dictionary<ushort, Type>();
+			this.handlers = new Dictionary<Type, List<IMHandler>>();
 			
 			Type[] types = DllHelper.GetMonoTypes();
-			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;
-				this.opcodeType[messageAttribute.Opcode] = type;
-			}
-
 			foreach (Type type in types)
 			{
 				object[] attrs = type.GetCustomAttributes(typeof(MessageHandlerAttribute), false);
@@ -77,46 +60,23 @@ namespace Model
 				}
 
 				Type messageType = imHandler.GetMessageType();
-				ushort opcode = this.GetOpcode(messageType);
-				if (!this.handlers.TryGetValue(opcode, out List<IMHandler> list))
+				if (!this.handlers.TryGetValue(messageType, out List<IMHandler> list))
 				{
 					list = new List<IMHandler>();
-					this.handlers.Add(opcode, list);
+					this.handlers.Add(messageType, list);
 				}
 				list.Add(imHandler);
 			}
 		}
 
-		public ushort GetOpcode(Type type)
-		{
-			if (!this.messageOpcode.TryGetValue(type, out MessageAttribute messageAttribute))
-			{
-				throw new Exception($"查找Opcode失败: {type.Name}");
-			}
-			return messageAttribute.Opcode;
-		}
-
-		public Type GetType(ushort opcode)
-		{
-			if (!this.opcodeType.TryGetValue(opcode, out Type messageType))
-			{
-				throw new Exception($"查找Opcode Type失败: {opcode}");
-			}
-			return messageType;
-		}
-
 		public void Handle(Session session, MessageInfo messageInfo)
 		{
-			if (!this.handlers.TryGetValue(messageInfo.Opcode, out List<IMHandler> actions))
+			if (!this.handlers.TryGetValue(messageInfo.Message.GetType(), out List<IMHandler> actions))
 			{
 				Log.Error($"消息 {messageInfo.Opcode} 没有处理");
 				return;
 			}
-
-			Type messageType = this.GetType(messageInfo.Opcode);
-			object message = MongoHelper.FromBson(messageType, messageInfo.MessageBytes, messageInfo.Offset, messageInfo.Count);
-			messageInfo.Message = message;
-
+			
 			foreach (IMHandler ev in actions)
 			{
 				try

+ 77 - 0
Server/Model/Component/OpcodeTypeComponent.cs

@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+
+namespace Model
+{
+	[ObjectEvent]
+	public class OpcodeTypeComponentEvent : ObjectEvent<OpcodeTypeComponent>, IAwake, ILoad
+	{
+		public void Awake()
+		{
+			this.Get().Awake();
+		}
+
+		public void Load()
+		{
+			this.Get().Load();
+		}
+	}
+	
+	public class OpcodeTypeComponent : Component
+	{
+		private Dictionary<ushort, Type> opcodeType { get; set; }
+		private Dictionary<Type, ActorMessageAttribute> messageOpcode { get; set; }
+
+		public void Awake()
+		{
+			this.Load();
+		}
+
+		public void Load()
+		{
+			this.opcodeType = new Dictionary<ushort, Type>();
+
+			Type[] types = DllHelper.GetMonoTypes();
+			foreach (Type type in types)
+			{
+				object[] attrs = type.GetCustomAttributes(typeof(ActorMessageAttribute), false);
+				if (attrs.Length == 0)
+				{
+					continue;
+				}
+
+				ActorMessageAttribute messageAttribute = (ActorMessageAttribute)attrs[0];
+				this.messageOpcode[type] = messageAttribute;
+				this.opcodeType[messageAttribute.Opcode] = type;
+			}
+		}
+
+		public ushort GetOpcode(Type type)
+		{
+			if (!this.messageOpcode.TryGetValue(type, out ActorMessageAttribute messageAttribute))
+			{
+				throw new Exception($"查找Opcode失败: {type.Name}");
+			}
+			return messageAttribute.Opcode;
+		}
+
+		public Type GetType(ushort opcode)
+		{
+			if (!this.opcodeType.TryGetValue(opcode, out Type messageType))
+			{
+				throw new Exception($"查找Opcode Type失败: {opcode}");
+			}
+			return messageType;
+		}
+
+		public override void Dispose()
+		{
+			if (this.Id == 0)
+			{
+				return;
+			}
+
+			base.Dispose();
+		}
+	}
+}

+ 7 - 0
Server/Model/Component/StartConfigComponent.cs

@@ -26,6 +26,8 @@ namespace Model
 
 		public StartConfig RealmConfig { get; private set; }
 
+		public StartConfig LocationConfig { get; private set; }
+
 		public void Awake(string path, int appId)
 		{
 			string[] ss = File.ReadAllText(path).Split('\n');
@@ -41,6 +43,11 @@ namespace Model
 					StartConfig startConfig = MongoHelper.FromJson<StartConfig>(s2);
 					this.allConfigs.Add(startConfig);
 					this.configDict.Add(startConfig.AppId, startConfig);
+
+					if (startConfig.AppType == AppType.Location)
+					{
+						LocationConfig = startConfig;
+					}
 				}
 				catch (Exception)
 				{

+ 8 - 8
Server/Model/Entity/Message/InnerMessage.cs

@@ -16,12 +16,12 @@ namespace Model
{
	[Message(Opcode.R2G_GetLoginKey)]
	[BsonIgnoreExtraElements]
 
 
	[Message(Opcode.A2M_Reload)]
	[BsonIgnoreExtraElements]
	public class A2M_Reload : AResponse
	{
	}
 
-
	[Message(Opcode.G2G_LockRequest)]
	[BsonIgnoreExtraElements]
	public class G2G_LockRequest : ARequest
	{
		public string Address;
	}
+
	[Message(Opcode.G2G_LockRequest)]
	[BsonIgnoreExtraElements]
	public class G2G_LockRequest : ARequest
	{
		public long Id;
		public string Address;
	}
 
 
	[Message(Opcode.G2G_LockResponse)]
	[BsonIgnoreExtraElements]
 	public class G2G_LockResponse : AResponse
	{
	}
 
-	[Message(Opcode.G2G_LockReleaseRequest)]
	[BsonIgnoreExtraElements]
	public class G2G_LockReleaseRequest : ARequest
	{
		public string Address;
	}
+	[Message(Opcode.G2G_LockReleaseRequest)]
	[BsonIgnoreExtraElements]
	public class G2G_LockReleaseRequest : ARequest
	{
		public long Id;
		public string Address;
	}
 
 
	[Message(Opcode.G2G_LockReleaseResponse)]
	[BsonIgnoreExtraElements]
	public class G2G_LockReleaseResponse : AResponse
	{
	}
 
	[Message(Opcode.DBSaveRequest)]
	[BsonIgnoreExtraElements]
	public class DBSaveRequest : ARequest
	{
		public bool NeedCache = true;
@@ -36,7 +36,7 @@ namespace Model
{
	[Message(Opcode.R2G_GetLoginKey)]
	[BsonIgnoreExtraElements]
 
 	[Message(Opcode.DBSaveResponse)]
	[BsonIgnoreExtraElements]
	public class DBSaveResponse : AResponse
	{
	}
 
-
	[Message(Opcode.DBQueryRequest)]
	[BsonIgnoreExtraElements]
	public class DBQueryRequest : ARequest
	{
		public string CollectionName { get; set; }
		public bool NeedCache = true;
	}
+
	[Message(Opcode.DBQueryRequest)]
	[BsonIgnoreExtraElements]
	public class DBQueryRequest : ARequest
	{
		public long Id;
		public string CollectionName { get; set; }
		public bool NeedCache = true;
	}
 
 
	[Message(Opcode.DBQueryResponse)]
	[BsonIgnoreExtraElements]
	public class DBQueryResponse : AResponse
	{
		public Entity Entity;
	}
 
@@ -48,22 +48,22 @@ namespace Model
{
	[Message(Opcode.R2G_GetLoginKey)]
	[BsonIgnoreExtraElements]
 
 	[Message(Opcode.DBQueryJsonResponse)]
	[BsonIgnoreExtraElements]
	public class DBQueryJsonResponse : AResponse
	{
		public List<Entity> Entitys;
	}
 
-	[Message(Opcode.ObjectAddRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectAddRequest : ARequest
	{
		public string Key { get; set; }
	}
+	[Message(Opcode.ObjectAddRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectAddRequest : ARequest
	{
		public long Key { get; set; }
	}
 
 	[Message(Opcode.ObjectAddResponse)]
	[BsonIgnoreExtraElements]
	public class ObjectAddResponse : AResponse
	{
	}
 
-	[Message(Opcode.ObjectRemoveRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectRemoveRequest : ARequest
	{
		public string Key { get; set; }
	}
+	[Message(Opcode.ObjectRemoveRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectRemoveRequest : ARequest
	{
		public long Key { get; set; }
	}
 
 	[Message(Opcode.ObjectRemoveResponse)]
	[BsonIgnoreExtraElements]
	public class ObjectRemoveResponse : AResponse
	{
	}
 
-	[Message(Opcode.ObjectLockRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectLockRequest : ARequest
	{
		public string Key { get; set; }
	}
+	[Message(Opcode.ObjectLockRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectLockRequest : ARequest
	{
		public long Key { get; set; }
	}
 
 	[Message(Opcode.ObjectLockResponse)]
	[BsonIgnoreExtraElements]
	public class ObjectLockResponse : AResponse
	{
	}
 
-	[Message(Opcode.ObjectUnLockRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectUnLockRequest : ARequest
	{
		public string Key { get; set; }
	}
+	[Message(Opcode.ObjectUnLockRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectUnLockRequest : ARequest
	{
		public long Key { get; set; }
	}
 
 	[Message(Opcode.ObjectUnLockResponse)]
	[BsonIgnoreExtraElements]
	public class ObjectUnLockResponse : AResponse
	{
	}
 
-	[Message(Opcode.ObjectGetRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectGetRequest : ARequest
	{
		public string Key { get; set; }
	}
+	[Message(Opcode.ObjectGetRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectGetRequest : ARequest
	{
		public long Key { get; set; }
	}
 
 	[Message(Opcode.ObjectGetResponse)]
	[BsonIgnoreExtraElements]
	public class ObjectGetResponse : AResponse
	{
		public string Location { get; set; }
	}
}

+ 19 - 7
Server/Model/Entity/Session.cs

@@ -86,8 +86,7 @@ namespace Model
 		{
 			int offset = 0;
 			uint flag = BitConverter.ToUInt32(messageBytes, 2);
-			uint rpcFlag = flag & 0x40000000;
-			uint rpcId = flag & 0x3fffffff;
+
 			bool isCompressed = (flag & 0x80000000) > 0;
 			if (isCompressed) // 最高位为1,表示有压缩,需要解压缩
 			{
@@ -99,16 +98,29 @@ namespace Model
 				offset = 6;
 			}
 
-			this.RunDecompressedBytes(opcode, rpcId, rpcFlag, messageBytes, offset);
+			this.RunDecompressedBytes(opcode, flag, messageBytes, offset);
 		}
 
-		private void RunDecompressedBytes(ushort opcode, uint rpcId, uint rpcFlag, byte[] messageBytes, int offset)
+		private void RunDecompressedBytes(ushort opcode, uint flag, byte[] messageBytes, int offset)
 		{
+			uint rpcFlag = flag & 0x40000000;
+			uint rpcId = flag & 0x3fffffff;
+
 			// 普通消息或者是Rpc请求消息
 			if (rpcFlag == 0)
 			{
 				MessageInfo messageInfo = new MessageInfo(opcode, messageBytes, offset, rpcId);
-				this.network.Owner.GetComponent<MessageDispatherComponent>().Handle(this, messageInfo);
+				Type messageType = this.network.Owner.GetComponent<OpcodeTypeComponent>().GetType(messageInfo.Opcode);
+				object message = MongoHelper.FromBson(messageType, messageInfo.MessageBytes, messageInfo.Offset, messageInfo.Count);
+				messageInfo.Message = message;
+				if (message is AActorMessage)
+				{
+					this.network.Owner.GetComponent<ActorMessageDispatherComponent>().Handle(this, messageInfo);
+				}
+				else
+				{
+					this.network.Owner.GetComponent<MessageDispatherComponent>().Handle(this, messageInfo);
+				}
 				return;
 			}
 
@@ -198,7 +210,7 @@ namespace Model
 			this.SendMessage(0, message);
 		}
 
-		public void Reply<Response>(uint rpcId, Response message) where Response : AResponse
+		public void Reply<Response>(uint rpcId, Response message)
 		{
 			if (this.Id == 0)
 			{
@@ -210,7 +222,7 @@ namespace Model
 		private void SendMessage(uint rpcId, object message, bool isCall = true)
 		{
 			//Log.Debug($"send: {message.ToJson()}");
-			ushort opcode = this.network.Owner.GetComponent<MessageDispatherComponent>().GetOpcode(message.GetType());
+			ushort opcode = this.network.Owner.GetComponent<OpcodeTypeComponent>().GetOpcode(message.GetType());
 			byte[] opcodeBytes = BitConverter.GetBytes(opcode);
 			if (!isCall)
 			{

+ 20 - 0
Server/Model/Message/AActorMessage.cs

@@ -0,0 +1,20 @@
+namespace Model
+{
+	public abstract class AActorMessage
+	{
+		public long Id { get; set; }
+	}
+
+	public abstract class AActorRequest : AMessage
+	{
+	}
+
+	/// <summary>
+	/// 服务端回的RPC消息需要继承这个抽象类
+	/// </summary>
+	public abstract class AActorResponse
+	{
+		public int Error = 0;
+		public string Message = "";
+	}
+}

+ 73 - 0
Server/Model/Message/AMActorHandler.cs

@@ -0,0 +1,73 @@
+using System;
+using Base;
+
+namespace Model
+{
+	public abstract class AMActorHandler<E, Message>: IMActorHandler where E: Entity where Message : AActorMessage
+	{
+		protected abstract void Run(E entity, Message message);
+
+		public void Handle(Session session, Entity entity, MessageInfo messageInfo)
+		{
+			Message message = messageInfo.Message as Message;
+			if (message == null)
+			{
+				Log.Error($"消息类型转换错误: {messageInfo.Message.GetType().Name} to {typeof (Message).Name}");
+			}
+			E e = entity as E;
+			if (e == null)
+			{
+				Log.Error($"Actor类型转换错误: {entity.GetType().Name} to {typeof(E).Name}");
+			}
+			this.Run(e, message);
+		}
+
+		public Type GetMessageType()
+		{
+			return typeof (Message);
+		}
+	}
+
+	public abstract class AMActorRpcHandler<Request, Response>: IMActorHandler where Request : AActorRequest where Response : AActorResponse
+	{
+		protected static void ReplyError(Response response, Exception e, Action<Response> reply)
+		{
+			Log.Error(e.ToString());
+			response.Error = ErrorCode.ERR_RpcFail;
+			response.Message = e.ToString();
+			reply(response);
+		}
+
+		protected abstract void Run(Entity entity, Request message, Action<Response> reply);
+
+		public void Handle(Session session, Entity entity,  MessageInfo messageInfo)
+		{
+			try
+			{
+				Request request = messageInfo.Message as Request;
+				if (request == null)
+				{
+					Log.Error($"消息类型转换错误: {messageInfo.Message.GetType().Name} to {typeof (Request).Name}");
+				}
+				this.Run(session, request, response =>
+				{
+					// 等回调回来,session可以已经断开了,所以需要判断session id是否为0
+					if (session.Id == 0)
+					{
+						return;
+					}
+					session.Reply(messageInfo.RpcId, response);
+				});
+			}
+			catch (Exception e)
+			{
+				throw new Exception($"解释消息失败: {messageInfo.Opcode}", e);
+			}
+		}
+
+		public Type GetMessageType()
+		{
+			return typeof (Request);
+		}
+	}
+}

+ 1 - 2
Server/Model/Message/AMessage.cs

@@ -2,7 +2,6 @@
 {
 	public abstract class AMessage
 	{
-		public long Id { get; set; }
 	}
 
 	public abstract class ARequest: AMessage
@@ -12,7 +11,7 @@
 	/// <summary>
 	/// 服务端回的RPC消息需要继承这个抽象类
 	/// </summary>
-	public abstract class AResponse: AMessage
+	public abstract class AResponse
 	{
 		public int Error = 0;
 		public string Message = "";

+ 14 - 0
Server/Model/Message/ActorMessageAttribute.cs

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

+ 14 - 0
Server/Model/Message/ActorMessageHandlerAttribute.cs

@@ -0,0 +1,14 @@
+using System;
+
+namespace Model
+{
+	public class ActorMessageHandlerAttribute : Attribute
+	{
+		public AppType Type { get; }
+
+		public ActorMessageHandlerAttribute(AppType appType)
+		{
+			this.Type = appType;
+		}
+	}
+}

+ 10 - 0
Server/Model/Message/IMActorHandler.cs

@@ -0,0 +1,10 @@
+using System;
+
+namespace Model
+{
+	public interface IMActorHandler
+	{
+		void Handle(Session session, Entity entity, MessageInfo messageInfo);
+		Type GetMessageType();
+	}
+}

+ 10 - 0
Server/Model/Server.Model.csproj

@@ -48,6 +48,8 @@
     <Reference Include="System.Core" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Component\OpcodeTypeComponent.cs" />
+    <Compile Include="Component\ActorManagerComponent.cs" />
     <Compile Include="Component\BenchmarkComponent.cs" />
     <Compile Include="Component\ConfigComponent.cs" />
     <Compile Include="Component\Config\ClientConfig.cs" />
@@ -60,6 +62,8 @@
     <Compile Include="Component\DBProxyComponent.cs" />
     <Compile Include="Component\EventComponent.cs" />
     <Compile Include="Component\KVComponent.cs" />
+    <Compile Include="Component\LocationProxyComponent.cs" />
+    <Compile Include="Component\ActorMessageDispatherComponent.cs" />
     <Compile Include="Component\MessageDispatherComponent.cs" />
     <Compile Include="Component\NetInnerComponent.cs" />
     <Compile Include="Component\NetOuterComponent.cs" />
@@ -67,6 +71,7 @@
     <Compile Include="Component\RobotComponent.cs" />
     <Compile Include="Component\TimerComponent.cs" />
     <Compile Include="Component\LocationComponent.cs" />
+    <Compile Include="Component\ActorComponent.cs" />
     <Compile Include="Component\UnitComponent.cs" />
     <Compile Include="Component\Unit\MasterComponent.cs" />
     <Compile Include="Component\Unit\LockComponent.cs" />
@@ -103,12 +108,17 @@
     <Compile Include="Event\EventIdType.cs" />
     <Compile Include="Event\IEvent.cs" />
     <Compile Include="Helper\DllHelper.cs" />
+    <Compile Include="Message\AActorMessage.cs" />
     <Compile Include="Message\AMessage.cs" />
+    <Compile Include="Message\AMActorHandler.cs" />
     <Compile Include="Message\AMHandler.cs" />
     <Compile Include="Message\AppType.cs" />
     <Compile Include="Message\ErrorCode.cs" />
+    <Compile Include="Message\IMActorHandler.cs" />
     <Compile Include="Message\IMHandler.cs" />
+    <Compile Include="Message\ActorMessageAttribute.cs" />
     <Compile Include="Message\MessageAttribute.cs" />
+    <Compile Include="Message\ActorMessageHandlerAttribute.cs" />
     <Compile Include="Message\MessageHandlerAttribute.cs" />
     <Compile Include="Message\MessageInfo.cs" />
     <Compile Include="Message\OpcodeHelper.cs" />