Fixed Reconnection Problem

This commit is contained in:
TheJoKlLa
2022-05-19 17:47:49 +02:00
parent 14552bf929
commit 224891cadb
8 changed files with 131 additions and 68 deletions

View File

@ -9,6 +9,7 @@ using System.Linq;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
namespace FabAccessAPI
@ -22,6 +23,8 @@ namespace FabAccessAPI
#region Private Members
private TcpRpcClient _TcpRpcClient;
private IBootstrap _Bootstrap;
private static SemaphoreSlim _ConnectSemaphore = new SemaphoreSlim(1, 1);
private static SemaphoreSlim _ReconnectSemaphore = new SemaphoreSlim(1, 1);
#endregion
#region Constructors
@ -36,22 +39,10 @@ namespace FabAccessAPI
public void OnTcpRpcConnectionChanged(object sender, ConnectionStateChange args)
{
EventHandler<ConnectionStatusChange> eventHandler = ConnectionStatusChanged;
if (eventHandler == null)
{
return;
}
if (args.LastState == ConnectionState.Initializing && args.NewState == ConnectionState.Active)
{
Log.Trace("TcpRpcClient Event Connected");
eventHandler(this, ConnectionStatusChange.Connected);
}
if (args.LastState == ConnectionState.Active && args.NewState == ConnectionState.Down)
{
Log.Trace("TcpRpcClient Event ConnectionLoss");
eventHandler(this, ConnectionStatusChange.ConnectionLoss);
ConnectionStatusChanged?.Invoke(this, ConnectionStatusChange.ConnectionLoss);
_TcpRpcClient = null;
}
}
@ -92,39 +83,44 @@ namespace FabAccessAPI
/// <exception cref="ConnectingFailedException"></exception>
public async Task Connect(ConnectionData connectionData, TcpRpcClient tcpRpcClient = null)
{
if (IsConnected)
{
await Disconnect();
}
if(tcpRpcClient == null)
{
_TcpRpcClient = new TcpRpcClient();
}
else
{
_TcpRpcClient = tcpRpcClient;
}
await _ConnectSemaphore.WaitAsync();
try
{
_TcpRpcClient.ConnectionStateChanged += OnTcpRpcConnectionChanged;
if (IsConnected)
{
await Disconnect();
}
await _ConnectAsync(_TcpRpcClient, connectionData).ConfigureAwait(false);
_Bootstrap = _TcpRpcClient.GetMain<IBootstrap>();
ConnectionInfo = await _GetConnectionInfo(_Bootstrap);
if (tcpRpcClient == null)
{
tcpRpcClient = new TcpRpcClient();
}
Session = await _Authenticate(connectionData).ConfigureAwait(false);
ConnectionData = connectionData;
try
{
await _ConnectAsync(tcpRpcClient, connectionData).ConfigureAwait(false);
Log.Info("API connected");
_Bootstrap = tcpRpcClient.GetMain<IBootstrap>();
ConnectionInfo = await _GetConnectionInfo(_Bootstrap);
Session = await _Authenticate(connectionData).ConfigureAwait(false);
ConnectionData = connectionData;
_TcpRpcClient = tcpRpcClient;
tcpRpcClient.ConnectionStateChanged += OnTcpRpcConnectionChanged;
ConnectionStatusChanged?.Invoke(this, ConnectionStatusChange.Connected);
Log.Info("API connected");
}
catch (System.Exception ex)
{
await Disconnect().ConfigureAwait(false);
Log.Warn(ex, "API connecting failed");
throw ex;
}
}
catch(System.Exception ex)
finally
{
await Disconnect().ConfigureAwait(false);
Log.Warn(ex, "API connecting failed");
throw ex;
_ConnectSemaphore.Release();
}
}
@ -150,13 +146,22 @@ namespace FabAccessAPI
public async Task Reconnect()
{
if (ConnectionData != null)
await _ReconnectSemaphore.WaitAsync();
try
{
await Connect(ConnectionData);
}
if (ConnectionData != null && IsConnected == false)
{
await Connect(ConnectionData);
}
ConnectionStatusChanged?.Invoke(this, ConnectionStatusChange.Reconnected);
Log.Info("API reconnected");
ConnectionStatusChanged?.Invoke(this, ConnectionStatusChange.Reconnected);
Log.Info("API reconnected");
}
finally
{
_ReconnectSemaphore.Release();
}
}
public async Task<ConnectionInfo> TestConnection(ConnectionData connectionData, TcpRpcClient tcpRpcClient = null)