Files
Denso/srcs/RobotNet10/RobotApp/RobotNet10.RobotApp.Client/Clients/NavigationMonitorHubClient.cs
2026-07-03 16:31:37 +07:00

105 lines
3.6 KiB
C#

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.SignalR.Client;
using RobotNet10.RobotApp.Shared.NavigationMonitor;
namespace RobotNet10.RobotApp.Client.Clients;
public class NavigationMonitorHubClient : IAsyncDisposable
{
private readonly HubConnection _hubConnection;
private bool _disposed;
public bool IsConnected => _hubConnection.State == HubConnectionState.Connected;
public HubConnectionState ConnectionState => _hubConnection.State;
public event Action<NavigationTelemetryDto>? TelemetryReceived;
public event Action<NavigationSafetyViolationDto>? SafetyViolationReceived;
public event Action<NavigationMonitorStateDto>? MonitorStateChanged;
public event Action<HubConnectionState>? ConnectionStateChanged;
public NavigationMonitorHubClient(NavigationManager navigationManager)
{
var hubUrl = navigationManager.ToAbsoluteUri("/hubs/motion/navigation-monitor");
_hubConnection = new HubConnectionBuilder()
.WithUrl(hubUrl)
.WithAutomaticReconnect()
.Build();
_hubConnection.On<NavigationTelemetryDto>("ReceiveTelemetry", dto => TelemetryReceived?.Invoke(dto));
_hubConnection.On<NavigationSafetyViolationDto>("ReceiveSafetyViolation", dto => SafetyViolationReceived?.Invoke(dto));
_hubConnection.On<NavigationMonitorStateDto>("ReceiveMonitorState", dto => MonitorStateChanged?.Invoke(dto));
_hubConnection.Reconnecting += async (_) =>
{
ConnectionStateChanged?.Invoke(_hubConnection.State);
await Task.CompletedTask;
};
_hubConnection.Reconnected += async (_) =>
{
ConnectionStateChanged?.Invoke(_hubConnection.State);
// Re-subscribe after reconnect
await _hubConnection.InvokeAsync("Subscribe");
};
_hubConnection.Closed += async (_) =>
{
ConnectionStateChanged?.Invoke(_hubConnection.State);
await Task.CompletedTask;
};
}
public async Task StartAsync()
{
if (_hubConnection.State == HubConnectionState.Disconnected)
{
await _hubConnection.StartAsync();
ConnectionStateChanged?.Invoke(_hubConnection.State);
await _hubConnection.InvokeAsync("Subscribe");
}
}
public async Task StopAsync()
{
if (_hubConnection.State != HubConnectionState.Disconnected)
{
try { await _hubConnection.InvokeAsync("Unsubscribe"); } catch { }
await _hubConnection.StopAsync();
}
}
public async Task SetTelemetryEnabledAsync(bool enabled)
{
await _hubConnection.InvokeAsync("SetTelemetryEnabled", enabled);
}
public async Task SetSafetyStopEnabledAsync(bool enabled)
{
await _hubConnection.InvokeAsync("SetSafetyStopEnabled", enabled);
}
public async Task UpdateSafetyConfigAsync(NavigationSafetyConfigDto config)
{
await _hubConnection.InvokeAsync("UpdateSafetyConfig", config);
}
public async Task ReleaseSafetyStopAsync()
{
await _hubConnection.InvokeAsync("ReleaseSafetyStop");
}
public async Task<NavigationMonitorStateDto> GetStateAsync()
{
return await _hubConnection.InvokeAsync<NavigationMonitorStateDto>("GetState");
}
public async ValueTask DisposeAsync()
{
if (_disposed) return;
_disposed = true;
await StopAsync();
await _hubConnection.DisposeAsync();
}
}