using Ayay.SerilogLogs; using Newtonsoft.Json; using Serilog; using System.Text; namespace SHH.MjpegPlayer; /// /// 扩展 HttpClient 的 PostJson 方法,用于发送 JSON 格式的数据 /// public static class NetHttpExtension { // Optimized: 统一日志对象 private static readonly ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); // Optimized: 使用静态单例 HttpClient 防止套接字耗尽。注意:生产环境建议配合 SocketsHttpHandler private static readonly HttpClient _httpClient = new HttpClient(); #region 同步方法 (Sync-over-Async, 谨慎使用) /// /// 发送 JSON 格式的 POST 请求 (同步) /// public static string PostJson(this object jsonData, string url, int timeout = 2000) { try { // Optimized: 显式调用异步版本并等待,注意在某些上下文可能死锁 return PostJsonAsync(jsonData, url, timeout).GetAwaiter().GetResult(); } catch (Exception ex) { _sysLog.Error(ex, "Post 同步请求异常: {Url}", url); return string.Empty; } } /// /// 发送 JSON 格式的 POST 请求并反序列化 (同步) /// public static T? PostJson(this object jsonData, string url, int timeout = 2000) { try { var msg = PostJson(jsonData, url, timeout); return string.IsNullOrWhiteSpace(msg) ? default : JsonConvert.DeserializeObject(msg); } catch (Exception ex) { _sysLog.Error(ex, "Post 同步请求并解析 JSON 异常: {Url}", url); return default; } } #endregion #region 异步方法 (推荐使用) /// /// 发送 JSON 格式的 POST 请求 (异步) /// /// 要发送的对象 /// 目标地址 /// 超时(ms) public static async Task PostJsonAsync(this object jsonData, string url, int timeout = 2000) { string jsonString = string.Empty; try { // Optimized: 序列化处理 jsonString = jsonData is string s ? s : JsonConvert.SerializeObject(jsonData); using var content = new StringContent(jsonString, Encoding.UTF8, "application/json"); // Optimized: 设置请求级别的超时处理(HttpClient.Timeout 是全局的,此处利用 CancellationTokenSource) using var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(timeout)); var response = await _httpClient.PostAsync(url, content, cts.Token); if (response.IsSuccessStatusCode) { return await response.Content.ReadAsStringAsync(); } _sysLog.Warning("Post 请求状态异常: {Url}, StatusCode: {Code}", url, response.StatusCode); return string.Empty; } catch (OperationCanceledException) { _sysLog.Warning("Post 请求超时: {Url}, Timeout: {Timeout}ms", url, timeout); return string.Empty; } catch (Exception ex) { // Modified: 使用结构化日志记录错误 _sysLog.Error(ex, "Post 异步请求发生故障: {Url}", url); return string.Empty; } } /// /// 发送 JSON 格式的 POST 请求并反序列化 (异步) /// public static async Task PostJsonAsync(this object jsonData, string url, int timeout = 2000) { try { var result = await PostJsonAsync(jsonData, url, timeout); if (string.IsNullOrWhiteSpace(result)) return default; return JsonConvert.DeserializeObject(result); } catch (Exception ex) { _sysLog.Error(ex, "Post 异步请求解析 JSON 失败: {Url}", url); return default; } } #endregion }