Hi.Webapi/Services/RenderingService.cs

121 lines
3.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 DispEngineConnectionId: {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 DispEngineConnectionId: {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 ErrorConnectionId: {kvp.Key}");
}
}
EngineDictionary.Clear();
}
disposedValue = true;
}
}
/// <inheritdoc/>
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}