free-code-dotnet/docs/服务子系统设计/服务子系统设计-其他服务子系统.md
应文浩wenhao.ying@xiaobao100.com e25ac591a7 init easy-code
2026-04-06 07:24:24 +08:00

5.6 KiB

服务子系统设计 — 其他服务子系统

元数据

21.1 远程会话

public interface IRemoteSessionManager
{
    Task ConnectAsync(string endpoint, CancellationToken cancellationToken = default);
    Task DisconnectAsync(CancellationToken cancellationToken = default);
    IAsyncEnumerable<RemoteEvent> ReadEventsAsync(CancellationToken cancellationToken = default);
}

public abstract record RemoteEvent(DateTimeOffset Timestamp);
public sealed record RemoteConnectedEvent(DateTimeOffset Timestamp, string SessionId) : RemoteEvent(Timestamp);
public sealed record RemoteDisconnectedEvent(DateTimeOffset Timestamp, string Reason) : RemoteEvent(Timestamp);
public sealed record RemoteMessageEvent(DateTimeOffset Timestamp, string Message) : RemoteEvent(Timestamp);

public enum RemoteConnectionStatus
{
    Disconnected,
    Connecting,
    Connected,
    Reconnecting,
    Failed
}

远程会话管理用于把本地交互扩展到远端主机或托管环境,并通过事件流表达连接状态、消息和断连原因。

21.2 语音输入

public interface IVoiceService
{
    Task StartAsync(CancellationToken cancellationToken = default);
    Task StopAsync(CancellationToken cancellationToken = default);
    Task<string?> RecognizeAsync(CancellationToken cancellationToken = default);
}

public sealed class VoiceService : IVoiceService
{
    public Task StartAsync(CancellationToken cancellationToken = default) => Task.CompletedTask;
    public Task StopAsync(CancellationToken cancellationToken = default) => Task.CompletedTask;
    public Task<string?> RecognizeAsync(CancellationToken cancellationToken = default) => Task.FromResult<string?>(null);
}

语音输入采用特性开关与 OAuth 门控:只有启用对应功能且完成授权后,语音能力才会暴露给会话流程。

21.3 通知服务

public interface INotificationService
{
    Task NotifyAsync(string title, string message, CancellationToken cancellationToken = default);
    bool IsSupportedTerminal();
}

public sealed class NotificationService : INotificationService
{
    public Task NotifyAsync(string title, string message, CancellationToken cancellationToken = default)
        => Task.CompletedTask;

    public bool IsSupportedTerminal()
    {
        var terminal = Environment.GetEnvironmentVariable("TERM_PROGRAM") ?? string.Empty;
        return terminal is "iTerm2" or "Kitty" or "Ghostty";
    }
}

通知服务依赖终端类型检测,在 iTerm2、Kitty、Ghostty 等环境中可提供更稳定的本地通知体验。

21.4 限流服务

public interface IRateLimitService
{
    bool CanProceed(IDictionary<string, string> headers);
    TimeSpan? GetRetryAfter(IDictionary<string, string> headers);
}

public sealed class RateLimitService : IRateLimitService
{
    public bool CanProceed(IDictionary<string, string> headers)
        => !GetRetryAfter(headers).HasValue;

    public TimeSpan? GetRetryAfter(IDictionary<string, string> headers)
    {
        foreach (var pair in headers)
        {
            if (pair.Key.StartsWith("anthropic-ratelimit-tokens-", StringComparison.OrdinalIgnoreCase))
            {
                return TimeSpan.FromSeconds(30);
            }
        }

        return null;
    }
}

限流服务通过解析 anthropic-ratelimit-tokens-* 头部推断令牌配额状态,并用于动态退避与重试控制。

21.5 伙伴系统

public interface ICompanionService
{
    Companion Create(string seed);
}

public sealed class CompanionService : ICompanionService
{
    public Companion Create(string seed)
    {
        var prng = new Mulberry32(seed.GetHashCode());
        return new Companion(
            Species: Species.Cat,
            Eye: Eye.Blue,
            Hat: Hat.Bowler,
            Rarity: Rarity.Rare,
            Name: $"Companion-{prng.NextInt(1000)}");
    }
}

public sealed class Mulberry32
{
    private uint _state;
    public Mulberry32(int seed) => _state = (uint)seed;
    public int NextInt(int max) => (int)(NextUInt() % (uint)max);
    private uint NextUInt()
    {
        _state += 0x6D2B79F5;
        var t = _state;
        t = (t ^ (t >> 15)) * (t | 1);
        t ^= t + (t ^ (t >> 7)) * (t | 61);
        return t ^ (t >> 14);
    }
}

public sealed record Companion(Species Species, Eye Eye, Hat Hat, Rarity Rarity, string Name);

public enum Species { Cat, Dog, Fox, Owl }
public enum Eye { Blue, Green, Gold, Red }
public enum Hat { None, Bowler, Cap, Crown }
public enum Rarity { Common, Uncommon, Rare, Epic, Legendary }

伙伴系统使用确定性生成逻辑:相同种子输入会产生相同角色结果,便于同步、复现和测试。

21.6 交叉引用