Files
Ayay/SHH.CameraService/Program.cs

194 lines
6.2 KiB
C#
Raw Normal View History

2025-12-29 08:09:14 +08:00
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using SHH.CameraSdk; // 引用你的业务核心
using SHH.NetMQ;
namespace SHH.CameraService;
public class Program
{
public static async Task Main(string[] args)
{
#region --- 1. ---
2025-12-29 08:09:14 +08:00
int processId = 1;
// 从命令行参数解析进程ID默认1
if (args.Length > 0 && int.TryParse(args[0], out int pid))
processId = pid;
// 计算 Web 服务端口基础5000 + 进程ID偏移
2025-12-29 08:09:14 +08:00
int port = 5000 + (processId - 1);
Console.Title = $"SHH Gateway - Instance #{processId} (Port: {port})";
#endregion
#region --- 2. () ---
2025-12-29 08:09:14 +08:00
InitHardwareEnv();
#endregion
#region --- 3. WebHost ---
2025-12-29 08:09:14 +08:00
var builder = WebApplication.CreateBuilder(args);
#region --- A. ZeroMQ () ---
// 注册转发客户端(定向推送)
2025-12-29 08:09:14 +08:00
string zmqBind = $"tcp://*:{5555 + (processId - 1)}";
// ★★★ 新增:注册指令总线服务 ★★★
2025-12-29 08:09:14 +08:00
string zmqTarget = "tcp://127.0.0.1:6000";
// 注册转发客户端(定向推送)
2025-12-29 08:09:14 +08:00
builder.Services.AddSingleton(new ForwarderClient(zmqTarget));
// ★★★ 新增:注册指令总线服务 ★★★
builder.Services.AddHostedService<CommandBusService>();
// 注册分发服务器(广播)
builder.Services.AddSingleton(new DistributorServer(zmqBind));
#endregion
#region --- B. ---
// 注册文件存储服务(进程隔离)
2025-12-29 08:09:14 +08:00
builder.Services.AddSingleton<IStorageService>(new FileStorageService(processId));
2025-12-29 08:09:14 +08:00
// CameraManager 注册为单例,生命周期由 CameraEngineWorker 管理
builder.Services.AddSingleton<CameraManager>();
// 图像处理配置管理器(单例)
2025-12-29 08:09:14 +08:00
builder.Services.AddSingleton<ProcessingConfigManager>();
// 显示窗口管理器(单例)
2025-12-29 08:09:14 +08:00
builder.Services.AddSingleton<DisplayWindowManager>();
#endregion
2025-12-29 08:09:14 +08:00
#region --- C. () ---
// 说明:通过责任链模式组装 Scale → Enhance 处理流程,确保顺序执行
// 1. 注册图像缩容集群并行度4
2025-12-29 08:09:14 +08:00
builder.Services.AddSingleton<ImageScaleCluster>(sp =>
{
var configManager = sp.GetRequiredService<ProcessingConfigManager>();
return new ImageScaleCluster(4, configManager);
2025-12-29 08:09:14 +08:00
});
// 2. 注册图像增强集群并行度4
2025-12-29 08:09:14 +08:00
builder.Services.AddSingleton<ImageEnhanceCluster>(sp =>
{
var configManager = sp.GetRequiredService<ProcessingConfigManager>();
return new ImageEnhanceCluster(4, configManager);
2025-12-29 08:09:14 +08:00
});
// 3. 注册管道配置服务(组装责任链)
2025-12-29 08:09:14 +08:00
builder.Services.AddHostedService<PipelineConfigurator>();
#endregion
#region --- D. Web ---
2025-12-29 08:09:14 +08:00
// 注册控制器(加载 SDK 中的 CamerasController、MonitorController
2025-12-29 08:09:14 +08:00
builder.Services.AddControllers()
.AddApplicationPart(typeof(CamerasController).Assembly) // 加载 SDK 中的控制器
.AddApplicationPart(typeof(MonitorController).Assembly)
.AddControllersAsServices();
// 注册全局操作日志过滤器(捕获 API 操作日志)
2025-12-29 08:09:14 +08:00
builder.Services.AddScoped<UserActionFilter>();
// 注册 Swagger 文档区分实例ID
2025-12-29 08:09:14 +08:00
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = $"Gateway #{processId}",
Version = "v1"
});
2025-12-29 08:09:14 +08:00
});
#endregion
#region --- E. (Worker) ---
2025-12-29 08:09:14 +08:00
// 1. 核心引擎工作者 (负责 StartAsync 和 ConfigureBusinessLogic)
builder.Services.AddHostedService<CameraEngineWorker>();
// 2.网络哨兵(负责断线重连)(监控设备断线重连,注册为单例)
builder.Services.AddSingleton<ConnectivitySentinel>();
2025-12-29 08:09:14 +08:00
// 3. ZeroMQ 桥梁服务(转发帧数据到外部系统)
2025-12-29 08:09:14 +08:00
builder.Services.AddHostedService<ZeroMqBridgeService>();
#endregion
#region --- F. CORS ---
2025-12-29 08:09:14 +08:00
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowAll", policy =>
{
policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
});
});
#endregion
#endregion
#region --- 4. ---
2025-12-29 08:09:14 +08:00
var app = builder.Build();
// 启用 Swagger 文档
2025-12-29 08:09:14 +08:00
app.UseSwagger();
app.UseSwaggerUI();
// 启用 CORS 策略
app.UseCors("AllowAll");
// 映射控制器路由
2025-12-29 08:09:14 +08:00
app.MapControllers();
// 输出启动信息
2025-12-29 08:09:14 +08:00
Console.WriteLine($"[System] 绑定 Web 端口: {port}");
Console.WriteLine($"[System] 绑定 ZMQ 端口: {zmqBind}");
// 启动 Web 应用
2025-12-29 08:09:14 +08:00
await app.RunAsync($"http://0.0.0.0:{port}");
#endregion
2025-12-29 08:09:14 +08:00
}
#region --- ---
/// <summary>
/// 初始化硬件环境(海康 SDK 预热)
/// </summary>
2025-12-29 08:09:14 +08:00
static void InitHardwareEnv()
{
Console.WriteLine("=== 工业级视频 SDK 架构测试 (V3.5 框架版) ===");
Console.WriteLine("[硬件] 海康驱动预热中...");
try
{
// 初始化海康 SDK
2025-12-29 08:09:14 +08:00
HikNativeMethods.NET_DVR_Init();
// 强制预热播放库(避免首次取流延迟)
2025-12-29 08:09:14 +08:00
HikSdkManager.ForceWarmUp();
Console.WriteLine("[硬件] 预热完成。");
}
catch (Exception ex)
{
Console.WriteLine($"[硬件] 预热失败: {ex.Message}");
// 不抛出异常,允许程序在无 DLL 环境下调试
2025-12-29 08:09:14 +08:00
}
}
#endregion
2025-12-29 08:09:14 +08:00
}