Remove NAPS2.Escl.Server as a dep from NAPS2.Sdk

Now it is optional for sdk usage, ensuring that transitive dependencies aren't installed unnecessarily.
This commit is contained in:
Ben Olden-Cooligan 2023-11-27 20:17:03 -08:00
parent 0ed7efd4ae
commit 2041107625
11 changed files with 58 additions and 43 deletions

View File

@ -3,17 +3,12 @@ using EmbedIO.WebApi;
namespace NAPS2.Escl.Server;
public class EsclServer : IDisposable
public class EsclServer : IEsclServer
{
private readonly CancellationTokenSource _cts = new();
private readonly MdnsAdvertiser _advertiser;
private readonly Dictionary<EsclDeviceConfig, CancellationTokenSource> _devices = new();
private bool _started;
public EsclServer()
{
_advertiser = new MdnsAdvertiser();
}
private CancellationTokenSource? _cts;
private MdnsAdvertiser? _advertiser;
public void AddDevice(EsclDeviceConfig deviceConfig)
{
@ -21,18 +16,23 @@ public class EsclServer : IDisposable
{
deviceConfig.Port = Port++;
}
Task.Run(() => _advertiser.AdvertiseDevice(deviceConfig));
_devices[deviceConfig] = new CancellationTokenSource();
if (_started)
{
StartServer(deviceConfig);
var advertiser = _advertiser!;
Task.Run(() => advertiser.AdvertiseDevice(deviceConfig));
}
}
public void RemoveDevice(EsclDeviceConfig deviceConfig)
{
// TODO: Maybe enforce ordering to ensure we don't unadvertise before advertising?
Task.Run(() => _advertiser.UnadvertiseDevice(deviceConfig));
if (_started)
{
// TODO: Maybe enforce ordering to ensure we don't unadvertise before advertising?
var advertiser = _advertiser!;
Task.Run(() => advertiser.UnadvertiseDevice(deviceConfig));
}
_devices[deviceConfig].Cancel();
_devices.Remove(deviceConfig);
}
@ -47,10 +47,13 @@ public class EsclServer : IDisposable
throw new InvalidOperationException();
}
_started = true;
_cts = new CancellationTokenSource();
_advertiser = new MdnsAdvertiser();
foreach (var device in _devices.Keys)
{
StartServer(device);
Task.Run(() => _advertiser!.AdvertiseDevice(device));
}
}
@ -64,7 +67,21 @@ public class EsclServer : IDisposable
.WithUrlPrefix(url))
.WithWebApi("/eSCL", m => m.WithController(() => new EsclApiController(deviceConfig, serverState)));
server.StateChanged += ServerOnStateChanged;
server.RunAsync(CancellationTokenSource.CreateLinkedTokenSource(_cts.Token, _devices[deviceConfig].Token).Token);
server.RunAsync(CancellationTokenSource.CreateLinkedTokenSource(_cts!.Token, _devices[deviceConfig].Token).Token);
}
public void Stop()
{
if (!_started)
{
throw new InvalidOperationException();
}
_started = false;
_cts!.Cancel();
_advertiser!.Dispose();
_cts = null;
_advertiser = null;
}
private void ServerOnStateChanged(object sender, WebServerStateChangedEventArgs e)
@ -73,7 +90,9 @@ public class EsclServer : IDisposable
public void Dispose()
{
_cts.Cancel();
_advertiser.Dispose();
if (_started)
{
Stop();
}
}
}

View File

@ -28,7 +28,7 @@ internal static class CapabilitiesParser
var adfDuplexCapsEl = root.Element(ScanNs + "Adf")?.Element(ScanNs + "AdfDuplexInputCaps");
return new EsclCapabilities
{
Version = root.Element(PwgNs + "Version")?.Value,
Version = root.Element(PwgNs + "Version")?.Value ?? EsclCapabilities.DEFAULT_VERSION,
MakeAndModel = root.Element(PwgNs + "MakeAndModel")?.Value,
SerialNumber = root.Element(PwgNs + "SerialNumber")?.Value,
Uuid = root.Element(ScanNs + "UUID")?.Value,

View File

@ -2,7 +2,9 @@ namespace NAPS2.Escl;
public class EsclCapabilities
{
public string Version { get; init; } = "2.6";
public const string DEFAULT_VERSION = "2.6";
public string Version { get; init; } = DEFAULT_VERSION;
public string? MakeAndModel { get; init; }
public string? SerialNumber { get; init; }
public string? Uuid { get; init; }

View File

@ -0,0 +1,10 @@
namespace NAPS2.Escl.Server;
public interface IEsclServer : IDisposable
{
void AddDevice(EsclDeviceConfig deviceConfig);
void RemoveDevice(EsclDeviceConfig deviceConfig);
int Port { get; set; }
void Start();
void Stop();
}

View File

@ -30,6 +30,7 @@
<ItemGroup>
<ProjectReference Include="..\NAPS2.Sdk\NAPS2.Sdk.csproj" />
<ProjectReference Include="..\NAPS2.Escl.Server\NAPS2.Escl.Server.csproj" />
<PackageReference Include="Autofac" Version="7.1.0" />
<PackageReference Include="Ben.Demystifier" Version="0.4.1" />
<PackageReference Include="CommandLineParser" Version="2.9.1" />

View File

@ -1,3 +1,4 @@
using NAPS2.Escl.Server;
using NAPS2.Scan;
namespace NAPS2.Remoting.Server;
@ -10,7 +11,7 @@ public class SharedDeviceManager : ISharedDeviceManager
public SharedDeviceManager(ScanningContext scanningContext, Naps2Config config)
{
_config = config;
_server = new ScanServer(scanningContext);
_server = new ScanServer(scanningContext, new EsclServer());
_server.SetDefaultIcon(Icons.scanner_128);
RegisterDevicesFromConfig();
}

View File

@ -86,7 +86,6 @@
<ItemGroup>
<ProjectReference Include="..\NAPS2.Escl\NAPS2.Escl.csproj" />
<ProjectReference Include="..\NAPS2.Escl.Server\NAPS2.Escl.Server.csproj" />
<ProjectReference Include="..\NAPS2.Images.Mac\NAPS2.Images.Mac.csproj" Condition="'$(TargetFramework)' == 'net8-macos10.15'" />
<ProjectReference Include="..\NAPS2.Images\NAPS2.Images.csproj" />
<ProjectReference Include="..\NAPS2.Internals\NAPS2.Internals.csproj" />

View File

@ -8,12 +8,13 @@ public class ScanServer : IDisposable
{
private readonly ScanningContext _scanningContext;
private readonly Dictionary<(Driver, string), EsclDeviceConfig> _currentDevices = new();
private EsclServer? _esclServer;
private readonly IEsclServer _esclServer;
private byte[]? _defaultIconPng;
public ScanServer(ScanningContext scanningContext)
public ScanServer(ScanningContext scanningContext, IEsclServer esclServer)
{
_scanningContext = scanningContext;
_esclServer = esclServer;
ScanController = new ScanController(scanningContext);
}
@ -29,7 +30,7 @@ public class ScanServer : IDisposable
var key = (device.Driver, device.Device.ID);
var esclDeviceConfig = MakeEsclDeviceConfig(device);
_currentDevices.Add(key, esclDeviceConfig);
_esclServer?.AddDevice(esclDeviceConfig);
_esclServer.AddDevice(esclDeviceConfig);
}
public void UnregisterDevice(SharedDevice device)
@ -37,7 +38,7 @@ public class ScanServer : IDisposable
var key = (device.Driver, device.Device.ID);
var esclDeviceConfig = _currentDevices[key];
_currentDevices.Remove(key);
_esclServer?.RemoveDevice(esclDeviceConfig);
_esclServer.RemoveDevice(esclDeviceConfig);
}
private EsclDeviceConfig MakeEsclDeviceConfig(SharedDevice device)
@ -69,27 +70,9 @@ public class ScanServer : IDisposable
};
}
public void Start()
{
if (_esclServer != null) throw new InvalidOperationException("Already started");
_esclServer = new EsclServer();
foreach (var device in _currentDevices.Values)
{
_esclServer.AddDevice(device);
}
_esclServer.Start();
}
public void Start() => _esclServer.Start();
public void Stop()
{
if (_esclServer == null) throw new InvalidOperationException("Not started");
_esclServer.Dispose();
_esclServer = null;
}
public void Stop() => _esclServer.Stop();
public void Dispose()
{
_esclServer?.Dispose();
_esclServer = null;
}
public void Dispose() => _esclServer.Dispose();
}