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

@ -11,6 +11,7 @@ using Borepin.Page.AddServerProcess;
using Borepin.PageModel.AddServerProcess; using Borepin.PageModel.AddServerProcess;
using System; using System;
using Borepin.Service.Storage; using Borepin.Service.Storage;
using NLog;
namespace Borepin namespace Borepin
{ {
@ -18,7 +19,10 @@ namespace Borepin
{ {
public App(IPlatformInitializer platformInitializer) : base(platformInitializer) public App(IPlatformInitializer platformInitializer) : base(platformInitializer)
{ {
var config = new NLog.Config.LoggingConfiguration();
var logconsole = new NLog.Targets.ConsoleTarget("logconsole");
config.AddRule(LogLevel.Trace, LogLevel.Fatal, logconsole);
LogManager.Configuration = config;
} }
protected override async void OnInitialized() protected override async void OnInitialized()

View File

@ -26,18 +26,29 @@ namespace Borepin.Base
#endregion #endregion
#region Methods #region Methods
public void OnConnectionStatusChanged(object sender, ConnectionStatusChange args) public async void OnConnectionStatusChanged(object sender, ConnectionStatusChange args)
{ {
switch(args) switch(args)
{ {
case ConnectionStatusChange.Connected: case ConnectionStatusChange.Connected:
IsConnected = true; IsConnected = true;
LoadAPIData(); await LoadAPIData().ConfigureAwait(false);
break; break;
case ConnectionStatusChange.Reconnected: case ConnectionStatusChange.Reconnected:
ReloadAPIData(); await ReloadAPIData().ConfigureAwait(false);
break; break;
case ConnectionStatusChange.ConnectionLoss: case ConnectionStatusChange.ConnectionLoss:
try
{
await _API.Reconnect().ConfigureAwait(false);
}
catch
{
IsConnected = false;
await _API.Disconnect().ConfigureAwait(false);
_API.UnbindAllEvents();
}
break;
case ConnectionStatusChange.Disconnected: case ConnectionStatusChange.Disconnected:
IsConnected = false; IsConnected = false;
break; break;

View File

@ -8,6 +8,7 @@ using System;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using Xamarin.Forms;
namespace Borepin.PageModel.AddServerProcess namespace Borepin.PageModel.AddServerProcess
{ {
@ -98,7 +99,7 @@ namespace Borepin.PageModel.AddServerProcess
try try
{ {
API api = new API(); API api = new API();
await api.TestConnection(_ConnectionData).ConfigureAwait(true); await api.TestConnection(_ConnectionData).ConfigureAwait(false);
} }
catch(ConnectingFailedException) catch(ConnectingFailedException)
{ {
@ -108,11 +109,14 @@ namespace Borepin.PageModel.AddServerProcess
return; return;
} }
INavigationResult result = await _NavigationService.NavigateAsync("AddServerProcess_ChooseAuthTypePage").ConfigureAwait(false); Device.BeginInvokeOnMainThread(async () =>
if (result.Exception != null)
{ {
Log.Fatal(result.Exception, "Navigating failed"); INavigationResult result = await _NavigationService.NavigateAsync("AddServerProcess_ChooseAuthTypePage").ConfigureAwait(false);
} if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
} }
private ICommand _ScanCodeCommand; private ICommand _ScanCodeCommand;

View File

@ -12,6 +12,7 @@ using System;
using NaturalSort.Extension; using NaturalSort.Extension;
using System.Linq; using System.Linq;
using Borepin.Service; using Borepin.Service;
using Xamarin.Forms;
namespace Borepin.PageModel namespace Borepin.PageModel
{ {
@ -101,7 +102,7 @@ namespace Borepin.PageModel
get => _SelectInstanceCommand; get => _SelectInstanceCommand;
set => SetProperty(ref _SelectInstanceCommand, value); set => SetProperty(ref _SelectInstanceCommand, value);
} }
public async void SelectInstanceCommandExecute(object obj) public void SelectInstanceCommandExecute(object obj)
{ {
MachineListItemViewModel viewmodel = obj as MachineListItemViewModel; MachineListItemViewModel viewmodel = obj as MachineListItemViewModel;
@ -110,7 +111,14 @@ namespace Borepin.PageModel
{ "instance", viewmodel.Instance.Id }, { "instance", viewmodel.Instance.Id },
}; };
await _NavigationService.NavigateAsync($"MachinePage", parameters).ConfigureAwait(false); Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.NavigateAsync($"MachinePage", parameters).ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
} }
private ICommand _ScanCodeCommand; private ICommand _ScanCodeCommand;
@ -154,7 +162,7 @@ namespace Borepin.PageModel
#endregion #endregion
#region IPageLifecycleAware #region IPageLifecycleAware
public async void OnAppearing() public void OnAppearing()
{ {
if(_NextMachine != null) if(_NextMachine != null)
{ {
@ -164,8 +172,15 @@ namespace Borepin.PageModel
}; };
_NextMachine = null; _NextMachine = null;
await _NavigationService.NavigateAsync("MachinePage", parameters).ConfigureAwait(false); Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.NavigateAsync("MachinePage", parameters).ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
} }
} }

View File

@ -8,6 +8,8 @@ using Borepin.Model;
using Prism.Services; using Prism.Services;
using Borepin.Service; using Borepin.Service;
using Borepin.Base.Exceptions; using Borepin.Base.Exceptions;
using Capnp.Rpc;
using System;
namespace Borepin.PageModel namespace Borepin.PageModel
{ {
@ -74,10 +76,17 @@ namespace Borepin.PageModel
if(_API.IsConnected) if(_API.IsConnected)
{ {
Machine.IUseInterface useInterface = _Machine.Use; try
{
Machine.IUseInterface useInterface = _Machine.Use;
await useInterface.Use().ConfigureAwait(false); await useInterface.Use().ConfigureAwait(false);
await LoadAPIData().ConfigureAwait(false); await LoadAPIData().ConfigureAwait(false);
}
catch (RpcException exception) when (string.Equals(exception.Message, "RPC connection is broken. Task would never return.", StringComparison.Ordinal))
{
Log.Debug("RPC Connection Loss");
}
} }
IsBusy = false; IsBusy = false;
@ -96,10 +105,17 @@ namespace Borepin.PageModel
if (_API.IsConnected) if (_API.IsConnected)
{ {
Machine.IInUseInterface inUseInterface = _Machine.Inuse; try
{
Machine.IInUseInterface inUseInterface = _Machine.Inuse;
await inUseInterface.GiveBack().ConfigureAwait(false); await inUseInterface.GiveBack().ConfigureAwait(false);
await LoadAPIData().ConfigureAwait(false); await LoadAPIData().ConfigureAwait(false);
}
catch(RpcException exception) when(string.Equals(exception.Message, "RPC connection is broken. Task would never return.", StringComparison.Ordinal))
{
Log.Debug("RPC Connection Loss");
}
} }
IsBusy = false; IsBusy = false;

View File

@ -2,8 +2,8 @@
using Prism.Commands; using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
using Prism.Services; using Prism.Services;
using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using Xamarin.Forms;
namespace Borepin.PageModel.SetUpProcess namespace Borepin.PageModel.SetUpProcess
{ {
@ -23,9 +23,17 @@ namespace Borepin.PageModel.SetUpProcess
get => _NextCommand; get => _NextCommand;
set => SetProperty(ref _NextCommand, value); set => SetProperty(ref _NextCommand, value);
} }
public async void NextCommandCommandExecute(object obj) public void NextCommandCommandExecute(object obj)
{ {
await _NavigationService.NavigateAsync("AddServerProcess_SelectServerPage").ConfigureAwait(false); Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.NavigateAsync("AddServerProcess_SelectServerPage").ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
} }
#endregion #endregion
} }

View File

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

@ -1 +1 @@
Subproject commit 0176a503c8d0b0be66e0212e04200c8324e11fd9 Subproject commit 086bbc2497785d2cc63e9252df6f6d3ee7599579