Files
Ayay/SHH.MjpegPlayer/Core/Extensions/NetHttpExtension.cs

120 lines
4.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Ayay.SerilogLogs;
using Newtonsoft.Json;
using Serilog;
using System.Text;
namespace SHH.MjpegPlayer;
/// <summary>
/// 扩展 HttpClient 的 PostJson 方法,用于发送 JSON 格式的数据
/// </summary>
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, 使)
/// <summary>
/// 发送 JSON 格式的 POST 请求 (同步)
/// </summary>
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;
}
}
/// <summary>
/// 发送 JSON 格式的 POST 请求并反序列化 (同步)
/// </summary>
public static T? PostJson<T>(this object jsonData, string url, int timeout = 2000)
{
try
{
var msg = PostJson(jsonData, url, timeout);
return string.IsNullOrWhiteSpace(msg) ? default : JsonConvert.DeserializeObject<T>(msg);
}
catch (Exception ex)
{
_sysLog.Error(ex, "Post 同步请求并解析 JSON 异常: {Url}", url);
return default;
}
}
#endregion
#region (使)
/// <summary>
/// 发送 JSON 格式的 POST 请求 (异步)
/// </summary>
/// <param name="jsonData">要发送的对象</param>
/// <param name="url">目标地址</param>
/// <param name="timeout">超时(ms)</param>
public static async Task<string> 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;
}
}
/// <summary>
/// 发送 JSON 格式的 POST 请求并反序列化 (异步)
/// </summary>
public static async Task<T?> PostJsonAsync<T>(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<T>(result);
}
catch (Exception ex)
{
_sysLog.Error(ex, "Post 异步请求解析 JSON 失败: {Url}", url);
return default;
}
}
#endregion
}