heartbeat

This commit is contained in:
EugeneTes
2026-01-20 11:32:03 +01:00
parent 6f5116736c
commit 7cd2c75d14
3 changed files with 112 additions and 4 deletions

View File

@@ -0,0 +1,105 @@
using Inspectron.Epson.PrintServer.ConfigurationSources;
using Microsoft.Extensions.Logging;
using System.Net.Http.Json;
using System.Text.Json.Serialization;
namespace EpsonPrintService;
/// <summary>
/// Background task that periodically sends heartbeat signals to the API
/// </summary>
public class HeartbeatBackgroundTask
{
private readonly EpsonPrintServiceConfiguration _configuration;
private readonly ILogger _logger;
private readonly HttpClient _httpClient;
private readonly TimeSpan _interval;
public HeartbeatBackgroundTask(
EpsonPrintServiceConfiguration configuration,
ILogger logger)
{
_configuration = configuration;
_logger = logger;
_httpClient = new HttpClient();
_interval = TimeSpan.FromSeconds(30);
}
/// <summary>
/// Starts the heartbeat background task
/// </summary>
/// <param name="cancellationToken">Token to cancel the background task</param>
public async Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Starting heartbeat background task (interval: {Interval}s)", _interval.TotalSeconds);
// Run immediately on start
await SendHeartbeatAsync();
// Then run periodically
while (!cancellationToken.IsCancellationRequested)
{
try
{
await Task.Delay(_interval, cancellationToken);
await SendHeartbeatAsync();
}
catch (TaskCanceledException)
{
break;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error during heartbeat");
}
}
_logger.LogInformation("Heartbeat background task stopped");
}
private async Task SendHeartbeatAsync()
{
try
{
var url = _configuration.HeartbeatApiUrl;
var apiKey = _configuration.PrinterServerKey;
if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(apiKey))
{
_logger.LogWarning("Heartbeat not configured (missing HeartbeatApiUrl or PrinterServerKey)");
return;
}
using var request = new HttpRequestMessage(HttpMethod.Post, url);
request.Headers.Add("X-Printer-Server-Key", apiKey);
var payload = new HeartbeatPayload
{
OsVersion = Environment.OSVersion.ToString()
};
request.Content = JsonContent.Create(payload);
var response = await _httpClient.SendAsync(request);
if (response.IsSuccessStatusCode)
{
_logger.LogDebug("Heartbeat sent successfully");
}
else
{
_logger.LogWarning("Heartbeat failed with status code: {StatusCode}", response.StatusCode);
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to send heartbeat");
}
}
private class HeartbeatPayload
{
[JsonPropertyName("osVersion")]
public string OsVersion { get; set; } = string.Empty;
}
}

View File

@@ -45,12 +45,12 @@ kernel.Bind<IReceiptConverterFactory>().To<ReceiptConverterFactory>().InSingleto
kernel.Bind<PrintServer>().ToSelf().InSingletonScope();
kernel.Bind<IDiscoveredPrintersReceiver>().To<JamesDiscoveredPrintersReceiver>().InSingletonScope();
kernel.Bind<PrinterDiscoveryBackgroundTask>().ToSelf().InSingletonScope();
kernel.Bind<HeartbeatBackgroundTask>().ToSelf().InSingletonScope();
var printLoop = kernel.Get<PrintLoop>();
var printServer = kernel.Get<PrintServer>();
var discoveryTask = kernel.Get<PrinterDiscoveryBackgroundTask>();
printServer.RegisterPrinter("127.0.0.1");
var discoveryTask = kernel.Get<PrinterDiscoveryBackgroundTask>();
var heartbeatTask = kernel.Get<HeartbeatBackgroundTask>();
await printLoop.StartAsync();
@@ -64,8 +64,9 @@ Console.CancelKeyPress += (sender, e) =>
cts.Cancel();
};
// Start the printer discovery background task
// Start background tasks
_ = discoveryTask.StartAsync(cts.Token);
_ = heartbeatTask.StartAsync(cts.Token);
try
{

View File

@@ -7,6 +7,8 @@ public class EpsonPrintServiceConfiguration: IPrinterConfigurationSource, IAssig
public string GroupId { get; set; }
public string RestaurantId { get; set; }
public string ApiKey { get; set; }
public string? HeartbeatApiUrl { get; set; }
public string? PrinterServerKey { get; set; }
public Dictionary<string, PrinterConfiguration> PrinterConfigurations { get; set; }
public PrinterConfiguration GetConfiguration(string printerAddress)