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

完善跨进程异常处理,异常通过序列化传送

tanghai 10 лет назад
Родитель
Сommit
df869dd5d1

+ 1 - 1
CSharp/Game/Controller/Controller.csproj

@@ -49,7 +49,7 @@
     <Compile Include="ConfigCategory\ServerInfoCategory.cs" />
     <Compile Include="ConfigCategory\UnitCategory.cs" />
     <Compile Include="Event\GateRecvServerMessageEvent.cs" />
-    <Compile Include="Event\LogicRecvRpcMessageEvent.cs" />
+    <Compile Include="Event\LogicRecvRequestMessageEvent.cs" />
     <Compile Include="Event\LogicRecvClientMessageEvent.cs" />
     <Compile Include="Event\GateRecvClientMessageEvent.cs" />
     <Compile Include="Factory\UnitPlayerFactory.cs" />

+ 3 - 3
CSharp/Game/Controller/Event/LogicRecvRpcMessageEvent.cs → CSharp/Game/Controller/Event/LogicRecvRequestMessageEvent.cs

@@ -5,8 +5,8 @@ using Model;
 
 namespace Controller
 {
-	[Event(EventType.LogicRecvRpcMessage, ServerType.All)]
-	public class LogicRecvRpcMessageEventEvent : IEventAsync
+	[Event(EventType.LogicRecvRequestMessage, ServerType.All)]
+	public class LogicRecvRequestMessageEvent : IEventAsync
 	{
 		public async Task RunAsync(Env env)
 		{
@@ -23,7 +23,7 @@ namespace Controller
 			catch (Exception e)
 			{
 				int requestId = env.Get<int>(EnvKey.RpcRequestId);
-				World.Instance.GetComponent<NetworkComponent>().RpcException(channel, requestId, 0, e.Message);
+				World.Instance.GetComponent<NetworkComponent>().RpcException(channel, requestId, e);
 				throw;
 			}
 		}

+ 0 - 2
CSharp/Game/Controller/MessageParseHelper.cs

@@ -1,6 +1,4 @@
 using System;
-using System.Collections.Generic;
-using System.Reflection.Emit;
 using Common.Helper;
 using Model;
 using MongoDB.Bson;

+ 2 - 0
CSharp/Game/Model/Component/GateNetworkComponent.cs

@@ -78,8 +78,10 @@ namespace Model
 					continue;
 				}
 
+#pragma warning disable 4014
 				World.Instance.GetComponent<EventComponent<EventAttribute>>()
 						.RunAsync(EventType.GateRecvClientMessage, env);
+#pragma warning restore 4014
 			}
 		}
 

+ 30 - 13
CSharp/Game/Model/Component/NetworkComponent.cs

@@ -1,5 +1,8 @@
 using System;
 using System.Collections.Generic;
+using System.IO;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
 using System.Threading.Tasks;
 using Common.Base;
 using Common.Helper;
@@ -111,23 +114,29 @@ namespace Model
 				// 如果是server message(发给client的消息),说明这是gate server,需要根据unitid查到channel,进行发送
 				if (MessageTypeHelper.IsServerMessage(opcode))
 				{
+#pragma warning disable 4014
 					World.Instance.GetComponent<EventComponent<EventAttribute>>()
 							.RunAsync(EventType.GateRecvServerMessage, env);
+#pragma warning restore 4014
 					continue;
 				}
 
 				// 进行消息分发
 				if (MessageTypeHelper.IsClientMessage(opcode))
 				{
+#pragma warning disable 4014
 					World.Instance.GetComponent<EventComponent<EventAttribute>>()
 							.RunAsync(EventType.LogicRecvClientMessage, env);
+#pragma warning restore 4014
 					continue;
 				}
 
 				if (MessageTypeHelper.IsRpcRequestMessage(opcode))
 				{
+#pragma warning disable 4014
 					World.Instance.GetComponent<EventComponent<EventAttribute>>()
-							.RunAsync(EventType.LogicRecvRpcMessage, env);
+							.RunAsync(EventType.LogicRecvRequestMessage, env);
+#pragma warning restore 4014
 				}
 			}
 		}
@@ -169,24 +178,29 @@ namespace Model
 			byte[] idBuffer = BitConverter.GetBytes(this.requestId);
 			channel.SendAsync(new List<byte[]> { typeBuffer, idBuffer, requestBuffer });
 			var tcs = new TaskCompletionSource<T>();
-			this.requestCallback[this.requestId] = (e, b) =>
+			this.requestCallback[this.requestId] = (messageBytes, status) =>
 			{
-				if (b == RpcResponseStatus.Timeout)
+				if (status == RpcResponseStatus.Timeout)
 				{
 					tcs.SetException(new Exception(
 						string.Format("rpc timeout {0} {1}", type, MongoHelper.ToJson(request))));
 					return;
 				}
-				if (b == RpcResponseStatus.Exception)
+				if (status == RpcResponseStatus.Exception)
 				{
-					RpcExcetionInfo errorInfo = MongoHelper.FromBson<RpcExcetionInfo>(e, 8);
-					tcs.SetException(new Exception(
-						string.Format("rpc exception {0} {1} {2}", type, MongoHelper.ToJson(request), MongoHelper.ToJson(errorInfo))));
+					BinaryFormatter formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.All));
+					Exception exception;
+					using (MemoryStream stream = new MemoryStream(messageBytes))
+					{
+						stream.Seek(6, SeekOrigin.Begin);
+						exception = (Exception)formatter.Deserialize(stream);
+					}
+					tcs.SetException(exception);
 					return;
 				}
 
 				// RpcResponseStatus.Succee
-				T response = MongoHelper.FromBson<T>(e, 6);
+				T response = MongoHelper.FromBson<T>(messageBytes, 6);
 				tcs.SetResult(response);
 			};
 
@@ -212,13 +226,16 @@ namespace Model
 		/// <summary>
 		/// Rpc响应
 		/// </summary>
-		public void RpcException(AChannel channel, int id, int errorCode, string errorInfo)
+		public void RpcException(AChannel channel, int id, Exception e)
 		{
-			byte[] typeBuffer = BitConverter.GetBytes(Opcode.RpcException);
+			byte[] opcodeBuffer = BitConverter.GetBytes(Opcode.RpcException);
 			byte[] idBuffer = BitConverter.GetBytes(id);
-			RpcExcetionInfo info = new RpcExcetionInfo(errorCode, errorInfo);
-			byte[] responseBuffer = MongoHelper.ToBson(info);
-			channel.SendAsync(new List<byte[]> { typeBuffer, idBuffer, responseBuffer });
+			BinaryFormatter formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.All));
+			using (MemoryStream stream = new MemoryStream())
+			{
+				formatter.Serialize(stream, e);
+				channel.SendAsync(new List<byte[]> { opcodeBuffer, idBuffer, stream.ToArray() });
+			}
 		}
 	}
 }

+ 1 - 1
CSharp/Game/Model/EventType.cs

@@ -8,7 +8,7 @@
 		public const int AfterRemoveBuff = 3;
 		public const int BuffTimeout = 4;
 		public const int LogicRecvClientMessage = 5;
-		public const int LogicRecvRpcMessage = 6;
+		public const int LogicRecvRequestMessage = 6;
 		public const int GateRecvClientMessage = 7;
 		public const int GateRecvServerMessage = 8;
 	}

+ 32 - 2
CSharp/Game/Model/GameException.cs

@@ -1,16 +1,46 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Model
 {
-	public class GameException: Exception
+	[Serializable]
+	public class GameException : Exception
 	{
 		public int ErrorCode { get; private set; }
 
 		public string ErrorInfo { get; private set; }
 
-		public GameException(int errorCode, string errorInfo): base(errorInfo)
+		public GameException(int errorCode, string message): base(message)
 		{
 			this.ErrorCode = errorCode;
 		}
+
+		public GameException(int errorCode, string format, params object[] args)
+			: base(string.Format(format, args))
+		{
+			this.ErrorCode = errorCode;
+		}
+
+		public GameException(int errorCode, string message, Exception innerException)
+			: base(message, innerException)
+		{
+			this.ErrorCode = errorCode;
+		}
+
+		public GameException(int errorCode, string format, Exception innerException, params object[] args)
+			: base(string.Format(format, args), innerException)
+		{
+			this.ErrorCode = errorCode;
+		}
+
+		protected GameException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+
+		public override string ToString()
+		{
+			return string.Format("error code: {0}, {1}", this.ErrorCode, base.ToString());
+		}
 	}
 }