121 lines
3.6 KiB
C#
121 lines
3.6 KiB
C#
using Hi.Disp;
|
||
using Hi.Geom;
|
||
using Microsoft.AspNetCore.SignalR;
|
||
using Hi.Webapi.Hubs;
|
||
using System.Collections.Concurrent;
|
||
|
||
namespace Hi.Webapi.Services
|
||
{
|
||
/// <summary>
|
||
/// Singleton Service for managing <see cref="DispEngine"/>.
|
||
/// </summary>
|
||
public class RenderingService : IDisposable
|
||
{
|
||
/// <summary>
|
||
/// Engine Dictionary.
|
||
/// Key is sessionID.
|
||
/// </summary>
|
||
public ConcurrentDictionary<string, DispEngine> EngineDictionary { get; } = new();
|
||
ILogger<RenderingService> Logger { get; }
|
||
IHubContext<RenderingHub> HubContext { get; }
|
||
private bool disposedValue;
|
||
|
||
public RenderingService(ILogger<RenderingService> logger, IHubContext<RenderingHub> hubContext)
|
||
{
|
||
Logger = logger;
|
||
HubContext = hubContext;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get Or Create an DispEngine.
|
||
/// </summary>
|
||
public DispEngine GetOrCreateEngine(string connectionId)
|
||
{
|
||
return EngineDictionary.GetOrAdd(connectionId, id =>
|
||
{
|
||
Logger.LogInformation($"Create new DispEngine,ConnectionId: {id}");
|
||
var engine = new DispEngine();
|
||
engine.BackgroundColor = new Vec3d(0.1, 0.1, 0.5);
|
||
engine.BackgroundOpacity = 0.1;
|
||
return engine;
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// Send image to specific client.
|
||
/// </summary>
|
||
public async Task SendImageToClient(string connectionId, byte[] compressedData, int originalLength, int width, int height)
|
||
{
|
||
try
|
||
{
|
||
await HubContext.Clients.Client(connectionId).SendAsync("ImageUpdate",
|
||
compressedData, originalLength, width, height);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.LogError(ex, $"Failed to send image to client: {connectionId}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Remove DispEngine
|
||
/// </summary>
|
||
public bool RemoveEngine(string connectionId)
|
||
{
|
||
if (EngineDictionary.TryRemove(connectionId, out var engine))
|
||
{
|
||
Logger.LogInformation($"Remove DispEngine,ConnectionId: {connectionId}");
|
||
|
||
try
|
||
{
|
||
engine.IsVisible = false;
|
||
engine.Dispose();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.LogError(ex, $"清理 DispEngine 時發生錯誤,ConnectionId: {connectionId}");
|
||
}
|
||
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get Active Engine Count.
|
||
/// </summary>
|
||
public int GetActiveEngineCount() => EngineDictionary.Count;
|
||
/// <inheritdoc/>
|
||
protected virtual void Dispose(bool disposing)
|
||
{
|
||
if (!disposedValue)
|
||
{
|
||
if (disposing)
|
||
{
|
||
foreach (var kvp in EngineDictionary)
|
||
{
|
||
try
|
||
{
|
||
kvp.Value.IsVisible = false;
|
||
kvp.Value.Dispose();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.LogError(ex, $"Dispose DispEngine Error,ConnectionId: {kvp.Key}");
|
||
}
|
||
}
|
||
EngineDictionary.Clear();
|
||
}
|
||
|
||
disposedValue = true;
|
||
}
|
||
}
|
||
/// <inheritdoc/>
|
||
public void Dispose()
|
||
{
|
||
Dispose(disposing: true);
|
||
GC.SuppressFinalize(this);
|
||
}
|
||
|
||
}
|
||
} |