| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- using System;
- using System.Net;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using Newtonsoft.Json;
- namespace IvfTl.ControlHost
- {
- /// <summary>
- /// control 进程内的本地 HTTP 小服务,只监听 127.0.0.1:port。
- /// 阶段1:/ping、/status。阶段2 扩展 /serial/pause|resume、/shutdown。
- /// </summary>
- public class ControlHttpServer
- {
- private readonly int _port;
- private readonly Func<StatusDto> _statusProvider;
- private readonly Action<string> _log;
- private HttpListener _listener;
- private CancellationTokenSource _cts;
- public ControlHttpServer(int port, Func<StatusDto> statusProvider, Action<string> log)
- {
- _port = port;
- _statusProvider = statusProvider;
- _log = log ?? (_ => { });
- }
- public void Start()
- {
- _listener = new HttpListener();
- _listener.Prefixes.Add($"http://127.0.0.1:{_port}/");
- _listener.Start();
- _cts = new CancellationTokenSource();
- _log($"ControlHttpServer 监听 http://127.0.0.1:{_port}/");
- Task.Run(() => Loop(_cts.Token));
- }
- private async Task Loop(CancellationToken token)
- {
- while (!token.IsCancellationRequested)
- {
- HttpListenerContext ctx;
- try { ctx = await _listener.GetContextAsync(); }
- catch (Exception ex) { if (!token.IsCancellationRequested) _log("HttpListener 异常:" + ex.Message); break; }
- try { Handle(ctx); }
- catch (Exception ex) { _log("处理请求异常:" + ex.Message); }
- }
- }
- private void Handle(HttpListenerContext ctx)
- {
- string path = ctx.Request.Url.AbsolutePath.TrimEnd('/').ToLowerInvariant();
- string body;
- int code = 200;
- switch (path)
- {
- case "/ping":
- case "/status":
- body = JsonConvert.SerializeObject(_statusProvider());
- break;
- default:
- code = 404; body = "{\"ok\":false,\"error\":\"not found\"}";
- break;
- }
- byte[] buf = Encoding.UTF8.GetBytes(body);
- ctx.Response.StatusCode = code;
- ctx.Response.ContentType = "application/json";
- ctx.Response.ContentLength64 = buf.Length;
- ctx.Response.OutputStream.Write(buf, 0, buf.Length);
- ctx.Response.OutputStream.Close();
- }
- public void Stop()
- {
- try { _cts?.Cancel(); _listener?.Stop(); _listener?.Close(); }
- catch (Exception ex) { _log("ControlHttpServer 停止异常:" + ex.Message); }
- }
- }
- }
|