feat: add remote control plane and whitelist reads
Build web service image / build (push) Successful in 1m53s

This commit is contained in:
2026-09-12 09:46:05 +08:00
parent c86ba9c4d7
commit 13c31fc902
53 changed files with 9878 additions and 43 deletions
+26 -2
View File
@@ -1,4 +1,6 @@
using System.Text.Json;
using Microsoft.Extensions.Hosting;
using WxAgent.Core;
namespace WxAgent.Service;
@@ -7,7 +9,7 @@ public interface IAgentEventSource
IAsyncEnumerable<AgentEvent> ListenAsync(CancellationToken cancellationToken);
}
public sealed class EventPump(IAgentBackend backend, EventHub hub, ServiceOptions options) : BackgroundService
public sealed class EventPump(IAgentBackend backend, EventHub hub, ServiceOptions options, RemoteEventQueue? remoteQueue = null) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
@@ -18,13 +20,35 @@ public sealed class EventPump(IAgentBackend backend, EventHub hub, ServiceOption
{
await foreach (var item in source.ListenAsync(stoppingToken))
{
var runtime = await LoadRuntimeConfigurationAsync(options, stoppingToken);
if (remoteQueue is not null && runtime.Remote.IsConfigured && item.Kind == "message"
&& item.ChatId is { Length: > 0 } chatId && item.ChatType is { } chatType)
{
_ = remoteQueue.Enqueue(runtime.Reporting, runtime.Remote.NodeId!, item.AccountId, chatId, chatType,
item.Kind, item.At, item.Content);
}
var localItem = item with { Content = null };
foreach (var credential in options.ReadCredentials())
if (credential.AccountIds.Length == 0 || credential.AccountIds.Contains(item.AccountId, StringComparer.Ordinal))
hub.Publish(credential.PrincipalId, item);
hub.Publish(credential.PrincipalId, localItem);
}
}
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) { return; }
catch (Exception) { await Task.Delay(TimeSpan.FromSeconds(2), stoppingToken); }
}
}
private static async Task<RemoteNodeConfiguration> LoadRuntimeConfigurationAsync(ServiceOptions options, CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(options.RemoteConfigurationFile))
return new RemoteNodeConfiguration { Remote = options.Remote ?? new RemoteAgentOptions(), Reporting = options.Reporting };
try
{
return await RemoteNodeConfigurationStore.LoadAsync(options.RemoteConfigurationFile, cancellationToken);
}
catch (Exception exception) when (exception is IOException or JsonException or WxAgentException)
{
return new RemoteNodeConfiguration();
}
}
}