120 lines
3.0 KiB
C#
120 lines
3.0 KiB
C#
using System;
|
|
using System.Security.Cryptography;
|
|
using System.Threading;
|
|
|
|
namespace TrajectoryPlanningVisualization;
|
|
|
|
public sealed class PlanningVisualizationSessionInfo
|
|
{
|
|
public PlanningVisualizationSessionInfo(Uri uri, string token)
|
|
{
|
|
Uri = uri ?? throw new ArgumentNullException(nameof(uri));
|
|
Token = token ?? throw new ArgumentNullException(nameof(token));
|
|
}
|
|
|
|
public Uri Uri { get; }
|
|
public string Token { get; }
|
|
}
|
|
|
|
public sealed class PlanningVisualizationSession : IDisposable
|
|
{
|
|
private readonly object lifecycleLock = new object();
|
|
private readonly PlanningVisualizationOptions options;
|
|
private LoopbackVisualizationServer server;
|
|
private PlanningVisualizationSessionInfo sessionInfo;
|
|
|
|
public PlanningVisualizationSession(PlanningVisualizationOptions options)
|
|
{
|
|
this.options = options ?? throw new ArgumentNullException(nameof(options));
|
|
}
|
|
|
|
public bool IsRunning
|
|
{
|
|
get
|
|
{
|
|
lock (lifecycleLock)
|
|
{
|
|
return server != null && server.IsRunning;
|
|
}
|
|
}
|
|
}
|
|
|
|
public PlanningVisualizationSessionInfo Start(PlanningVisualizationStaticSnapshot staticSnapshot)
|
|
{
|
|
if (staticSnapshot == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(staticSnapshot));
|
|
}
|
|
|
|
lock (lifecycleLock)
|
|
{
|
|
if (server != null)
|
|
{
|
|
return sessionInfo;
|
|
}
|
|
|
|
PlanningVisualizationOptionsSnapshot validated = options.CreateValidatedSnapshot();
|
|
string token = CreateToken();
|
|
var created = new LoopbackVisualizationServer(validated, staticSnapshot, token);
|
|
try
|
|
{
|
|
created.Start();
|
|
server = created;
|
|
sessionInfo = new PlanningVisualizationSessionInfo(
|
|
new Uri("http://127.0.0.1:" + created.Port + "/?token=" + token), token);
|
|
return sessionInfo;
|
|
}
|
|
catch
|
|
{
|
|
created.Dispose();
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Publish(PlanningVisualizationDynamicSnapshot snapshot)
|
|
{
|
|
if (snapshot == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(snapshot));
|
|
}
|
|
|
|
try
|
|
{
|
|
Volatile.Read(ref server)?.Publish(snapshot);
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
LoopbackVisualizationServer current;
|
|
lock (lifecycleLock)
|
|
{
|
|
current = server;
|
|
server = null;
|
|
sessionInfo = null;
|
|
}
|
|
|
|
current?.Dispose();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Stop();
|
|
}
|
|
|
|
private static string CreateToken()
|
|
{
|
|
byte[] tokenBytes = new byte[32];
|
|
using (RandomNumberGenerator random = RandomNumberGenerator.Create())
|
|
{
|
|
random.GetBytes(tokenBytes);
|
|
}
|
|
|
|
return BitConverter.ToString(tokenBytes).Replace("-", string.Empty).ToLowerInvariant();
|
|
}
|
|
}
|