Browse Source

优化服务端AMRpcHandler

johnclot69 1 year ago
parent
commit
6772357a5d

+ 1 - 1
DotNet/Hotfix/Scenes/Benchmark/C2G_BenchmarkHandler.cs

@@ -5,7 +5,7 @@ namespace ET.Server
     [MessageHandler(SceneType.BenchmarkServer)]
     public class C2G_BenchmarkHandler: AMRpcHandler<C2G_Benchmark, G2C_Benchmark>
     {
-        protected override async ETTask Run(Session session, C2G_Benchmark request, G2C_Benchmark response)
+        protected override async ETTask Run(Session session, C2G_Benchmark request, G2C_Benchmark response, Action reply)
         {            
             BenchmarkServerComponent benchmarkServerComponent = session.DomainScene().GetComponent<BenchmarkServerComponent>();
             if (benchmarkServerComponent.Count++ % 1000000 == 0)

+ 4 - 2
DotNet/Hotfix/Scenes/Game/Handler/C2G_EnterMapHandler.cs

@@ -1,9 +1,11 @@
-namespace ET.Server
+using System;
+
+namespace ET.Server
 {
 	[MessageHandler(SceneType.Game)]
 	public class C2G_EnterMapHandler : AMRpcHandler<C2G_EnterMap, G2C_EnterMap>
 	{
-		protected override async ETTask Run(Session session, C2G_EnterMap request, G2C_EnterMap response)
+		protected override async ETTask Run(Session session, C2G_EnterMap request, G2C_EnterMap response, Action reply)
 		{
 			Player player = session.GetComponent<SessionPlayerComponent>().GetMyPlayer();
 

+ 8 - 1
DotNet/Hotfix/Scenes/Game/Handler/C2G_LoginGameHandler.cs

@@ -5,7 +5,7 @@ namespace ET.Server
 	[MessageHandler(SceneType.Game)]
 	public class C2G_LoginGameHandler : AMRpcHandler<C2G_LoginGate, G2C_LoginGate>
 	{
-		protected override async ETTask Run(Session session, C2G_LoginGate request, G2C_LoginGate response)
+		protected override async ETTask Run(Session session, C2G_LoginGate request, G2C_LoginGate response, Action reply)
 		{
 			Scene scene = session.DomainScene();
 			string account = scene.GetComponent<GameSessionKeyComponent>().Get(request.Key);
@@ -16,6 +16,13 @@ namespace ET.Server
 				return;
 			}
 			
+			// 重复请求
+			if (session.GetComponent<SessionLockComponent>() != null)
+			{
+				response.Error = ErrorCode.ERR_RequestRepeatedly;
+				return;
+			}
+			
 			session.RemoveComponent<SessionAcceptTimeoutComponent>();
 
 			PlayerComponent playerComponent = scene.GetComponent<PlayerComponent>();

+ 2 - 1
DotNet/Hotfix/Scenes/Game/Handler/C2G_PingHandler.cs

@@ -8,9 +8,10 @@ namespace ET.Server
 	[MessageHandler(SceneType.Game)]
 	public class C2G_PingHandler : AMRpcHandler<C2G_Ping, G2C_Ping>
 	{
-		protected override async ETTask Run(Session session, C2G_Ping request, G2C_Ping response)
+		protected override async ETTask Run(Session session, C2G_Ping request, G2C_Ping response, Action reply)
 		{
 			response.Time = TimeHelper.ClientNow();
+			reply();
 			await ETTask.CompletedTask;
 		}
 	}

+ 23 - 4
DotNet/Hotfix/Scenes/Realm/Handler/C2R_LoginHandler.cs

@@ -1,19 +1,38 @@
 using System;
 using System.Net;
 
-
 namespace ET.Server
 {
+	/// <summary>
+	/// 登录验证
+	/// </summary>
 	[MessageHandler(SceneType.Realm)]
 	public class C2R_LoginHandler : AMRpcHandler<C2R_Login, R2C_Login>
 	{
-		protected override async ETTask Run(Session session, C2R_Login request, R2C_Login response)
+		protected override async ETTask Run(Session session, C2R_Login request, R2C_Login response, Action reply)
 		{
+			if (session.DomainScene().SceneType != SceneType.Realm)
+			{
+				Log.Debug($"请求的Scene错误...SceneType={session.DomainScene().SceneType}");
+				session.Dispose();
+				return;
+			}
+			
+			// 重复请求
+			if (session.GetComponent<SessionLockComponent>() != null)
+			{
+				response.Error = ErrorCode.ERR_RequestRepeatedly;
+				reply();
+				return;
+			}
+			
+			session.AddComponent<SessionLockComponent>();
+			
 			// 随机分配一个Game
 			StartSceneConfig config = RealmGameAddressHelper.GetGame(session.DomainZone());
-			Log.Debug($"gate address: {MongoHelper.ToJson(config)}");
+			Log.Debug($"Game address: {MongoHelper.ToJson(config)}");
 			
-			// 向gate请求一个key,客户端可以拿着这个key连接gate
+			// 向game请求一个key,客户端可以拿着这个key连接game
 			G2R_GetLoginKey g2RGetLoginKey = (G2R_GetLoginKey) await ActorMessageSenderComponent.Instance.Call(
 				config.InstanceId, new R2G_GetLoginKey() {Account = request.Account});
 

+ 16 - 11
DotNet/Model/Module/Message/AMRpcHandler.cs

@@ -4,7 +4,7 @@ namespace ET.Server
 {
     public abstract class AMRpcHandler<Request, Response>: IMHandler where Request : class, IRequest where Response : class, IResponse
     {
-        protected abstract ETTask Run(Session session, Request request, Response response);
+        protected abstract ETTask Run(Session session, Request request, Response response, Action reply);
 
         public void Handle(Session session, object message)
         {
@@ -22,29 +22,34 @@ namespace ET.Server
                 }
 
                 int rpcId = request.RpcId;
+
                 long instanceId = session.InstanceId;
 
                 Response response = Activator.CreateInstance<Response>();
 
+                void Reply()
+                {
+                    // 等回调回来,session可以已经断开了,所以需要判断session InstanceId是否一样
+                    if (session.InstanceId != instanceId)
+                    {
+                        return;
+                    }
+
+                    response.RpcId = rpcId;
+                    session.Send(response);
+                }
+
                 try
                 {
-                    await this.Run(session, request, response);
+                    await this.Run(session, request, response, Reply);
                 }
                 catch (Exception exception)
                 {
                     Log.Error(exception);
                     response.Error = ErrorCore.ERR_RpcFail;
                     response.Message = exception.ToString();
+                    Reply();
                 }
-                
-                // 等回调回来,session可以已经断开了,所以需要判断session InstanceId是否一样
-                if (session.InstanceId != instanceId)
-                {
-                    return;
-                }
-                
-                response.RpcId = rpcId; // 在这里设置rpcId是为了防止在Run中不小心修改rpcId字段
-                session.Send(response);
             }
             catch (Exception e)
             {

+ 7 - 0
DotNet/Model/Scenes/Game/SessionLockComponent.cs

@@ -0,0 +1,7 @@
+namespace ET.Server
+{
+    [ComponentOf(typeof (Session))]
+    public class SessionLockComponent: Entity, IAwake
+    {
+    }
+}

+ 55 - 10
Unity/Assets/Scripts/Codes/Model/Share/Module/Message/ErrorCode.cs

@@ -1,17 +1,62 @@
 namespace ET
 {
+    /// <summary>
+    /// 1-11004 是SocketError请看SocketError定义
+    ///-----------------------------------
+    /// 100000-109999是Core层的错误
+    /// 110000以下的错误请看ErrorCore.cs
+    /// 这里配置逻辑层的错误码
+    /// 110000 - 200000是抛异常的错误
+    ///  200001以上不抛异常
+    /// </summary>
     public static partial class ErrorCode
     {
         public const int ERR_Success = 0;
 
-        // 1-11004 是SocketError请看SocketError定义
-        //-----------------------------------
-        // 100000-109999是Core层的错误
-        
-        // 110000以下的错误请看ErrorCore.cs
-        
-        // 这里配置逻辑层的错误码
-        // 110000 - 200000是抛异常的错误
-        // 200001以上不抛异常
+        /** 系统错误 **/
+        public const int ERR_SystemError = 200002;
+        /** 操作错误 **/
+        public const int ERR_OperationError = 200003;
+        /** 参数错误 **/
+        public const int ERR_ParameterError = 200004;
+        /** 登陆错误 **/
+        public const int ERR_LoginError = 200005;
+        /** 重复请求 **/
+        public const int ERR_RequestRepeatedly = 200006;
+        /** 请输入用户名和密码 **/
+        public const int ERR_UserNameOrPasswordIsNull = 200007;
+        /** 用户名或密码格式错误 **/
+        public const int ERR_UserNameOrPasswordFormatError = 200008;
+        /** 用户名或密码错误 **/
+        public const int ERR_UserNameOrPasswordError = 200009;
+        /** 已被永久封禁 **/
+        public const int ERR_UserPermanentBan = 200010;
+        /** 已被限时封禁 **/
+        public const int ERR_UserBanTime = 200011;
+        /** 请输入角色名 **/
+        public const int ERR_PlayerNameIsNull = 200012;
+        /** 该职业有误 **/
+        public const int ERR_ProNotProper = 200013;
+        /** 该性别有误 **/
+        public const int ERR_SexNotProper = 200014;
+        /** 创角失败 **/
+        public const int ERR_CreatePlayerError = 200015;
+        /** 该角色已经绑定 **/
+        public const int ERR_PlayerIdIsBind = 200016;
+        /** 选角出错 **/
+        public const int ERR_BindPlayerError = 200017;
+        /** 操作过快,请稍后重试 **/
+        public const int ERR_OperationToFast = 200018;
+        /** 场景不存在 **/
+        public const int ERR_EnterMapError = 200019;
+        /** 配置错误 **/
+        public const int ERR_ConfigError = 200020;
+        /** 账号已在其他地方登录 **/
+        public const int ERR_AccountAlreadyLoggedInElsewhere = 200021;
+        /** 角色已在其他地方登录 **/
+        public const int ERR_PlayerAlreadyLoggedInElsewhere = 200022;
+        /** 创建单位玩家有误 **/
+        public const int ERR_CreateUnitPlayerError = 200023;
+
     }
-}
+}