diff --git a/EpsonPrintService/EpsonPrintService.csproj b/EpsonPrintService/EpsonPrintService.csproj
index 520711e..8e69454 100644
--- a/EpsonPrintService/EpsonPrintService.csproj
+++ b/EpsonPrintService/EpsonPrintService.csproj
@@ -5,7 +5,7 @@
net8.0
enable
enable
- 1.0.10
+ 1.0.11
diff --git a/EpsonPrintService/PrinterDiscoveryBackgroundTask.cs b/EpsonPrintService/PrinterDiscoveryBackgroundTask.cs
index 50d8744..bed7624 100644
--- a/EpsonPrintService/PrinterDiscoveryBackgroundTask.cs
+++ b/EpsonPrintService/PrinterDiscoveryBackgroundTask.cs
@@ -16,9 +16,11 @@ public class PrinterDiscoveryBackgroundTask
private readonly PrintServer _printServer;
private readonly TimeSpan _interval;
private readonly TimeSpan _discoveryTimeout;
+ private readonly TimeSpan _retentionPeriod;
- private HashSet _lastDiscoveredPrinterIps = new();
- private List _lastDiscoveredPrinters = new();
+ private readonly Dictionary _lastSeenTimes = new();
+ private readonly Dictionary _knownPrinters = new();
+ private HashSet _lastEffectiveIps = new();
public PrinterDiscoveryBackgroundTask(
IDiscoveryService discoveryService,
@@ -32,6 +34,7 @@ public class PrinterDiscoveryBackgroundTask
_printServer = printServer;
_interval = TimeSpan.FromSeconds(30);
_discoveryTimeout = TimeSpan.FromSeconds(3);
+ _retentionPeriod = TimeSpan.FromMinutes(2);
}
///
@@ -69,21 +72,11 @@ public class PrinterDiscoveryBackgroundTask
private async Task DiscoverAndNotifyAsync()
{
List printers;
- HashSet currentIps;
- bool configChanged;
await _printServer.EnterDiscoveryLockAsync();
try
{
printers = await _discoveryService.DiscoverPrintersAsync(_discoveryTimeout);
- currentIps = printers.Select(p => p.IPAddress).ToHashSet();
- configChanged = HasConfigurationChanged(currentIps);
-
- if (configChanged)
- {
- _lastDiscoveredPrinterIps = currentIps;
- _lastDiscoveredPrinters = printers;
- }
}
catch (Exception ex)
{
@@ -95,25 +88,59 @@ public class PrinterDiscoveryBackgroundTask
_printServer.ExitDiscoveryLock();
}
- // Register printers AFTER releasing the lock
- foreach (string currentIp in currentIps)
+ // Update last seen times for discovered printers
+ DateTime now = DateTime.UtcNow;
+ foreach (DiscoveredPrinter printer in printers)
{
- _logger.LogDebug("Registering discovered printer with IP: {IP}", currentIp);
- _printServer.RegisterPrinter(currentIp);
+ _lastSeenTimes[printer.IPAddress] = now;
+ _knownPrinters[printer.IPAddress] = printer;
+ }
+
+ // Remove printers not seen within the retention period
+ List expiredIps = _lastSeenTimes
+ .Where(kvp => now - kvp.Value > _retentionPeriod)
+ .Select(kvp => kvp.Key)
+ .ToList();
+
+ foreach (string expiredIp in expiredIps)
+ {
+ _logger.LogInformation("Printer {IP} not seen for over {Retention}s, removing", expiredIp, _retentionPeriod.TotalSeconds);
+ _lastSeenTimes.Remove(expiredIp);
+ _knownPrinters.Remove(expiredIp);
+ }
+
+ // Compute effective set and detect changes
+ HashSet effectiveIps = _lastSeenTimes.Keys.ToHashSet();
+ bool configChanged = HasConfigurationChanged(effectiveIps);
+
+ // Register newly appeared printers
+ foreach (string ip in effectiveIps.Except(_lastEffectiveIps))
+ {
+ _logger.LogDebug("Registering discovered printer with IP: {IP}", ip);
+ _printServer.RegisterPrinter(ip);
+ }
+
+ // Unregister expired printers
+ foreach (string ip in _lastEffectiveIps.Except(effectiveIps))
+ {
+ _logger.LogDebug("Unregistering expired printer with IP: {IP}", ip);
+ _printServer.UnregisterPrinter(ip);
}
if (configChanged)
{
- _logger.LogInformation("Discovered printer configuration changed: {Count} printer(s)", printers.Count);
- await _receiver.OnPrintersDiscoveredAsync(printers.AsReadOnly());
+ _lastEffectiveIps = effectiveIps;
+ List effectivePrinters = _knownPrinters.Values.ToList();
+ _logger.LogInformation("Discovered printer configuration changed: {Count} printer(s)", effectivePrinters.Count);
+ await _receiver.OnPrintersDiscoveredAsync(effectivePrinters.AsReadOnly());
}
}
- private bool HasConfigurationChanged(HashSet currentIps)
+ private bool HasConfigurationChanged(HashSet effectiveIps)
{
- if (currentIps.Count != _lastDiscoveredPrinterIps.Count)
+ if (effectiveIps.Count != _lastEffectiveIps.Count)
return true;
- return !currentIps.SetEquals(_lastDiscoveredPrinterIps);
+ return !effectiveIps.SetEquals(_lastEffectiveIps);
}
}