namespace NetAdmin.Host.Middlewares; /// /// 安全停机中间件 /// /// /// 放在所有中间件最前面 /// public sealed class SafetyShopHostMiddleware(RequestDelegate next) { private static long _connections; private static bool _trafficOff; /// /// 当前连接数 /// public static long Connections => Interlocked.Read(ref _connections); /// /// 是否已停机 /// public static bool IsShutdown => Volatile.Read(ref _trafficOff); /// /// 停机处理 /// public static void OnStopping() { Stop(); while (Interlocked.Read(ref _connections) > 0) { Thread.Sleep(10); } } /// /// 系统启机 /// public static void Start() { Volatile.Write(ref _trafficOff, false); } /// /// 系统停机 /// public static void Stop() { Volatile.Write(ref _trafficOff, true); } /// /// 主函数 /// public async Task InvokeAsync(HttpContext context) { if (Volatile.Read(ref _trafficOff) && !context.Request.Path.StartsWithSegments($"/{Chars.FLG_PATH_API_RPOBE}")) { context.Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable; return; } // webSocket链接不参与计算 if (context.Request.Path.StartsWithSegments($"/{Chars.FLG_PATH_WEBSOCKET_PREFIX}")) { await next(context).ConfigureAwait(false); } else { _ = Interlocked.Increment(ref _connections); await next(context).ConfigureAwait(false); _ = Interlocked.Decrement(ref _connections); } } }