using RobotNet10.RobotApp.Hubs; namespace RobotNet10.RobotApp.Services; /// /// Broadcast odometry tới SignalR clients định kỳ (mặc định 10 Hz) để hiển thị realtime /// public class OdometryBroadcastService : IHostedService, IDisposable { private readonly OdometryHubContext _odometryHubContext; private readonly ILogger _logger; private Timer? _timer; private const int BroadcastIntervalMs = 100; // 10 Hz public OdometryBroadcastService(OdometryHubContext odometryHubContext, ILogger logger) { _odometryHubContext = odometryHubContext; _logger = logger; } public Task StartAsync(CancellationToken cancellationToken) { _timer = new Timer( async _ => { try { await _odometryHubContext.BroadcastOdometryAsync(); } catch (Exception ex) { _logger.LogDebug(ex, "Odometry broadcast skipped"); } }, null, TimeSpan.FromMilliseconds(BroadcastIntervalMs), TimeSpan.FromMilliseconds(BroadcastIntervalMs)); _logger.LogInformation("Odometry broadcast started at {Hz} Hz", 1000.0 / BroadcastIntervalMs); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { _timer?.Change(Timeout.Infinite, 0); _logger.LogInformation("Odometry broadcast stopped"); return Task.CompletedTask; } public void Dispose() { _timer?.Dispose(); GC.SuppressFinalize(this); } }