using DigitalData.Auth.Abstractions; using Microsoft.AspNetCore.SignalR.Client; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace DigitalData.Auth.Client; public class AuthClient : IAuthClient, IAsyncDisposable { private readonly HubConnection _connection; private readonly Lazy> _lazyInitiator; private readonly ILogger? _logger; private readonly ClientParams _params; public AuthClient(IOptions paramsOptions, HubConnectionBuilder connectionBuilder, ILogger? 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(nameof(ReceiveKeyAsync), ReceiveKeyAsync); _logger = logger; _lazyInitiator = new(async () => { try { await _connection.StartAsync(); IsConnected = true; return true; } catch(Exception ex) { ConnectionError = ex; throw; } }); } public bool IsConnected { get; private set; } = false; public Exception? ConnectionError { get; private set; } public async Task StartAsync() => await _lazyInitiator.Value; public async Task TryStartAsync() { try { return await _lazyInitiator.Value; } catch { return false; } } public Task ReceiveKeyAsync(string name, string message) => Task.Run(() => _params.Events.OnMessageReceived(name, message, _logger)); public Task SendKeyAsync(string name, string message) => _connection.InvokeAsync(nameof(SendKeyAsync), name, message); public virtual async ValueTask DisposeAsync() { await _connection.StopAsync(); await _connection.DisposeAsync(); GC.SuppressFinalize(this); } }