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 化 + 多设备并发调试 + 后台生命周期管理

---
 DeviceBroker/Program.cs |   79 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 79 insertions(+), 0 deletions(-)

diff --git a/DeviceBroker/Program.cs b/DeviceBroker/Program.cs
new file mode 100644
index 0000000..a5fc729
--- /dev/null
+++ b/DeviceBroker/Program.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+using log4net;
+
+namespace DeviceBroker
+{
+    /// <summary>
+    /// DeviceBroker 瀹夸富鍏ュ彛銆�
+    /// 鐢ㄦ硶: DeviceBroker.exe [--db data.db璺緞] [--arb arb.db璺緞] [--broker broker-b01]
+    /// 榛樿璺緞涓庨泦鎴愭祴璇曠幆澧冧竴鑷达紙%LOCALAPPDATA%\PluginIntegrationTest锛夈��
+    /// </summary>
+    public static class Program
+    {
+        private static readonly ILog Log = LogManager.GetLogger(typeof(Program));
+
+        public static async Task Main(string[] args)
+        {
+            var map = ParseArgs(args);
+            string appData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
+            string defaultDir = Path.Combine(appData, "PluginIntegrationTest");
+            string dbPath = Get(map, "--db", Path.Combine(defaultDir, "data.db"));
+            string arbPath = Get(map, "--arb", Path.Combine(defaultDir, "arb.db"));
+            string brokerId = Get(map, "--broker", "broker-b01");
+
+            Console.WriteLine($"DeviceBroker [{brokerId}]");
+            Console.WriteLine($"  閰嶇疆搴�: {dbPath}");
+            Console.WriteLine($"  浠茶搴�: {arbPath}");
+
+            if (!File.Exists(dbPath))
+            {
+                Console.WriteLine($"[FATAL] 閰嶇疆搴撲笉瀛樺湪锛岃鍏堝湪娉ㄥ唽椤典繚瀛樿澶囬厤缃�倇dbPath}");
+                Environment.ExitCode = 2;
+                return;
+            }
+
+            using var cts = new CancellationTokenSource();
+            Console.CancelKeyPress += (_, e) =>
+            {
+                e.Cancel = true;   // 浼橀泤閫�鍑猴細绉熺害闈� TTL 杩囨湡 + 浜哄伐鍥炴敹锛屼笉鍋氳繘绋嬪唴寮烘斁
+                cts.Cancel();
+                Console.WriteLine("[Broker] 鏀跺埌閫�鍑鸿姹傦紝鍦ㄩ�旂墖娈垫寜 deadline 鏀跺彛鈥�");
+            };
+
+            try
+            {
+                var server = new BrokerServer(dbPath, arbPath, brokerId);
+                server.LoadDevices();
+                Console.WriteLine($"[Broker] epoch={server.Epoch}锛孋trl+C 閫�鍑�");
+                await server.RunAsync(cts.Token).ConfigureAwait(false);
+            }
+            catch (Exception ex)
+            {
+                Log.Fatal("[Broker] 瀹夸富寮傚父閫�鍑�", ex);
+                Console.WriteLine($"[FATAL] {ex.Message}");
+                Environment.ExitCode = 1;
+            }
+        }
+
+        private static string Get(Dictionary<string, string> map, string key, string fallback)
+            => map.TryGetValue(key, out var v) && !string.IsNullOrWhiteSpace(v) ? v : fallback;
+
+        private static Dictionary<string, string> ParseArgs(string[] args)
+        {
+            var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+            for (int i = 0; i + 1 < args.Length; i++)
+            {
+                if (args[i].StartsWith("--"))
+                {
+                    map[args[i]] = args[i + 1];
+                    i++;
+                }
+            }
+            return map;
+        }
+    }
+}

--
Gitblit v1.9.1