Developer 02 e194cd8054 feat: Implementierung der Wiederholungslogik für den Verbindungsaufbau in AuthClient
- Hinzugefügt: `TryStartConnectionAsync`-Methode zur Durchführung von Verbindungsversuchen mit Wiederholungslogik.
- `StartAsync` aktualisiert, um wiederholt zu versuchen, die Verbindung herzustellen, bis sie erfolgreich ist oder `RetryDelay` erschöpft ist.
2025-03-12 09:32:10 +01:00

85 lines
2.8 KiB
C#

using DigitalData.Auth.Abstractions;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace DigitalData.Auth.Client;
public class AuthClient : IAuthClient, IHostedService
{
private readonly HubConnection _connection;
private readonly ILogger<AuthClient>? _logger;
private readonly ClientParams _params;
public AuthClient(IOptions<ClientParams> paramsOptions, HubConnectionBuilder connectionBuilder, ILogger<AuthClient>? logger = null)
{
_params = paramsOptions.Value;
var cnnBuilder = connectionBuilder.WithUrl(_params.Url);
// set RetryPolicy if it exists
if (_params.RetryPolicy is not null)
cnnBuilder = cnnBuilder.WithAutomaticReconnect(_params.RetryPolicy);
_connection = cnnBuilder.Build();
_connection.On<string, string, string>(nameof(ReceivePublicKeyAsync), ReceivePublicKeyAsync);
_connection.Reconnected += async cnnId => await GetAllPublicKeysAsync();
_logger = logger;
}
public bool IsConnected { get; private set; } = false;
public IEnumerable<ClientPublicKey> PublicKeys => _params.PublicKeys;
public async Task StartAsync(CancellationToken cancellationToken = default)
{
while(!await TryStartConnectionAsync(cancellationToken))
{
if (_params.RetryDelay is not null)
await Task.Delay(_params.RetryDelay.Value.Milliseconds, cancellationToken);
else
return;
}
IsConnected = true;
await GetAllPublicKeysAsync();
}
private async Task<bool> TryStartConnectionAsync(CancellationToken cancellationToken = default)
{
try
{
await _connection.StartAsync(cancellationToken);
return true;
}
catch(HttpRequestException ex)
{
_logger?.LogError(ex, "Connection is failed. {message}", ex.Message);
return false;
}
}
public async Task StopAsync(CancellationToken cancellationToken)
{
await _connection.StopAsync(cancellationToken);
IsConnected = false;
}
public Task ReceivePublicKeyAsync(string issuer, string audience, string message) => Task.Run(() => _params.TriggerOnPublicReceivedEvent(this, issuer, audience, message, _logger));
public Task SendPublicKeyAsync(string issuer, string audience, string message) => _connection.InvokeAsync(nameof(SendPublicKeyAsync), issuer, audience, message);
public Task GetPublicKeyAsync(string issuer, string audience) => _connection.InvokeAsync(nameof(GetPublicKeyAsync), issuer, audience);
public async Task GetAllPublicKeysAsync()
{
foreach (var publicKey in PublicKeys)
await GetPublicKeyAsync(publicKey.Issuer, publicKey.Audience);
}
}