Laservall_solidworks_inject/Server/Handlers/BomStreamHandler.cs

132 lines
4.5 KiB
C#
Raw Normal View History

using Laservall.Solidworks.Model;
using Laservall.Solidworks.Server.Dto;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Laservall.Solidworks.Server.Handlers
{
internal sealed class BomStreamHandler
{
private readonly IBomDataProvider _dataProvider;
private BomLoadResult _lastLoadResult;
public BomStreamHandler(IBomDataProvider dataProvider)
{
_dataProvider = dataProvider;
}
public BomLoadResult LastLoadResult => _lastLoadResult;
public async Task HandleStream(HttpListenerContext context, CancellationToken ct)
{
context.Response.ContentType = "text/event-stream; charset=utf-8";
context.Response.Headers.Set("Cache-Control", "no-cache");
context.Response.Headers.Set("Connection", "keep-alive");
context.Response.StatusCode = 200;
var stream = context.Response.OutputStream;
try
{
var progress = new Progress<BomLoadProgress>(async p =>
{
try
{
var evt = new ProgressEventDto
{
Processed = p.Processed,
Total = p.Total,
CurrentName = p.CurrentName
};
string json = JsonConvert.SerializeObject(evt);
await WriteSseEvent(stream, "progress", json, ct);
}
catch { }
});
var result = await _dataProvider.LoadBomAsync(progress, ct);
_lastLoadResult = result;
var response = new BomStreamResponse
{
Items = result.Items.Select(ToDto).ToList(),
DynamicKeys = result.DynamicKeys,
Settings = ToSettingsDto(result.Settings)
};
string completeJson = JsonConvert.SerializeObject(response);
await WriteSseEvent(stream, "complete", completeJson, ct);
}
catch (OperationCanceledException)
{
}
catch (Exception ex)
{
try
{
string errorJson = JsonConvert.SerializeObject(new { error = ex.Message });
await WriteSseEvent(stream, "error", errorJson, ct);
}
catch { }
}
finally
{
try { context.Response.Close(); } catch { }
}
}
private static async Task WriteSseEvent(System.IO.Stream stream, string eventType, string data, CancellationToken ct)
{
string message = $"event: {eventType}\ndata: {data}\n\n";
byte[] bytes = Encoding.UTF8.GetBytes(message);
await stream.WriteAsync(bytes, 0, bytes.Length, ct);
await stream.FlushAsync(ct);
}
private static BomItemDto ToDto(BomItemModel item)
{
return new BomItemDto
{
Level = item.Level,
LevelDisplay = item.LevelDisplay,
DrawingNo = item.DrawingNo,
ConfigName = item.ConfigName,
PartName = item.PartName,
MaterialProp = item.MaterialProp,
Material = item.Material,
Classification = item.Classification,
Quantity = item.Quantity,
IsAssembly = item.IsAssembly,
IsOutSourcing = item.IsOutSourcing,
DocPath = item.DocPath,
Props = item.Props ?? new Dictionary<string, string>(),
HasChildren = item.HasChildren,
NodeId = item.NodeId,
ParentNodeId = item.ParentNodeId
};
}
private static SettingsDto ToSettingsDto(BomSettings settings)
{
return new SettingsDto
{
Columns = settings.Columns.Select(c => new ColumnConfigDto
{
Name = c.Name,
IsVisible = c.IsVisible,
IsExport = c.IsExport,
IsFixed = c.IsFixed,
IsUserAdded = c.IsUserAdded
}).ToList(),
RemovedKeys = settings.RemovedKeys?.ToList() ?? new List<string>()
};
}
}
}