瀏覽代碼

增加一个不抛异常的rpc调用,主要是为了解决ActorLocationSender中,如果接收方收到消息出了错误,会导致整个ActorLocationSender堵塞

tanghai 6 年之前
父節點
當前提交
ceafebcb6d

+ 7 - 0
Server/Hotfix/Module/Actor/ActorMessageSenderHelper.cs

@@ -17,5 +17,12 @@ namespace ETHotfix
 			message.ActorId = self.ActorId;
 			return (IActorResponse)await session.Call(message);
 		}
+		
+		public static async ETTask<IActorResponse> CallWithoutException(this ActorMessageSender self, IActorRequest message)
+		{
+			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(self.Address);
+			message.ActorId = self.ActorId;
+			return (IActorResponse)await session.CallWithoutException(message);
+		}
 	}
 }

+ 13 - 1
Server/Hotfix/Module/ActorLocation/ActorLocationSenderSystem.cs

@@ -136,7 +136,19 @@ namespace ETHotfix
 		private static async ETTask RunTask(this ActorLocationSender self, ActorTask task)
 		{
 			ActorMessageSender actorMessageSender = Game.Scene.GetComponent<ActorMessageSenderComponent>().Get(self.ActorId);
-			IActorResponse response = await actorMessageSender.Call(task.ActorRequest);
+			IActorResponse response;
+			try
+			{
+				// 这里必须使用不抛异常的rpc,因为服务端handler很可能出现错误,返回一个rpc fail的错误,结果这里抛了异常
+				// 这里抛了异常就会导致队列中的消息无法继续发送,导致整个actorlocationsender堵塞
+				response = await actorMessageSender.CallWithoutException(task.ActorRequest);
+			}
+			catch (Exception e)
+			{
+				self.GetParent<ActorLocationSenderComponent>().Remove(self.Id);
+				return;
+			}
+			
 			
 			// 发送成功
 			switch (response.Error)

+ 4 - 5
Unity/Assets/Model/Module/Message/ErrorCode.cs

@@ -8,11 +8,11 @@ namespace ETModel
 		//-----------------------------------
 		// 100000 以上,避免跟SocketError冲突
 		public const int ERR_MyErrorCode = 100000;
-		
+		public const int ERR_NotFoundActor = 100002;
 		public const int ERR_ActorNoMailBoxComponent = 100003;
 		public const int ERR_ActorRemove = 100004;
 		public const int ERR_PacketParserError = 100005;
-		
+		public const int ERR_ConnectGateKeyError = 100006;
 		public const int ERR_KcpCantConnect = 102005;
 		public const int ERR_KcpChannelTimeout = 102006;
 		public const int ERR_KcpRemoteDisconnect = 102007;
@@ -30,14 +30,13 @@ namespace ETModel
 		
 		public const int ERR_RpcFail = 102001;
 		public const int ERR_ReloadFail = 102003;
-		public const int ERR_ConnectGateKeyError = 100105;
+		
 		public const int ERR_ActorLocationNotFound = 102004;
+		
 		//-----------------------------------
 		// 小于这个Rpc会抛异常,大于这个异常的error需要自己判断处理,也就是说需要处理的错误应该要大于该值
 		public const int ERR_Exception = 200000;
 		
-		public const int ERR_NotFoundActor = 200002;
-		
 		public const int ERR_AccountOrPasswordError = 200102;
 		//-----------------------------------
 		public static bool IsRpcNeedThrowException(int error)

+ 1 - 1
Unity/Assets/Model/Module/Message/IMessage.cs

@@ -16,7 +16,7 @@
 		int RpcId { get; set; }
 	}
 
-	public class ResponseMessage : IResponse
+	public class ErrorResponse : IResponse
 	{
 		public int Error { get; set; }
 		public string Message { get; set; }

+ 51 - 22
Unity/Assets/Model/Module/Message/Session.cs

@@ -70,7 +70,7 @@ namespace ETModel
 			
 			foreach (Action<IResponse> action in this.requestCallback.Values.ToArray())
 			{
-				action.Invoke(new ResponseMessage { Error = this.Error });
+				action.Invoke(new ErrorResponse { Error = this.Error });
 			}
 
 			//int error = this.channel.Error;
@@ -174,54 +174,83 @@ namespace ETModel
 
 			action(response);
 		}
-
-		public ETTask<IResponse> Call(IRequest request)
+		
+		public ETTask<IResponse> CallWithoutException(IRequest request)
 		{
 			int rpcId = ++RpcId;
 			var tcs = new ETTaskCompletionSource<IResponse>();
 
 			this.requestCallback[rpcId] = (response) =>
 			{
-				try
+				if (response is ErrorResponse errorResponse)
 				{
-					if (ErrorCode.IsRpcNeedThrowException(response.Error))
-					{
-						throw new RpcException(response.Error, response.Message);
-					}
-
-					tcs.SetResult(response);
+					tcs.SetException(new Exception($"session close, errorcode: {errorResponse.Error} {errorResponse.Message}"));
+					return;
 				}
-				catch (Exception e)
+				tcs.SetResult(response);
+			};
+
+			request.RpcId = rpcId;
+			this.Send(request);
+			return tcs.Task;
+		}
+		
+		public ETTask<IResponse> CallWithoutException(IRequest request, CancellationToken cancellationToken)
+		{
+			int rpcId = ++RpcId;
+			var tcs = new ETTaskCompletionSource<IResponse>();
+
+			this.requestCallback[rpcId] = (response) =>
+			{
+				if (response is ErrorResponse errorResponse)
 				{
-					tcs.SetException(new Exception($"Rpc Error: {request.GetType().FullName}", e));
+					tcs.SetException(new Exception($"session close, errorcode: {errorResponse.Error} {errorResponse.Message}"));
+					return;
 				}
+				tcs.SetResult(response);
 			};
 
+			cancellationToken.Register(() => this.requestCallback.Remove(rpcId));
+
 			request.RpcId = rpcId;
 			this.Send(request);
 			return tcs.Task;
 		}
 
-		public ETTask<IResponse> Call(IRequest request, CancellationToken cancellationToken)
+		public ETTask<IResponse> Call(IRequest request)
 		{
 			int rpcId = ++RpcId;
 			var tcs = new ETTaskCompletionSource<IResponse>();
 
 			this.requestCallback[rpcId] = (response) =>
 			{
-				try
+				if (ErrorCode.IsRpcNeedThrowException(response.Error))
 				{
-					if (ErrorCode.IsRpcNeedThrowException(response.Error))
-					{
-						throw new RpcException(response.Error, response.Message);
-					}
-
-					tcs.SetResult(response);
+					tcs.SetException(new Exception($"Rpc Error: {request.GetType().FullName} {response.Error}"));
+					return;
 				}
-				catch (Exception e)
+
+				tcs.SetResult(response);
+			};
+
+			request.RpcId = rpcId;
+			this.Send(request);
+			return tcs.Task;
+		}
+
+		public ETTask<IResponse> Call(IRequest request, CancellationToken cancellationToken)
+		{
+			int rpcId = ++RpcId;
+			var tcs = new ETTaskCompletionSource<IResponse>();
+
+			this.requestCallback[rpcId] = (response) =>
+			{
+				if (ErrorCode.IsRpcNeedThrowException(response.Error))
 				{
-					tcs.SetException(new Exception($"Rpc Error: {request.GetType().FullName}", e));
+					tcs.SetException(new Exception($"Rpc Error: {request.GetType().FullName} {response.Error}"));
 				}
+
+				tcs.SetResult(response);
 			};
 
 			cancellationToken.Register(() => this.requestCallback.Remove(rpcId));