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.ResourceContracts/BrokerIpc.cs |   91 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 91 insertions(+), 0 deletions(-)

diff --git a/Aging.ResourceContracts/BrokerIpc.cs b/Aging.ResourceContracts/BrokerIpc.cs
new file mode 100644
index 0000000..1aef23f
--- /dev/null
+++ b/Aging.ResourceContracts/BrokerIpc.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Buffers.Binary;
+using System.Text;
+using System.Text.Json;
+
+namespace Aging.ResourceContracts
+{
+    /// <summary>
+    /// Broker IPC 甯у崗璁細4 瀛楄妭澶х闀垮害鍓嶇紑 + UTF8 JSON 灏佸銆�
+    /// 鍗忚涓荤増鏈笉鍖归厤鏃� Broker 鐩存帴鎷掔粷杩炴帴锛圴3.0 搂13锛夈��
+    /// DTO 绾挎牸寮忕嫭绔嬩簬 LeaseGrant 绛夊彧璇绘瀯閫犲櫒绫诲瀷锛岃閬� System.Text.Json 鍙嶅簭鍒楀寲闄愬埗銆�
+    /// </summary>
+    public static class BrokerIpc
+    {
+        public const int ProtocolVersion = 1;
+
+        /// <summary>鍗曞抚鏈�澶у瓧鑺傛暟锛�1MB锛夛紝瓒呴檺瑙嗕负鍗忚閿欒</summary>
+        public const int MaxFrameBytes = 1024 * 1024;
+
+        private static readonly JsonSerializerOptions JsonOpts = new JsonSerializerOptions
+        {
+            PropertyNameCaseInsensitive = true,
+            DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
+        };
+
+        // ==================== 甯х紪瑙g爜 ====================
+
+        /// <summary>缂栫爜涓轰竴甯э細[4 瀛楄妭澶х闀垮害][UTF8 JSON]</summary>
+        public static byte[] EncodeFrame(string json)
+        {
+            var payload = Encoding.UTF8.GetBytes(json);
+            if (payload.Length > MaxFrameBytes)
+                throw new InvalidOperationException($"甯ц秴闄�: {payload.Length} > {MaxFrameBytes}");
+            var frame = new byte[4 + payload.Length];
+            BinaryPrimitives.WriteInt32BigEndian(frame.AsSpan(), payload.Length);
+            payload.CopyTo(frame, 4);
+            return frame;
+        }
+
+        /// <summary>浠� payload JSON 瑙g爜灏佸銆傞潪娉� JSON 鎶� FormatException銆�</summary>
+        public static IpcEnvelope DecodeEnvelope(string payloadJson)
+        {
+            var env = JsonSerializer.Deserialize<IpcEnvelope>(payloadJson, JsonOpts);
+            if (env == null || string.IsNullOrEmpty(env.MessageType))
+                throw new FormatException("鏃犳晥 IPC 灏佸");
+            return env;
+        }
+
+        public static string EncodeEnvelope(IpcEnvelope env)
+            => JsonSerializer.Serialize(env, JsonOpts);
+
+        // ==================== 绾挎牸寮� DTO ====================
+
+        /// <summary>SubmitTask Body锛氫竴娆℃湁鐣岃澶囧姩浣滐紙OneShot 鍚屾妯″瀷锛�</summary>
+        public sealed class SubmitBody
+        {
+            public string DeviceId { get; set; } = "";
+            /// <summary>鐧藉悕鍗曟搷浣滅爜锛欳ONNECT/DISCONNECT/SEND/QUERY/STATUS</summary>
+            public string OperationCode { get; set; } = "";
+            /// <summary>鎿嶄綔杞借嵎锛堝懡浠ゆ垨鏌ヨ瀛楃涓诧級</summary>
+            public string Payload { get; set; } = "";
+            /// <summary>浠茶璧勬簮閿紙broker 渚� fence 鍐嶆牎楠岀敤锛屽 CAN-003:Generic锛�</summary>
+            public string ResourceKey { get; set; } = "";
+            /// <summary>瀹㈡埛绔繘绋嬪疄渚嬭韩浠� boot+pid锛屼笌 arb.db owner 瀵归綈</summary>
+            public string ClientInstanceId { get; set; } = "";
+        }
+
+        /// <summary>SubmitTask 鍝嶅簲 Body</summary>
+        public sealed class ResultBody
+        {
+            public string State { get; set; } = "";      // Succeeded/Failed/RejectedStaleLease/RejectedConfigMismatch/...
+            public string ErrorCode { get; set; } = "";
+            public string Readback { get; set; } = "";
+            public long ServerEpoch { get; set; }
+        }
+
+        public static string SerializeBody(object body)
+            => JsonSerializer.Serialize(body, JsonOpts);
+
+        public static T? DeserializeBody<T>(string json) where T : class
+        {
+            if (string.IsNullOrWhiteSpace(json)) return default;
+            try { return JsonSerializer.Deserialize<T>(json, JsonOpts); }
+            catch (JsonException) { return default; }
+        }
+
+        /// <summary>deadline 璁$畻锛歎TC 姣</summary>
+        public static long NowUtcMs()
+            => DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+    }
+}

--
Gitblit v1.9.1