Files
laatzen/Common/SIRTBroadcaster.Client/SIRTBroadcasterClient.cs
T
2023-08-22 14:58:05 +02:00

181 lines
5.6 KiB
C#

namespace SIRTBroadcaster.Client
{
using SIRTBroadcaster.Abstraction;
using Microsoft.AspNet.SignalR.Client;
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
public interface ISIRTBroadcasterSignalRClient : ISIRTBroadcasterClient
{
bool TryGetPayload(string sirtId, uint address, out Payload payload);
}
/// <summary>
/// Implements a SignalR client connection.
/// </summary>
public class SIRTBroadcasterClient : ISIRTBroadcaster, ISIRTBroadcasterSignalRClient
{
/// <summary>
/// TODO: Add description ...
/// </summary>
private readonly ConcurrentDictionary<string, ConcurrentDictionary<uint, Payload>> payloads;
/// <summary>
/// TODO: Add description ...
/// </summary>
private readonly ICollection<IDisposable> disposables;
/// <summary>
/// TODO: Add description ...
/// </summary>
private readonly HubConnection hubConnection;
/// <summary>
/// TODO: Add description ...
/// </summary>
private readonly IHubProxy hubProxy;
/// <summary>
/// TODO: Add description ...
/// </summary>
private bool hubConnected;
/// <summary>
/// TODO: Add description ...
/// </summary>
public SIRTBroadcasterClient(params string[] sirts)
{
this.payloads = new ConcurrentDictionary<string, ConcurrentDictionary<uint, Payload>>
(collection: sirts.ToDictionary(x => x, _ => new ConcurrentDictionary<uint, Payload>()));
this.hubConnection = new HubConnection(SIRTFixed.SIRT_URL);
this.hubProxy = this.hubConnection.CreateHubProxy(SIRTFixed.SIRT_HUB);
this.disposables = new List<IDisposable>();
this.ConfigureHubConnection();
}
public event Action<UInt32> UnitDetected;
/// <summary>
/// Disposes all disposables in this instance and clears all collections.
/// </summary>
public void Dispose()
{
try
{
foreach (var disposable in this.disposables)
{
disposable?.Dispose();
}
this.disposables.Clear();
this.hubConnection.Dispose();
}
catch (Exception)
{
// TODO: Exception logging.
}
}
/// <summary>
/// Receives messages from the SignalR hub connection.
/// Under different checks the received messages are added to the payloads collection.
/// Afterword is the <see cref="UnitDetected"/> event triggered if received message is a BUP.
/// </summary>
/// <param name="message"> - received <see cref="SIRTMessage"/>.</param>
public void MessageReceived(SIRTMessage message)
{
if (message is null)
{
return;
}
var sirtId = message.SirtId;
var address = message.Address;
var payload = this.payloads
.GetOrAdd(sirtId, new ConcurrentDictionary<uint, Payload>())
.GetOrAdd(address, new Payload(sirtId, address));
if (message.MessageType == SIRTFixed.FromAir)
{
var length = message.DataLength;
if (length == 13)
{
payload.AddBUP(message);
this.UnitDetected?.Invoke(address);
}
else if (length >= 51 && 53 <= length)
{
payload.AddDEBUG(message);
}
else if (length >= 91 && 93 <= length)
{
payload.AddSEMI(message);
}
else
{
// TODO: Do smething !?.
}
}
else if (message.MessageType == SIRTFixed.LastCMD)
{
}
else if (message.MessageType == SIRTFixed.Debug)
{
}
}
/// <summary>
/// Sends the message to the hub.
/// </summary>
/// <param name="message"></param>
public void SendMessage(SIRTMessage message)
{
if (this.hubConnected)
{
this.hubProxy.Invoke(nameof(ISIRTBroadcaster.SendMessage), message);
}
}
public bool TryGetPayload(string sirtId, uint address, out Payload payload)
{
payload = payload = this.payloads
.GetOrAdd(sirtId, new ConcurrentDictionary<uint, Payload>())
.GetOrAdd(address, new Payload(sirtId, address));
return payload != null;
}
/// <summary>
/// TODO: Add description ...
/// </summary>
private void ConfigureHubConnection()
{
this.disposables.Add(this.hubProxy.On<SIRTMessage>(nameof(ISIRTBroadcaster.MessageReceived), this.MessageReceived));
this.hubConnection.StateChanged += (args) =>
{
this.hubConnected = args.NewState == ConnectionState.Connected;
};
try
{
this.hubConnection
.Start()
.ConfigureAwait(true)
.GetAwaiter()
.GetResult();
}
catch (Exception)
{
// TODO: exception logging.
}
}
}
}