RobotNet/RobotNet.RobotManager/Services/Traffic/TrafficPublisher.cs
2025-10-15 15:15:53 +07:00

85 lines
3.0 KiB
C#

using Microsoft.AspNetCore.SignalR;
using RobotNet.RobotManager.Hubs;
using RobotNet.RobotShares.Dtos;
namespace RobotNet.RobotManager.Services.Traffic;
public class TrafficPublisher(TrafficManager TrafficManager, IHubContext<TrafficHub> TrafficHub, LoggerController<TrafficPublisher> Logger) : IHostedService
{
private const int intervalTime = 2000;
private WatchTimer<TrafficPublisher>? Timer;
public readonly Dictionary<Guid, string> TrafficMapActive = [];
public List<TrafficAgentDto> GetAgents(Guid MapId)
{
if (TrafficManager.TrafficMaps.TryGetValue(MapId, out TrafficMap? trafficMap))
{
List<TrafficAgentDto> agents = [];
List<TrafficNodeDto> lockedNodes = [];
foreach (var agent in trafficMap.Agents)
{
if (trafficMap.Locked.TryGetValue(agent.Key, out List<TrafficNodeDto>? locked) && locked is not null) lockedNodes = locked;
var trafficConflict = trafficMap.Conflicts.FirstOrDefault(c => c.AgentRequest.Robot.SerialNumber == agent.Key);
agents.Add(new()
{
RobotId = agent.Key,
State = agent.Value.State,
ReleaseNode = agent.Value.ReleaseNode,
Nodes = agent.Value.Nodes,
InNode = agent.Value.Nodes[agent.Value.InNodeIndex],
LockedNodes = lockedNodes,
SubNodes = agent.Value.SubNodes,
GiveWayNodes = agent.Value.GivewayNodes,
ConflictAgentId = trafficConflict is null ? "" : trafficConflict.AgentConflict.Robot.SerialNumber,
ConflictNode = trafficConflict?.NodeConflict,
});
}
foreach (var agent in trafficMap.Locked)
{
if (agents.Any(a => a.RobotId == agent.Key)) continue;
agents.Add(new()
{
RobotId = agent.Key,
LockedNodes = agent.Value,
});
}
return agents;
}
return [];
}
private void TimerHandler()
{
try
{
foreach (var mapActive in TrafficMapActive)
{
var agents = GetAgents(mapActive.Key);
if (agents.Count > 0)
{
var pub = Task.Run(async () => await TrafficHub.Clients.Client(mapActive.Value).SendAsync("TrafficAgentUpdated", agents));
pub.Wait();
}
}
}
catch (Exception ex)
{
Logger.Error($"Robot Publisher Error: {ex}");
}
}
public async Task StartAsync(CancellationToken cancellationToken)
{
Timer = new(intervalTime, TimerHandler, Logger);
Timer.Start();
await Task.Yield();
}
public Task StopAsync(CancellationToken cancellationToken)
{
Timer?.Dispose();
return Task.CompletedTask;
}
}