client: Windows 客户端(WinUI3 壳 + agent-core;调试用 Electron 壳存档);localserver token 改为常数时间比较

This commit is contained in:
Qiufeng
2026-08-20 20:38:21 +08:00
parent 33b7d57498
commit 9abf7f8213
60 changed files with 10025 additions and 0 deletions
+91
View File
@@ -0,0 +1,91 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace EveryPublish.Client.Services;
/// <summary>看门狗:spawn agent-core 子进程,5s 心跳检查,失败自动拉起,3 次失败告警</summary>
public class Watchdog : IDisposable
{
private readonly CoreClient _core;
private readonly string _dataDir;
private readonly Action _onFatal;
private Process? _proc;
private Timer? _timer;
private int _failCount;
public Watchdog(CoreClient core, string dataDir, Action onFatal)
{
_core = core;
_dataDir = dataDir;
_onFatal = onFatal;
}
public void Start()
{
Spawn();
_timer = new Timer(_ => Check(), null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5));
}
public void Restart()
{
try { _proc?.Kill(); } catch { /* 忽略 */ }
Spawn();
}
private void Spawn()
{
var exe = Path.Combine(AppContext.BaseDirectory, "agent-core.exe");
if (!File.Exists(exe))
{
_onFatal();
return;
}
var psi = new ProcessStartInfo
{
FileName = exe,
Arguments = "-dir \"" + _dataDir + "\"",
WorkingDirectory = Path.GetDirectoryName(exe) ?? AppContext.BaseDirectory,
CreateNoWindow = true,
UseShellExecute = false,
};
_proc = Process.Start(psi);
}
private void Check()
{
_core.ReloadLocalJson();
var healthy = false;
if (_proc != null && !_proc.HasExited)
{
try
{
var status = _core.GetStatusAsync().GetAwaiter().GetResult();
healthy = status != null;
}
catch
{
healthy = false;
}
}
if (healthy)
{
_failCount = 0;
return;
}
_failCount++;
if (_failCount >= 3)
{
_onFatal();
return;
}
Spawn();
}
public void Dispose()
{
_timer?.Dispose();
try { _proc?.Kill(); } catch { /* 忽略 */ }
}
}