using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.SignalR.Client; using RobotNet10.RobotApp.Client.Shared.Devices; namespace RobotNet10.RobotApp.Client.Clients; public class RfHandleHubClient : IAsyncDisposable { private readonly HubConnection _hubConnection; private bool _disposed; public bool IsConnected => _hubConnection.State == HubConnectionState.Connected; public HubConnectionState ConnectionState => _hubConnection.State; public RfHandleHubClient(NavigationManager navigationManager) { var hubUrl = navigationManager.ToAbsoluteUri("/hubs/devices/rfhandle"); _hubConnection = new HubConnectionBuilder() .WithUrl(hubUrl) .WithAutomaticReconnect() .Build(); _hubConnection.Reconnecting += async (ex) => { // optionally notify UI await Task.CompletedTask; }; _hubConnection.Reconnected += async (id) => { // optionally notify UI await Task.CompletedTask; }; _hubConnection.Closed += async (ex) => { // optionally notify UI await Task.CompletedTask; }; } // CONNECT / DISCONNECT public async Task StartAsync() { if (_hubConnection.State == HubConnectionState.Disconnected) { await _hubConnection.StartAsync(); } } public async Task StopAsync() { if (_hubConnection.State != HubConnectionState.Disconnected) await _hubConnection.StopAsync(); } // SERVER CALLS (RPC) public async Task GetRfHandleDataAsync(string deviceId) { var result = await _hubConnection.InvokeAsync("GetRfHandleData", deviceId); return result ?? new RfHandleDataDto(); } public async Task GetDeviceInfoAsync(string deviceId) { return await _hubConnection.InvokeAsync("GetDeviceInfo", deviceId); } // DISPOSE public async ValueTask DisposeAsync() { if (_disposed) return; _disposed = true; try { // stop but don't throw await StopAsync(); await _hubConnection.DisposeAsync(); } catch { } GC.SuppressFinalize(this); } }