Browse Source

如果不wait async方法将无法在其被调用函数捕捉async抛出的异常

tanghai 13 years ago
parent
commit
4c1f962f6e

+ 21 - 15
CSharp/App/LoginClient/LoginClient.cs

@@ -1,5 +1,4 @@
 using System;
-using System.Collections.Generic;
 using System.Net.Sockets;
 using ENet;
 using Log;
@@ -32,23 +31,30 @@ namespace LoginClient
 		public async void Login(
 			string hostName, ushort port, string account, string password)
 		{
-			++this.sessionId;
+			int loginSessionId = ++this.sessionId;
 
-			// 登录realm
-			var tcpClient = new TcpClient();
-			await tcpClient.ConnectAsync(hostName, port);
-			Tuple<string, ushort, SRP6Client> realmInfo = null; // ip, port, K
-			using (var realmSession = new RealmSession(this.sessionId, new TcpChannel(tcpClient)))
+			try
 			{
-				realmInfo = await realmSession.Login(account, password);
-				Logger.Trace("session: {0}, login success!", realmSession.ID);
-			}
+				// 登录realm
+				var tcpClient = new TcpClient();
+				await tcpClient.ConnectAsync(hostName, port);
+				Tuple<string, ushort, SRP6Client> realmInfo = null; // ip, port, K
+				using (var realmSession = new RealmSession(loginSessionId, new TcpChannel(tcpClient)))
+				{
+					realmInfo = await realmSession.Login(account, password);
+					Logger.Trace("session: {0}, login success!", realmSession.ID);
+				}
 
-			// 登录gate
-			Peer peer = await this.clientHost.ConnectAsync(realmInfo.Item1, realmInfo.Item2);
-			gateSession = new GateSession(this.sessionId, new ENetChannel(peer));
-			await gateSession.Login(realmInfo.Item3);
-			await gateSession.HandleMessages();
+				// 登录gate
+				Peer peer = await this.clientHost.ConnectAsync(realmInfo.Item1, realmInfo.Item2);
+				gateSession = new GateSession(loginSessionId, new ENetChannel(peer));
+				await gateSession.Login(realmInfo.Item3);
+				await gateSession.HandleMessages();
+			}
+			catch (Exception e)
+			{
+				Logger.Trace("session: {0}, exception: {1}", loginSessionId, e.ToString());
+			}
 		}
 
 		public void SendCommand(string command)

+ 14 - 0
CSharp/App/LoginClient/LoginException.cs

@@ -1,11 +1,25 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace LoginClient
 {
+	[Serializable]
 	public class LoginException: Exception
 	{
+		public LoginException()
+		{
+		}
+
 		public LoginException(string message): base(message)
 		{
 		}
+
+		public LoginException(string message, Exception inner): base(message, inner)
+		{
+		}
+
+		protected LoginException(SerializationInfo info, StreamingContext context)
+		{
+		}
 	}
 }

+ 25 - 33
CSharp/App/LoginClient/RealmSession.cs

@@ -1,7 +1,4 @@
 using System;
-using System.Collections.Generic;
-using System.Net.Sockets;
-using System.Numerics;
 using System.Security.Cryptography;
 using System.Threading.Tasks;
 using Helper;
@@ -26,7 +23,7 @@ namespace LoginClient
 			this.MessageChannel.Dispose();
 		}
 
-		public async Task<SMSG_Password_Protect_Type> Handle_CMSG_AuthLogonPermit_Response()
+		public async Task<SMSG_Password_Protect_Type> Handle_SMSG_Password_Protect_Type()
 		{
 			var result = await this.MessageChannel.RecvMessage();
 			ushort opcode = result.Item1;
@@ -40,13 +37,6 @@ namespace LoginClient
 
 			var smsgPasswordProtectType = 
 				ProtobufHelper.FromBytes<SMSG_Password_Protect_Type>(message);
-			
-			if (smsgPasswordProtectType.Code != 200)
-			{
-				throw new LoginException(string.Format(
-					"session: {0}, SMSG_Lock_For_Safe_Time: {1}", 
-					this.ID, JsonHelper.ToString(smsgPasswordProtectType)));
-			}
 
 			return smsgPasswordProtectType;
 		}
@@ -68,17 +58,6 @@ namespace LoginClient
 			var smsgAuthLogonChallengeResponse =
 				ProtobufHelper.FromBytes<SMSG_Auth_Logon_Challenge_Response>(message);
 
-			if (smsgAuthLogonChallengeResponse.ErrorCode != ErrorCode.REALM_AUTH_SUCCESS)
-			{
-				Logger.Trace("error code: {0}", smsgAuthLogonChallengeResponse.ErrorCode);
-				throw new LoginException(
-					string.Format("session: {0}, SMSG_Auth_Logon_Challenge_Response: {1}",
-					this.ID, JsonHelper.ToString(smsgAuthLogonChallengeResponse)));
-			}
-
-			Logger.Debug("SMSG_Auth_Logon_Challenge_Response: \n{0}", 
-				JsonHelper.ToString(smsgAuthLogonChallengeResponse));
-
 			return smsgAuthLogonChallengeResponse;
 		}
 
@@ -95,14 +74,6 @@ namespace LoginClient
 			}
 
 			var smsgAuthLogonProofM2 = ProtobufHelper.FromBytes<SMSG_Auth_Logon_Proof_M2>(message);
-
-			if (smsgAuthLogonProofM2.ErrorCode != ErrorCode.REALM_AUTH_SUCCESS)
-			{
-				throw new LoginException(string.Format(
-					"session: {0}, SMSG_Auth_Logon_Proof_M2: {1}", 
-					this.ID, JsonHelper.ToString(smsgAuthLogonProofM2)));
-			}
-
 			return smsgAuthLogonProofM2;
 		}
 
@@ -136,19 +107,33 @@ namespace LoginClient
 				Account = account.ToByteArray(),
 				PasswordMd5 = passwordMd5Hex
 			};
-
+			
 			Logger.Trace("session: {0}, account: {1}, password: {2}", this.ID,
 				cmsgAuthLogonPermit.Account.ToStr(), cmsgAuthLogonPermit.PasswordMd5.ToHex());
 
 			this.MessageChannel.SendMessage(MessageOpcode.CMSG_AUTH_LOGON_PERMIT, cmsgAuthLogonPermit);
-			await this.Handle_CMSG_AuthLogonPermit_Response();
+
+			var smsgPasswordProtectType = await this.Handle_SMSG_Password_Protect_Type();
+			if (smsgPasswordProtectType.Code != 200)
+			{
+				throw new LoginException(string.Format(
+					"session: {0}, SMSG_Password_Protect_Type: {1}",
+					this.ID, JsonHelper.ToString(smsgPasswordProtectType)));
+			}
 
 			// 这个消息已经没有作用,只用来保持原有的代码流程
 			var cmsgAuthLogonChallenge = new CMSG_Auth_Logon_Challenge();
 			this.MessageChannel.SendMessage(
 				MessageOpcode.CMSG_AUTH_LOGON_CHALLENGE, cmsgAuthLogonChallenge);
+
 			var smsgAuthLogonChallengeResponse = 
 				await this.Handle_SMSG_Auth_Logon_Challenge_Response();
+			if (smsgAuthLogonChallengeResponse.ErrorCode != ErrorCode.REALM_AUTH_SUCCESS)
+			{
+				throw new LoginException(
+					string.Format("session: {0}, SMSG_Auth_Logon_Challenge_Response: {1}",
+					this.ID, JsonHelper.ToString(smsgAuthLogonChallengeResponse)));
+			}
 
 			Logger.Trace("session: {0}, SMSG_Auth_Logon_Challenge_Response OK", this.ID);
 
@@ -178,7 +163,14 @@ namespace LoginClient
 				M = srp6Client.M.ToUBigIntegerArray()
 			};
 			this.MessageChannel.SendMessage(MessageOpcode.CMSG_AUTH_LOGON_PROOF, cmsgAuthLogonProof);
-			await this.Handle_SMSG_Auth_Logon_Proof_M2();
+
+			var smsgAuthLogonProofM2 = await this.Handle_SMSG_Auth_Logon_Proof_M2();
+			if (smsgAuthLogonProofM2.ErrorCode != ErrorCode.REALM_AUTH_SUCCESS)
+			{
+				throw new LoginException(string.Format(
+					"session: {0}, SMSG_Auth_Logon_Proof_M2: {1}",
+					this.ID, JsonHelper.ToString(smsgAuthLogonProofM2)));
+			}
 
 			Logger.Trace("session: {0}, SMSG_Auth_Logon_Proof_M2 OK", this.ID);
 

+ 2 - 10
CSharp/App/Modules/Robot/RobotViewModel.cs

@@ -1,7 +1,6 @@
 using System;
 using System.ComponentModel.Composition;
 using System.Windows.Threading;
-using Log;
 using Microsoft.Practices.Prism.ViewModel;
 
 namespace Modules.Robot
@@ -129,15 +128,8 @@ namespace Modules.Robot
 
 		public void Login()
 		{
-			try
-			{
-				this.loginClient.Login(
-					this.LoginIP, this.LoginPort, this.Account, this.Password);
-			}
-			catch (Exception e)
-			{
-				Logger.Trace("realm exception: {0}, {1}", e.Message, e.StackTrace);
-			}
+			this.loginClient.Login(
+				this.LoginIP, this.LoginPort, this.Account, this.Password);
 		}
 
 		public void SendCommand()

+ 14 - 0
CSharp/Platform/ENet/ENetException.cs

@@ -1,11 +1,25 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace ENet
 {
+	[Serializable]
 	public class ENetException: Exception
 	{
+		public ENetException()
+		{
+		}
+
 		public ENetException(string message): base(message)
 		{
 		}
+
+		public ENetException(string message, Exception inner): base(message, inner)
+		{
+		}
+
+		protected ENetException(SerializationInfo info, StreamingContext context)
+		{
+		}
 	}
 }