Files
Print_server/Inspectron.Epson/PrintServer/JobSources/HttpPollingPrintJobSource.cs
2026-02-05 09:31:38 +01:00

144 lines
4.4 KiB
C#

using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Channels;
using Inspectron.Epson.PrintServer.ConfigurationSources;
using Inspectron.Epson.Queue;
using Microsoft.Extensions.Logging;
namespace Inspectron.Epson.PrintServer.JobSources;
public class HttpPollingPrintJobSource : IPrintJobSource, IDisposable
{
private readonly EpsonPrintServiceConfiguration _groupConfiguration;
private readonly ILogger _logger;
private readonly HttpClient _httpClient;
private readonly Channel<PrintJob> _printJobChannel = Channel.CreateUnbounded<PrintJob>();
private readonly CancellationTokenSource _pollingCts = new();
private readonly TimeSpan _pollingInterval;
public HttpPollingPrintJobSource(
EpsonPrintServiceConfiguration groupConfiguration,
ILogger logger
)
{
_groupConfiguration = groupConfiguration;
_logger = logger;
_pollingInterval = TimeSpan.FromSeconds(3);
_httpClient = new HttpClient
{
BaseAddress = new Uri(groupConfiguration.ApiUrl?.TrimEnd('/') + "/")
};
_httpClient.DefaultRequestHeaders.Add("X-Printer-Server-Key", groupConfiguration.ApiKey);
}
private async Task StartPollingAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Starting HTTP polling for print jobs at {BaseUrl}", _httpClient.BaseAddress);
while (!cancellationToken.IsCancellationRequested)
{
try
{
await PollForJobsAsync(cancellationToken);
}
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
{
break;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error polling for print jobs. Retrying in {Interval}...", _pollingInterval);
}
try
{
await Task.Delay(_pollingInterval, cancellationToken);
}
catch (OperationCanceledException)
{
break;
}
}
_logger.LogInformation("HTTP polling stopped.");
}
private async Task PollForJobsAsync(CancellationToken cancellationToken)
{
var requestUrl = $"/api/printerServer/jobs";
var response = await _httpClient.GetAsync(requestUrl, cancellationToken);
if (!response.IsSuccessStatusCode)
{
_logger.LogWarning("Failed to fetch jobs. Status: {StatusCode}", response.StatusCode);
return;
}
var jobs = await response.Content.ReadFromJsonAsync<List<PrintJobDto>>(cancellationToken: cancellationToken);
if (jobs == null || jobs.Count == 0)
{
return;
}
_logger.LogInformation("Received {Count} print job(s) from HTTP endpoint.", jobs.Count);
foreach (var job in jobs)
{
_logger.LogInformation("Queuing print job: {PrintJob}", JsonSerializer.Serialize(job));
_printJobChannel.Writer.TryWrite(new PrintJob
{
JobId = job.JobId,
IP = job.PrinterIp,
Document = new SignalRPrintJobSource.PrintJobFromSignalR
{
JobId = job.JobId,
PrinterIp = job.PrinterIp,
LogoUrl = job.LogoUrl,
ReceiptType = job.ReceiptType,
Content = job.Content
}
});
}
}
public Task StartAsync()
{
return StartPollingAsync(_pollingCts.Token);
}
public async Task<PrintJob> GetNextJobAsync(CancellationToken cancellationToken)
{
return await _printJobChannel.Reader.ReadAsync(cancellationToken);
}
public void Dispose()
{
_pollingCts.Cancel();
_pollingCts.Dispose();
_httpClient.Dispose();
}
public class PrintJobDto
{
[JsonPropertyName("jobId")]
public string JobId { get; set; } = "";
[JsonPropertyName("printerIp")]
public string PrinterIp { get; set; } = "";
[JsonPropertyName("logoUrl")]
public string? LogoUrl { get; set; }
[JsonPropertyName("receiptType")]
public int ReceiptType { get; set; }
[JsonPropertyName("content")]
public string Content { get; set; } = "";
}
}