From 559890c482f5973f06aafdfec9550fee5ba3c7f2 Mon Sep 17 00:00:00 2001
From: wenxiangchao <wenxiangchao@ihengxin.com.cn>
Date: 星期一, 09 十一月 2026 17:02:15 +0800
Subject: [PATCH] feat: CAN 模拟器 TCP 化 + 多设备并发调试 + 后台生命周期管理
---
Aging.Infrastructure/InfrastructureBootstrapper.cs | 79 +++++++++++++++++++++++++++++++++++++--
1 files changed, 75 insertions(+), 4 deletions(-)
diff --git a/Aging.Infrastructure/InfrastructureBootstrapper.cs b/Aging.Infrastructure/InfrastructureBootstrapper.cs
index aebb5b0..63169ee 100644
--- a/Aging.Infrastructure/InfrastructureBootstrapper.cs
+++ b/Aging.Infrastructure/InfrastructureBootstrapper.cs
@@ -1,5 +1,7 @@
+using System.IO;
using log4net;
using HMI.Core.Util;
+using Aging.Infrastructure.Broker;
using Aging.Infrastructure.Contracts;
using Aging.Infrastructure.Core;
using Aging.Infrastructure.Services;
@@ -32,10 +34,16 @@
{
log.Info("寮�濮嬪垵濮嬪寲鍩虹璁炬柦鏈嶅姟...");
- // 1. 鍒涘缓 ResourceManager 鍗曚緥
- var resourceManager = new ResourceManager();
+ // V3.0 MVP锛氫徊瑁佸簱 arb.db锛堜笌 data.db 鍚岀洰褰曪級
+ string arbPath = Path.Combine(Path.GetDirectoryName(deviceConfigDbPath)!, "arb.db");
+ var leaseStore = new DbLeaseStore(arbPath, "local-main");
+ // V3.0 INV-03锛氬惎鍔ㄥ璐︹�斺�斾笂娆¤繘绋嬪紓甯搁��鍑烘湭閲婃斁鐨勭绾﹀湪鏈満瀹夸富鏇存浛鍚庤嚜鍔ㄥ洖鏀讹紝
+ // 閬垮厤璋冭瘯/鐢熶骇缁存姢琚� RecoveryRequired 姘镐箙闃诲锛堣瘉鎹啓鍏� recovery_checkpoint锛�
+ leaseStore.ReconcileAfterBoot($"{Environment.MachineName}/{System.Diagnostics.Process.GetCurrentProcess().Id}");
+ var resourceManager = new LayeredResourceManager(leaseStore);
+ UtilContainer.RegisterUtil("LeaseCoordinator", leaseStore);
UtilContainer.RegisterUtil("ResourceManager", resourceManager);
- log.Info("ResourceManager 宸叉敞鍐�");
+ log.Info("LayeredResourceManager (鍩轰簬 DbLeaseStore) 宸叉敞鍐�");
// 2. 鍒涘缓 DeviceManager 鍗曚緥
var deviceManager = new DeviceManager();
@@ -57,8 +65,21 @@
UtilContainer.RegisterUtil("PowerSupplyService", powerSupplyService);
log.Info("PowerSupplyService 宸叉敞鍐�");
- // 6. 浠庢暟鎹簱鍔犺浇璁惧瀹氫箟骞舵敞鍐岄┍鍔�
+ // 6. 鍒涘缓 AutoDeviceFacade (鑷姩鍖栨祴璇曞叆鍙�)
+ var autoFacade = new AutoDeviceFacade(resourceManager, deviceService);
+ UtilContainer.RegisterUtil("AutoDeviceFacade", autoFacade);
+ log.Info("AutoDeviceFacade 宸叉敞鍐�");
+
+ // 7. 鍒涘缓 CanBusService (CAN 绫诲瀷鍖栨湇鍔�)
+ var canBusService = new CanBusService(autoFacade);
+ UtilContainer.RegisterUtil("CanBusService", canBusService);
+ log.Info("CanBusService 宸叉敞鍐�");
+
+ // 8. 浠庢暟鎹簱鍔犺浇璁惧瀹氫箟骞舵敞鍐岄┍鍔�
LoadDevicesFromConfig(deviceManager, mappingResolver);
+
+ // 8.5. V3.0 娣峰悎鏋舵瀯锛欱roker 鍩熻澶囨敞鍐屼唬鐞嗛┍鍔紙鐗╃悊浼氳瘽鐢� DeviceBroker.exe 瀹夸富鍞竴鎸佹湁锛�
+ RegisterBrokeredDrivers(deviceManager, deviceConfigDbPath);
_initialized = true;
log.Info("鍩虹璁炬柦鏈嶅姟鍒濆鍖栧畬鎴�");
@@ -71,6 +92,56 @@
}
/// <summary>
+ /// V3.0锛氭壂鎻忛厤缃簱涓� ExecutionMode=Broker 鐨勮澶囷紝娉ㄥ唽缁熶竴 CanDeviceDriver锛圔rokerRpc 浠g悊鍚庣锛夈��
+ /// Local 璁惧淇濇寔鐜版湁鐩撮┍璺緞涓嶅彉锛汢roker 瀹夸富鏈惎鍔ㄦ椂浠g悊浠呭湪鍙戣捣 I/O 鏃跺け璐ワ紝涓嶉樆濉炲垵濮嬪寲銆�
+ /// </summary>
+ private static void RegisterBrokeredDrivers(IDeviceManager deviceManager, string deviceConfigDbPath)
+ {
+ try
+ {
+ if (!File.Exists(deviceConfigDbPath)) return;
+
+ var brokeredDevices = new System.Collections.Generic.List<(string DeviceId, string BrokerId, string Endpoint)>();
+ using (var conn = new System.Data.SQLite.SQLiteConnection(
+ $"Data Source={deviceConfigDbPath};Version=3;Read Only=True;"))
+ {
+ conn.Open();
+ using var cmd = conn.CreateCommand();
+ cmd.CommandText = "SELECT DeviceId, BrokerId, Endpoint FROM DeviceDefinition WHERE ExecutionMode = 'Broker';";
+ using var rd = cmd.ExecuteReader();
+ while (rd.Read())
+ {
+ string id = rd.GetString(0);
+ string brokerId = rd.IsDBNull(1) ? "" : rd.GetString(1);
+ string endpoint = rd.IsDBNull(2) ? "" : rd.GetString(2);
+ if (!string.IsNullOrWhiteSpace(brokerId))
+ brokeredDevices.Add((id, brokerId, endpoint));
+ }
+ }
+
+ if (brokeredDevices.Count == 0) return;
+
+ // INV-04锛氬鎴风渚х敓鏁堥厤缃揩鐓э紝闅忔瘡娆� RPC 鎻愪氦渚� Broker 瀵硅处
+ string configHash;
+ try { configHash = DeviceConfigHash.Compute(deviceConfigDbPath); }
+ catch { configHash = ""; }
+
+ foreach (var (deviceId, brokerId, endpoint) in brokeredDevices)
+ {
+ if (deviceManager.GetDriver(deviceId) != null) continue;
+ var driver = CanDeviceDriver.CreateBrokerProxy(deviceId, endpoint, BrokerPipeName.For(brokerId), configHash);
+ deviceManager.RegisterDriver(deviceId, driver);
+ log.Info($"[Bootstrapper] 璁惧 {deviceId} 宸叉敞鍐� Broker 浠g悊椹卞姩 (绠¢亾={BrokerPipeName.For(brokerId)}, hash={configHash.Substring(0, Math.Min(8, configHash.Length))})");
+ }
+ }
+ catch (Exception ex)
+ {
+ // 浠g悊娉ㄥ唽澶辫触闄嶇骇锛氫笉褰卞搷 Local 鐩撮┍璁惧閾捐矾
+ log.Warn($"[Bootstrapper] Broker 浠g悊椹卞姩娉ㄥ唽澶辫触锛圔roker 閾捐矾涓嶅彲鐢紝Local 璁惧涓嶅彈褰卞搷锛�: {ex.Message}", ex);
+ }
+ }
+
+ /// <summary>
/// 浠� DeviceConfig 鏁版嵁搴撳姞杞借澶囧畾涔夊苟娉ㄥ唽椹卞姩
/// </summary>
private static void LoadDevicesFromConfig(IDeviceManager deviceManager, SlotDeviceMappingResolver mappingResolver)
--
Gitblit v1.9.1