Quellcode durchsuchen

重新设计了RPC服务端代码,使用起来更简单更不容易出错

tanghai vor 9 Jahren
Ursprung
Commit
1d1b0499af

+ 1 - 1
Server/App/Program.cs

@@ -23,7 +23,7 @@ namespace App
 				Object.ObjectManager.Register("Controller", controller);
 
 				Options options = Game.Scene.AddComponent<OptionsComponent, string[]>(args).Options;
-
+				
 				Game.Scene.AddComponent<EventComponent>();
 				Game.Scene.AddComponent<TimerComponent>();
 				Game.Scene.AddComponent<NetworkComponent, NetworkProtocol, string, int>(options.Protocol, options.Host, options.Port);

+ 3 - 3
Server/Base/Server.Base.csproj

@@ -122,12 +122,12 @@
     <Compile Include="..\..\Unity\Assets\Plugins\Base\LogType.cs">
       <Link>LogType.cs</Link>
     </Compile>
+    <Compile Include="..\..\Unity\Assets\Plugins\Base\Message\AMessage.cs">
+      <Link>Message\AMessage.cs</Link>
+    </Compile>
     <Compile Include="..\..\Unity\Assets\Plugins\Base\Message\AMEvent.cs">
       <Link>Message\AMEvent.cs</Link>
     </Compile>
-    <Compile Include="..\..\Unity\Assets\Plugins\Base\Message\IErrorMessage.cs">
-      <Link>Message\IErrorMessage.cs</Link>
-    </Compile>
     <Compile Include="..\..\Unity\Assets\Plugins\Base\Message\IMRegister.cs">
       <Link>Message\IMRegister.cs</Link>
     </Compile>

+ 0 - 15
Server/Controller/C2S_LoginEvent.cs

@@ -1,15 +0,0 @@
-using Base;
-using Model;
-
-namespace Controller
-{
-	[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>().Reply(rpcId, new S2C_Login());
-		}
-	}
-}

+ 17 - 0
Server/Controller/C2S_LoginHandler.cs

@@ -0,0 +1,17 @@
+using System;
+using Base;
+using Model;
+
+namespace Controller
+{
+	[MessageHandler(AppType.Realm)]
+	public class C2S_LoginHandler: AMRpcEvent<C2S_Login, S2C_Login>
+	{
+		protected override void Run(Entity scene, C2S_Login message, Action<S2C_Login> reply)
+		{
+			Log.Info(MongoHelper.ToJson(message));
+
+			reply(new S2C_Login());
+		}
+	}
+}

+ 5 - 4
Server/Controller/C2S_SubscribeLogEvent.cs → Server/Controller/C2S_SubscribeLogHandler.cs

@@ -1,18 +1,19 @@
-using Base;
+using System;
+using Base;
 using Model;
 
 namespace Controller
 {
 	[MessageHandler(AppType.Realm)]
-	public class C2S_SubscribeLogEvent : AMRpcEvent<C2S_SubscribeLog>
+	public class C2S_SubscribeLogHandler : AMRpcEvent<C2S_SubscribeLog, S2C_SubscribeLog>
 	{
-		protected override void Run(Entity entity, C2S_SubscribeLog message, uint rpcId)
+		protected override void Run(Entity entity, C2S_SubscribeLog message, Action<S2C_SubscribeLog> reply)
 		{
 			Log.Info(MongoHelper.ToJson(message));
 
 			entity.AddComponent<LogToClientComponent>();
 
-			entity.GetComponent<MessageComponent>().Reply(rpcId, new S2C_SubscribeLog());
+			reply(new S2C_SubscribeLog());
 		}
 	}
 }

+ 2 - 2
Server/Controller/Server.Controller.csproj

@@ -34,9 +34,9 @@
     <Reference Include="System.Core" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="C2S_SubscribeLogEvent.cs" />
+    <Compile Include="C2S_SubscribeLogHandler.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="C2S_LoginEvent.cs" />
+    <Compile Include="C2S_LoginHandler.cs" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\Base\Server.Base.csproj">

+ 4 - 1
Server/Model/Component/LogToClientComponent.cs

@@ -13,8 +13,11 @@ namespace Model
 
 	public class LogToClientComponent : Component
 	{
+		private string appType;
+
 		public void Awake()
 		{
+			this.appType = Game.Scene.GetComponent<OptionsComponent>().Options.AppType;
 			Log.Callback.Add(this.Id, this.LogToClient);
 		}
 
@@ -24,7 +27,7 @@ namespace Model
 			{
 				return;
 			}
-			this.GetComponent<MessageComponent>().Send(new S2C_ServerLog { Type = type, Log = message });
+			this.GetComponent<MessageComponent>().Send(new S2C_ServerLog { AppType = this.appType, Type = type, Log = message });
 		}
 
 		public override void Dispose()

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

@@ -41,6 +41,9 @@
     <Reference Include="System.Core" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="..\..\Unity\Assets\Scripts\Component\AppInfoComponent.cs">
+      <Link>Component\AppInfoComponent.cs</Link>
+    </Compile>
     <Compile Include="..\..\Unity\Assets\Scripts\Component\EventComponent.cs">
       <Link>Component\EventComponent.cs</Link>
     </Compile>

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

@@ -1,24 +1,28 @@
-namespace Base
+using System;
+
+namespace Base
 {
-	public abstract class AMEvent<T>: IMRegister
+	public abstract class AMEvent<Message>: IMRegister where Message: AMessage
 	{
-		protected abstract void Run(Entity scene, T message);
+		protected abstract void Run(Entity scene, Message message);
 
 		public void Register(IMessageDispather component)
 		{
-			ushort opcode = component.GetOpcode(typeof (T));
-			component.RegisterHandler<T>(opcode, Run);
+			ushort opcode = component.GetOpcode(typeof (Message));
+			component.RegisterHandler<Message>(opcode, Run);
 		}
 	}
 
-	public abstract class AMRpcEvent<T> : IMRegister
+	public abstract class AMRpcEvent<Request, Response> : IMRegister
+			where Request : ARequest
+			where Response: AResponse
 	{
-		protected abstract void Run(Entity scene, T message, uint rpcId);
+		protected abstract void Run(Entity scene, Request message, Action<Response> reply);
 
 		public void Register(IMessageDispather component)
 		{
-			ushort opcode = component.GetOpcode(typeof(T));
-			component.RegisterRpcHandler<T>(opcode, Run);
+			ushort opcode = component.GetOpcode(typeof(Request));
+			component.RegisterRpcHandler<Request, Response>(opcode, Run);
 		}
 	}
 }

+ 0 - 3
Unity/Assets/Plugins/Base/Message/IErrorMessage.cs → Unity/Assets/Plugins/Base/Message/AMessage.cs

@@ -6,7 +6,6 @@
 
 	public abstract class ARequest : AMessage
 	{
-		public uint RpcId;
 	}
 
 	/// <summary>
@@ -14,8 +13,6 @@
 	/// </summary>
 	public abstract class AResponse: AMessage
 	{
-		public uint RpcId;
-
 		public int ErrorCode = 0;
 		public string Message = "";
 	}

+ 0 - 0
Unity/Assets/Plugins/Base/Message/IErrorMessage.cs.meta → Unity/Assets/Plugins/Base/Message/AMessage.cs.meta


+ 5 - 2
Unity/Assets/Plugins/Base/Message/IMRegister.cs

@@ -5,8 +5,11 @@ namespace Base
 	public interface IMessageDispather
 	{
 		ushort GetOpcode(Type type);
-		void RegisterHandler<T>(ushort opcode, Action<Entity, T> action);
-		void RegisterRpcHandler<T>(ushort opcode, Action<Entity, T, uint> action);
+		void RegisterHandler<Message>(ushort opcode, Action<Entity, Message> action) where Message : AMessage;
+
+		void RegisterRpcHandler<Request, Response>(ushort opcode, Action<Entity, Request, Action<Response>> action) 
+			where Request : ARequest
+			where Response : AResponse;
 	}
 
 	public interface IMRegister

+ 23 - 0
Unity/Assets/Scripts/Component/AppInfoComponent.cs

@@ -0,0 +1,23 @@
+using Base;
+
+namespace Model
+{
+	[ObjectEvent]
+	public class AppInfoComponentEvent : ObjectEvent<AppInfoComponent>, IAwake<string>
+	{
+		public void Awake(string appType)
+		{
+			this.GetValue().Awake(appType);
+		}
+	}
+
+	public class AppInfoComponent : Component
+    {
+		private string AppType { get; set; }
+
+		public void Awake(string appType)
+		{
+			this.AppType = appType;
+		}
+    }
+}

+ 12 - 0
Unity/Assets/Scripts/Component/AppInfoComponent.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: d4852a0f714d73f43af0109603bd32ba
+timeCreated: 1476849603
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 21 - 12
Unity/Assets/Scripts/Component/MessageComponent.cs

@@ -99,20 +99,24 @@ namespace Model
 
 		private void RunDecompressedBytes(ushort opcode, uint rpcId, uint rpcFlag, byte[] messageBytes, int offset)
 		{
+			// 普通消息
 			if (rpcId == 0)
 			{
 				this.messageDispather.Handle(this.Owner, opcode, messageBytes, offset);
+				return;
 			}
 
 			// rpcFlag>0 表示这是一个rpc响应消息
 			if (rpcFlag > 0)
 			{
 				Action<byte[], int, int> action;
-				if (this.requestCallback.TryGetValue(rpcId, out action))
+				// Rpc回调有找不着的可能,因为client可能取消Rpc调用
+				if (!this.requestCallback.TryGetValue(rpcId, out action))
 				{
-					this.requestCallback.Remove(rpcId);
-					action(messageBytes, offset, messageBytes.Length - offset);
+					return;
 				}
+				this.requestCallback.Remove(rpcId);
+				action(messageBytes, offset, messageBytes.Length - offset);
 			}
 			else // 这是一个rpc请求消息
 			{
@@ -161,7 +165,6 @@ namespace Model
 			where Request: ARequest 
 			where Response : AResponse
 		{
-			request.RpcId = ++RpcId;
 			this.SendMessage(++RpcId, request);
 			var tcs = new TaskCompletionSource<Response>();
 			this.requestCallback[RpcId] = (bytes, offset, count) =>
@@ -185,12 +188,12 @@ namespace Model
 			return tcs.Task;
 		}
 
-		public void Send(object message)
+		public void Send<Message>(Message message) where Message: AMessage
 		{
 			this.SendMessage(0, message);
 		}
 
-		public void Reply<T>(uint rpcId, T message) where T: AResponse
+		public void Reply<Response>(uint rpcId, Response message) where Response: AResponse
 		{
 			this.SendMessage(rpcId, message, false);
 		}
@@ -199,18 +202,24 @@ namespace Model
 		{
 			ushort opcode = this.messageDispather.GetOpcode(message.GetType());
 			byte[] opcodeBytes = BitConverter.GetBytes(opcode);
-			if (rpcId > 0 && !isCall)
+			if (!isCall)
 			{
-				rpcId = rpcId | 0x4fffffff;
+				rpcId = rpcId | 0x40000000;
 			}
-			byte[] seqBytes = BitConverter.GetBytes(rpcId);
-			byte[] messageBytes = MongoHelper.ToBson(message);
 			
-			if (channel == null)
+			byte[] messageBytes = MongoHelper.ToBson(message);
+			if (messageBytes.Length > 100)
 			{
-				throw new Exception("game channel not found!");
+				byte[] newMessageBytes = ZipHelper.Compress(messageBytes);
+				if (newMessageBytes.Length < messageBytes.Length)
+				{
+					messageBytes = newMessageBytes;
+					rpcId = rpcId | 0x80000000;
+				}
 			}
 
+			byte[] seqBytes = BitConverter.GetBytes(rpcId);
+
 			channel.Send(new List<byte[]> { opcodeBytes, seqBytes, messageBytes });
 		}
 

+ 36 - 35
Unity/Assets/Scripts/Component/MessageDispatherComponent.cs

@@ -35,9 +35,9 @@ namespace Model
 		}
 
 		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>();
+		private Dictionary<ushort, List<Action<Entity, MessageInfo>>> handlers;
+		private Dictionary<ushort, Action<Entity, MessageInfo>> rpcHandlers;
+		private Dictionary<Type, MessageAttribute> messageOpcode { get; set; } = new Dictionary<Type, MessageAttribute>();
 		
 		public void Awake(string appType)
 		{
@@ -47,8 +47,8 @@ namespace Model
 
 		public void Load()
 		{
-			this.events = new Dictionary<ushort, List<Action<Entity, MessageInfo>>>();
-			this.rpcHandlers = new Dictionary<ushort, List<Action<Entity, MessageInfo>>>();
+			this.handlers = new Dictionary<ushort, List<Action<Entity, MessageInfo>>>();
+			this.rpcHandlers = new Dictionary<ushort, Action<Entity, MessageInfo>>();
 			this.messageOpcode = new Dictionary<Type, MessageAttribute>();
 
 			Assembly[] assemblies = Object.ObjectManager.GetAssemblies();
@@ -91,7 +91,7 @@ namespace Model
 					IMRegister iMRegister = obj as IMRegister;
 					if (iMRegister == null)
 					{
-						throw new Exception($"message handler not inherit IEventSync or IEventAsync interface: {obj.GetType().FullName}");
+						throw new Exception($"message handler not inherit AMEvent or AMRpcEvent abstract class: {obj.GetType().FullName}");
 					}
 					iMRegister.Register(this);
 				}
@@ -103,51 +103,55 @@ namespace Model
 			return this.messageOpcode[type].Opcode;
 		}
 
-		public void RegisterHandler<T>(ushort opcode, Action<Entity, T> action)
+		public void RegisterHandler<Message>(ushort opcode, Action<Entity, Message> action) where Message: AMessage
 		{
-			if (!this.events.ContainsKey(opcode))
+			if (!this.handlers.ContainsKey(opcode))
 			{
-				this.events.Add(opcode, new List<Action<Entity, MessageInfo>>());
+				this.handlers.Add(opcode, new List<Action<Entity, MessageInfo>>());
 			}
-			List<Action<Entity, MessageInfo>> actions = this.events[opcode];
+			List<Action<Entity, MessageInfo>> actions = this.handlers[opcode];
 
 			actions.Add((entity, messageInfo) =>
 			{
-				T t;
+				Message message;
 				try
 				{
-                    t = MongoHelper.FromBson<T>(messageInfo.MessageBytes, messageInfo.Offset, messageInfo.Count);
+                    message = MongoHelper.FromBson<Message>(messageInfo.MessageBytes, messageInfo.Offset, messageInfo.Count);
                 }
 			    catch (Exception ex)
 			    {
 			        throw new Exception("解释消息失败:" + opcode, ex);
 			    }
 
-				action(entity, t);
+				action(entity, message);
 			});
 		}
-
-		public void RegisterRpcHandler<T>(ushort opcode, Action<Entity, T, uint> action)
+		
+		public void RegisterRpcHandler<Request, Response>(ushort opcode, Action<Entity, Request, Action<Response>> action) 
+			where Request: ARequest 
+			where Response: AResponse
 		{
-			if (!this.rpcHandlers.ContainsKey(opcode))
+			if (this.rpcHandlers.ContainsKey(opcode))
 			{
-				this.rpcHandlers.Add(opcode, new List<Action<Entity, MessageInfo>>());
+				Log.Error($"rpc消息不能注册两次! opcode: {opcode}");
+				return;
 			}
-			List<Action<Entity, MessageInfo>> actions = this.rpcHandlers[opcode];
-
-			actions.Add((entity, messageInfo) =>
+			this.rpcHandlers.Add(opcode, (entity, messageInfo) =>
 			{
-				T t;
+				Request request;
 				try
 				{
-					t = MongoHelper.FromBson<T>(messageInfo.MessageBytes, messageInfo.Offset, messageInfo.Count);
+					request = MongoHelper.FromBson<Request>(messageInfo.MessageBytes, messageInfo.Offset, messageInfo.Count);
 				}
 				catch (Exception ex)
 				{
 					throw new Exception("解释消息失败:" + opcode, ex);
 				}
 
-				action(entity, t, messageInfo.RpcId);
+				action(entity, request, response =>
+				{
+					entity.GetComponent<MessageComponent>().Reply(messageInfo.RpcId, response);
+				});
 			});
 		}
 
@@ -155,7 +159,7 @@ namespace Model
 		public void Handle(Entity entity, ushort opcode, byte[] messageBytes, int offset)
 		{
 			List<Action<Entity, MessageInfo>> actions;
-			if (!this.events.TryGetValue(opcode, out actions))
+			if (!this.handlers.TryGetValue(opcode, out actions))
 			{
 				Log.Error($"消息 {opcode} 没有处理");
 				return;
@@ -176,23 +180,20 @@ namespace Model
 
 		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))
+			Action<Entity, MessageInfo> action;
+			if (!this.rpcHandlers.TryGetValue(opcode, out action))
 			{
 				Log.Error($"Rpc消息 {opcode} 没有处理");
 				return;
 			}
 
-			foreach (var ev in actions)
+			try
 			{
-				try
-				{
-					ev(entity, new MessageInfo { MessageBytes = messageBytes, Offset = offset, Count = messageBytes.Length - offset, RpcId = rpcId });
-				}
-				catch (Exception e)
-				{
-					Log.Error(e.ToString());
-				}
+				action(entity, new MessageInfo { MessageBytes = messageBytes, Offset = offset, Count = messageBytes.Length - offset, RpcId = rpcId });
+			}
+			catch (Exception e)
+			{
+				Log.Error(e.ToString());
 			}
 		}
 

+ 2 - 1
Unity/Assets/Scripts/Message/Message.cs

@@ -21,8 +21,9 @@ namespace Model
 
 	[Message(3)]
 	[BsonIgnoreExtraElements]
-	public class S2C_ServerLog
+	public class S2C_ServerLog: AMessage
 	{
+		public string AppType;
 		public LogType Type;
 		public string Log;
 	}

+ 2 - 2
Unity/Controller/Message/S2C_ServerLogEvent.cs → Unity/Controller/Message/S2C_ServerLogHandler.cs

@@ -4,11 +4,11 @@ using Model;
 namespace Controller
 {
 	[MessageHandler(AppType.Client)]
-	public class S2C_ServerLogEvent: AMEvent<S2C_ServerLog>
+	public class S2C_ServerLogHandler: AMEvent<S2C_ServerLog>
 	{
 		protected override void Run(Entity scene, S2C_ServerLog message)
 		{
-			Log.Debug(message.Log);
+			Log.Debug($"[{message.AppType}] [{message.Type}] {message.Log}");
 		}
 	}
 }

+ 1 - 1
Unity/Controller/Unity.Controller.csproj

@@ -54,7 +54,7 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Event\InitSceneStartEvent_InitGame.cs" />
-    <Compile Include="Message\S2C_ServerLogEvent.cs" />
+    <Compile Include="Message\S2C_ServerLogHandler.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   <ItemGroup>

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

@@ -100,7 +100,7 @@
     <Compile Include="Assets\Plugins\Base\Log.cs" />
     <Compile Include="Assets\Plugins\Base\LogType.cs" />
     <Compile Include="Assets\Plugins\Base\Message\AMEvent.cs" />
-    <Compile Include="Assets\Plugins\Base\Message\IErrorMessage.cs" />
+    <Compile Include="Assets\Plugins\Base\Message\AMessage.cs" />
     <Compile Include="Assets\Plugins\Base\Message\IMRegister.cs" />
     <Compile Include="Assets\Plugins\Base\Message\MessageHandlerAttribute.cs" />
     <Compile Include="Assets\Plugins\Base\Message\MessageAttribute.cs" />

+ 1 - 0
Unity/Unity.CSharp.csproj

@@ -83,6 +83,7 @@
     <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\AppInfoComponent.cs" />
     <Compile Include="Assets\Scripts\Component\KVComponent.cs" />
     <Compile Include="Assets\Scripts\Component\MessageComponent.cs" />
     <Compile Include="Assets\Scripts\Component\MessageDispatherComponent.cs" />