XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEExtension.NetCore.ServerInteractive

[DLL] Server interaction extension, including user identity verification and querying in conjunction with AutoConfig

公开
关注 0 Fork 0 Star 0
UTF-8
using XFEExtension.NetCore.AutoImplement;
using XFEExtension.NetCore.ServerInteractive.Implements.ServerService;
using XFEExtension.NetCore.ServerInteractive.Interfaces.ServerService;

namespace XFEExtension.NetCore.ServerInteractive.Utilities.Server;

/// <summary>XFE 服务器生命周期状态。</summary>
public enum XFEServerState
{
    Created,
    Starting,
    Running,
    Stopping,
    Stopped,
    Faulted
}

/// <summary>
/// 可由控制台 EXE 驱动并支持优雅停止的 XFE 服务器。
/// </summary>
[CreateImpl]
public class XFEServer : IAsyncDisposable
{
    private readonly SemaphoreSlim _lifecycleGate = new(1, 1);
    private CancellationTokenSource? _runSource;
    private Task? _runTask;
    private bool _initialized;

    internal readonly List<IServerInitializerService> ServerInitializerServiceList = [];
    internal readonly List<IServerService> ServerServiceList = [];
    internal readonly List<IAsyncServerService> AsyncServerServiceList = [];
    public IServerCoreProcessService ServerCoreProcessService { get; set; } = new ServerCoreProcessServiceBaseImpl();
    public XFEServerState State { get; private set; } = XFEServerState.Created;

    /// <summary>启动服务器并在全部监听器就绪后返回。</summary>
    public async Task StartAsync(CancellationToken cancellationToken = default)
    {
        await _lifecycleGate.WaitAsync(cancellationToken).ConfigureAwait(false);
        try
        {
            if (State == XFEServerState.Running) return;
            if (State is XFEServerState.Starting or XFEServerState.Stopping)
                throw new InvalidOperationException($"服务器当前状态不允许启动:{State}");
            State = XFEServerState.Starting;

            if (!_initialized)
            {
                foreach (var initializer in ServerInitializerServiceList) initializer.Initialize();
                foreach (var service in ServerServiceList) service.StartService();
                foreach (var service in AsyncServerServiceList) await service.StartServiceAsync().ConfigureAwait(false);
                _initialized = true;
            }

            XFEServerCoreHost.Configure(ServerCoreProcessService.ServerCoreServiceList.OfType<XFEServerCore>());
            await ServerCoreProcessService.StartAsync(cancellationToken).ConfigureAwait(false);
            _runSource?.Dispose();
            _runSource = new CancellationTokenSource();
            _runTask = ServerCoreProcessService.RunAsync(_runSource.Token);
            State = XFEServerState.Running;
        }
        catch
        {
            State = XFEServerState.Faulted;
            throw;
        }
        finally
        {
            _lifecycleGate.Release();
        }
    }

    /// <summary>启动服务器并等待取消或服务器结束。</summary>
    public async Task RunAsync(CancellationToken cancellationToken = default)
    {
        await StartAsync(cancellationToken).ConfigureAwait(false);
        using var registration = cancellationToken.Register(static state => ((CancellationTokenSource)state!).Cancel(), _runSource);
        try
        {
            if (_runTask is not null) await _runTask.ConfigureAwait(false);
        }
        catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested || _runSource?.IsCancellationRequested == true)
        {
        }
        finally
        {
            await StopAsync(CancellationToken.None).ConfigureAwait(false);
        }
    }

    /// <summary>停止接收新请求并关闭底层 CyberComm 服务器。</summary>
    public async Task StopAsync(CancellationToken cancellationToken = default)
    {
        await _lifecycleGate.WaitAsync(cancellationToken).ConfigureAwait(false);
        try
        {
            if (State is XFEServerState.Created or XFEServerState.Stopped)
            {
                State = XFEServerState.Stopped;
                return;
            }
            if (State == XFEServerState.Stopping) return;
            State = XFEServerState.Stopping;
            _runSource?.Cancel();
            await ServerCoreProcessService.StopAsync(cancellationToken).ConfigureAwait(false);
            if (_runTask is not null)
            {
                try { await _runTask.ConfigureAwait(false); }
                catch (OperationCanceledException) { }
            }
            State = XFEServerState.Stopped;
        }
        finally
        {
            _lifecycleGate.Release();
        }
    }

    /// <summary>兼容旧 API:启动并持续运行直到服务器停止。</summary>
    [Obsolete("请使用 RunAsync(CancellationToken)")]
    public Task Start() => RunAsync();

    public async ValueTask DisposeAsync()
    {
        await StopAsync().ConfigureAwait(false);
        _runSource?.Dispose();
        _lifecycleGate.Dispose();
    }
}