/// <summary> /// Raises the <see cref="ConnectionAttemptFailed"/> event. /// </summary> protected virtual void OnConnectionAttemptFailed(ConnectionAttemptFailedEventArgs e) { ConnectionAttemptFailed(this, e); }
/// <summary> /// Try to connect, according to the set <see cref="MaxConnectionAttempts"/>, asynchronously. /// </summary> /// <exception cref="InvalidOperationException"></exception> /// <exception cref="AlreadyLoggedInException"></exception> public void RequestLogin() { // Already requesting. if (Status == ClientStatus.Connected || Status == ClientStatus.Connecting) { return; } if (EndPoint == null) { throw new InvalidOperationException($@"The property ""{EndPoint}"" cannot be null."); } if (Status == ClientStatus.LoggedIn) { throw new AlreadyLoggedInException( $@"""{Name}"" is already logged in. You must logout this client before logging in again.", null); } Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); abortConnectionPending = false; connectionAttempts = 0; ReceiveSendGuard = false; Status = ClientStatus.Connecting; Task.Run(() => { while (Socket != null && !Socket.Connected && !abortConnectionPending) { try { Socket.Connect(EndPoint); Status = ClientStatus.Connected; StartReceiving(); // Ask to login. SendPackageAsyncBase((int)BaseCommand.Login, new LoginContent(Name)); return; } catch (SocketException) { connectionAttempts++; var args = new ConnectionAttemptFailedEventArgs( connectionAttempts, MaxConnectionAttempts > 0 && connectionAttempts > MaxConnectionAttempts, abortConnectionPending); UiContext.Default.Invoke(delegate { if (args.EndOfAttempts) { Status = ClientStatus.Disconnected; } OnConnectionAttemptFailed(args); }); if (args.EndOfAttempts) { break; } } } }); }