Files
Ayay/SHH.CameraService/Program.cs

130 lines
5.3 KiB
C#
Raw Normal View History

2026-01-15 18:56:39 +08:00
using Ayay.SerilogLogs;
2026-01-15 09:31:57 +08:00
using Microsoft.AspNetCore.Builder;
2025-12-29 08:09:14 +08:00
using Microsoft.Extensions.DependencyInjection;
2026-01-15 18:56:39 +08:00
using Serilog;
using SHH.CameraSdk;
2025-12-29 08:09:14 +08:00
namespace SHH.CameraService;
public class Program
{
2026-01-15 18:56:39 +08:00
/// <summary>
/// 主程序
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
2025-12-29 08:09:14 +08:00
public static async Task Main(string[] args)
{
2026-01-15 09:31:57 +08:00
// 1. [核心环境] 必须在所有网络操作前开启
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
2026-01-15 18:56:39 +08:00
// 2. 解析配置与初始化日志
var (config, opts, isDebugArgs) = Bootstrapper.ParseConfigAndInitLogger(args);
var sysLog = Log.ForContext("SourceContext", LogModules.Core);
2026-01-05 14:54:06 +08:00
// =============================================================
2026-01-15 18:56:39 +08:00
// 1. 启动日志
// =============================================================
2026-01-15 18:56:39 +08:00
sysLog.Warning($"🚀 视频取流进程启动, 日志组件初始化完毕 => 进程: {opts.AppId}");
string argString = string.Join(" ", args);
sysLog.Debug($"🚀 启动参数({(isDebugArgs ? "" : "")}: {argString}");
2026-01-05 14:54:06 +08:00
2026-01-15 09:31:57 +08:00
// =============================================================
2026-01-15 18:56:39 +08:00
// 2. 硬件预热、端口扫描、gRPC链接
2026-01-15 09:31:57 +08:00
// =============================================================
2026-01-15 18:56:39 +08:00
Bootstrapper.WarmUpHardware(sysLog);
2026-01-15 18:56:39 +08:00
// 端口自动扫描 (必须做,否则端口冲突)
int activePort = Bootstrapper.ScanForAvailablePort(config, sysLog);
if (activePort == -1)
{
sysLog.Fatal("💀 无法启动:配置范围内无可用端口");
Bootstrapper.Shutdown("无法启动:配置范围内无可用端口", exitCode: 1);
return;
}
config.UpdateActualPort(activePort); // 回填端口
2026-01-15 18:56:39 +08:00
// 具体的 gRPC 链接逻辑封装在 Bootstrapper 中,保持 Main 清爽但逻辑可见
await Bootstrapper.RegisterToGatewayAsync(config, sysLog);
2025-12-29 08:09:14 +08:00
// =============================================================
2026-01-15 18:56:39 +08:00
// 3. 构建 Web 主机环境
// =============================================================
2026-01-15 18:56:39 +08:00
var builder = WebApplication.CreateBuilder(args);
2026-01-15 18:56:39 +08:00
// ★ 核心改动:一行代码注册所有业务 (SDK, Workers, gRPC, 视频流)
builder.Services.AddCameraBusinessServices(config, sysLog);
2025-12-29 08:09:14 +08:00
2026-01-15 18:56:39 +08:00
// ★ 核心改动:注册 Web 基础 (Controller, Swagger, Cors)
builder.Services.AddWebSupport(config);
2026-01-15 09:31:57 +08:00
// =============================================================
2026-01-15 09:31:57 +08:00
// 6. 启动服务
// =============================================================
var app = builder.Build();
2025-12-29 08:09:14 +08:00
2026-01-15 09:31:57 +08:00
// 激活 SDK 管理器并启动业务点火
2026-01-15 18:56:39 +08:00
await StartBusinessLogic(app, sysLog);
2026-01-15 18:56:39 +08:00
// ★ 核心改动:配置 HTTP 管道 (Swagger, MapControllers 等)
app.ConfigurePipeline(config);
2026-01-05 14:54:06 +08:00
2026-01-15 18:56:39 +08:00
// 启动监听
string url = $"http://0.0.0.0:{config.BasePort}";
sysLog.Information($"🚀 [WebApi] 服务启动,监听: {url}");
2026-01-15 18:56:39 +08:00
await app.RunAsync(url);
2025-12-29 08:09:14 +08:00
}
/// <summary>
2026-01-15 09:31:57 +08:00
/// 激活单例并启动相机管理器
/// </summary>
2026-01-15 18:56:39 +08:00
/// <param name="app"></param>
/// <param name="logger"></param>
static async Task StartBusinessLogic(WebApplication app, Serilog.ILogger logger)
2026-01-05 14:54:06 +08:00
{
var manager = app.Services.GetRequiredService<CameraManager>();
2026-01-15 18:56:39 +08:00
// 激活哨兵
_ = app.Services.GetRequiredService<ConnectivitySentinel>();
2026-01-15 18:56:39 +08:00
await manager.StartAsync();
2026-01-15 18:56:39 +08:00
Console.WriteLine("✅[System] 核心业务逻辑已激活。");
2025-12-29 08:09:14 +08:00
}
2026-01-15 18:56:39 +08:00
}
/*
🚀 /
🏁 / 退
🔄 /
/
💤 / 线
🌐 /HTTP HTTP API Web
🔌 Socket
📡 /广 MQ 广
💾 /
🔒 /
/
🐞 Bug/
🧪 /
🔍 /
💡 /
🔴 / (Fatal/Error)
🟡 (Warning)
🟢 绿/ (Info/Success)
🔵 / (Data/Network)
/ (Debug/Verbose)
Check Mark Button \u{2705} &#x2705;
🆗 OK Button \u{1F197} &#x1F197;
🔚 END Arrow () \u{1F51A} &#x1F51A;
💯 Hundred Points () \u{1F4AF} &#x1F4AF;
🛑 Stop Sign () \u{1F6D1} &#x1F6D1;
No Entry (/) \u{26D4} &#x26D4;
🚫 Prohibited () \u{1F6AB} &#x1F6AB;
Stop Button () \u{23F9} &#x23F9;
Cross Mark () \u{274C} &#x274C;
💀 Skull ( Kill) \u{1F480} &#x1F480;
Coffin () \u{26B0} &#x26B0;
👻 Ghost () \u{1F47B} &#x1F47B;
*/