Sfoglia il codice sorgente

feat(d2-02): ControlHttpServer 加 /debug/acquire|command|release|heartbeat 路由

huangjie 1 giorno fa
parent
commit
7c4393315b

+ 53 - 1
ivf_tl_operate_2.0/control/ivf_tl_ControlHost/ControlHttpServer.cs

@@ -6,6 +6,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
+using IvfTl.ControlHost.Debug;
 
 namespace IvfTl.ControlHost
 {
@@ -22,6 +23,7 @@ namespace IvfTl.ControlHost
         private readonly Func<int, bool> _serialPauseHandler;  // /serial/pause(借串口:control 让路该舱)
         private readonly Func<int, bool> _serialResumeHandler; // /serial/resume(归还:恢复采集)
         private readonly Action<string> _log;
+        private readonly DebugSessionManager _debug;
         private HttpListener _listener;
         private CancellationTokenSource _cts;
 
@@ -32,7 +34,8 @@ namespace IvfTl.ControlHost
             Func<string, bool> shutdownHandler,
             Func<int, bool> serialPauseHandler,
             Func<int, bool> serialResumeHandler,
-            Action<string> log)
+            Action<string> log,
+            DebugSessionManager debug = null)
         {
             _port = port;
             _pingProvider = pingProvider;
@@ -41,6 +44,7 @@ namespace IvfTl.ControlHost
             _serialPauseHandler = serialPauseHandler;
             _serialResumeHandler = serialResumeHandler;
             _log = log ?? (_ => { });
+            _debug = debug;
         }
 
         public void Start()
@@ -101,6 +105,40 @@ namespace IvfTl.ControlHost
                         body = "{\"ok\":" + (ok ? "true" : "false") + ",\"houseSn\":" + houseSn + (ok ? "" : ",\"error\":\"bad houseSn or handler\"") + "}";
                     }
                     break;
+                case "/debug/acquire":
+                    if (method != "POST") { code = 405; body = Err("method not allowed"); break; }
+                    {
+                        int houseSn = ReadIntField(ctx, "houseSn");
+                        var r = _debug != null ? _debug.Acquire(houseSn) : DebugCommandResult.Fail("NO_HANDLE", "debug 未装配");
+                        code = r.Ok ? 200 : 409; body = JsonConvert.SerializeObject(r);
+                    }
+                    break;
+                case "/debug/heartbeat":
+                    if (method != "POST") { code = 405; body = Err("method not allowed"); break; }
+                    {
+                        var r = _debug != null ? _debug.Heartbeat(ReadField(ctx, "sessionId")) : DebugCommandResult.Fail("SESSION_EXPIRED", "debug 未装配");
+                        code = r.Ok ? 200 : 410; body = JsonConvert.SerializeObject(r);
+                    }
+                    break;
+                case "/debug/release":
+                    if (method != "POST") { code = 405; body = Err("method not allowed"); break; }
+                    {
+                        var r = _debug != null ? _debug.Release(ReadField(ctx, "sessionId")) : DebugCommandResult.Okay();
+                        code = 200; body = JsonConvert.SerializeObject(r);
+                    }
+                    break;
+                case "/debug/command":
+                    if (method != "POST") { code = 405; body = Err("method not allowed"); break; }
+                    {
+                        var jo = ReadBody(ctx);
+                        string sid = jo?["sessionId"]?.ToString();
+                        string op = jo?["op"]?.ToString();
+                        var argsObj = jo?["args"] as Newtonsoft.Json.Linq.JObject;
+                        var r = _debug != null ? _debug.Execute(sid, op, argsObj) : DebugCommandResult.Fail("SESSION_EXPIRED", "debug 未装配");
+                        code = r.Ok ? 200 : (r.Code == "SESSION_EXPIRED" ? 410 : (r.Code == "OUT_OF_RANGE" ? 400 : 200));
+                        body = JsonConvert.SerializeObject(r);
+                    }
+                    break;
                 default:
                     code = 404; body = Err("not found");
                     break;
@@ -137,6 +175,20 @@ namespace IvfTl.ControlHost
             return int.TryParse(s, out int v) ? v : -1;
         }
 
+        /// <summary>把 POST body 整体解析为 JObject(失败返回 null)。/debug/command 多字段用。</summary>
+        private Newtonsoft.Json.Linq.JObject ReadBody(HttpListenerContext ctx)
+        {
+            try
+            {
+                using (var sr = new StreamReader(ctx.Request.InputStream, ctx.Request.ContentEncoding ?? Encoding.UTF8))
+                {
+                    string raw = sr.ReadToEnd();
+                    return string.IsNullOrEmpty(raw) ? null : Newtonsoft.Json.Linq.JObject.Parse(raw);
+                }
+            }
+            catch (Exception ex) { _log("解析 body 异常:" + ex.Message); return null; }
+        }
+
         public void Stop()
         {
             try { _cts?.Cancel(); _listener?.Stop(); _listener?.Close(); }