| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net.Http;
- using System.Text;
- using System.Threading.Tasks;
- using Newtonsoft.Json;
- namespace ivf_tl_Operate.Debug
- {
- /// <summary>
- /// operate 端"16 孔标定协作"客户端:封装 control 的 /debug/calibrate/* 四端点(start/progress/recalibrate/stop)
- /// + 轮询进度。复用 operate 已借到的 sessionId(由 DebugSessionClient.Acquire 取得),全程同一会话。
- /// 纯逻辑可单测:HttpClient 可注入(测试用 FakeHandler);http=null 则自建并自 Dispose(对齐 DebugSessionClient)。
- /// start/recalibrate/stop 返回 AcquireResult(对齐 control DebugCommandResult:Ok/Result/Error/Code);
- /// progress 返回 CalibProgressDto(从 DebugCommandResult.result 内嵌对象反序列化)。
- /// 实时画面复用 MjpegStreamClient(不在本类)。
- /// </summary>
- public sealed class CalibrationClient : IDisposable
- {
- private readonly string _baseUrl;
- private readonly string _sessionId;
- private readonly HttpClient _http;
- private readonly bool _ownsHttp;
- public CalibrationClient(string baseUrl, string sessionId, HttpClient http = null)
- {
- _baseUrl = baseUrl.TrimEnd('/');
- _sessionId = sessionId;
- _ownsHttp = http == null; // 自建的由本类 Dispose;注入的归调用方
- _http = http ?? new HttpClient();
- }
- // /progress 的 result 内嵌 CalibProgress,用 envelope 把外层 ok/code 与内层 result 一并取出。
- private sealed class ProgressEnvelope
- {
- [JsonProperty("ok")] public bool Ok { get; set; }
- [JsonProperty("code")] public string Code { get; set; }
- [JsonProperty("error")] public string Error { get; set; }
- [JsonProperty("result")] public CalibProgressDto Result { get; set; }
- }
- private async Task<AcquireResult> PostAsync(string path, object body)
- {
- var content = new StringContent(body == null ? "{}" : JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json");
- var resp = await _http.PostAsync($"{_baseUrl}{path}", content);
- string s = await resp.Content.ReadAsStringAsync();
- return JsonConvert.DeserializeObject<AcquireResult>(s) ?? new AcquireResult { Ok = false, Error = "空响应" };
- }
- /// <summary>起一次 16 孔标定。wells 为空则 control 端默认 1..16。</summary>
- public Task<AcquireResult> StartAsync(IEnumerable<int> wells = null)
- => PostAsync("/debug/calibrate/start", new { sessionId = _sessionId, wells = wells?.ToArray() });
- /// <summary>轮询进度:返回 CalibProgressDto(无进度/会话失效则返回 null)。</summary>
- public async Task<CalibProgressDto> PollProgressAsync()
- {
- var content = new StringContent(JsonConvert.SerializeObject(new { sessionId = _sessionId }), Encoding.UTF8, "application/json");
- var resp = await _http.PostAsync($"{_baseUrl}/debug/calibrate/progress", content);
- string s = await resp.Content.ReadAsStringAsync();
- var env = JsonConvert.DeserializeObject<ProgressEnvelope>(s);
- return env?.Result; // ok=false(SESSION_EXPIRED 等)时 result 缺省 → null
- }
- /// <summary>单孔重标。</summary>
- public Task<AcquireResult> RecalibrateAsync(int wellSn)
- => PostAsync("/debug/calibrate/recalibrate", new { sessionId = _sessionId, wellSn });
- /// <summary>中止标定。</summary>
- public Task<AcquireResult> StopAsync()
- => PostAsync("/debug/calibrate/stop", new { sessionId = _sessionId });
- public void Dispose()
- {
- if (_ownsHttp) { try { _http?.Dispose(); } catch { } } // 只释放自建的;注入的归调用方
- }
- }
- }
|