XFEExtension.NetCore.ServerInteractive
[DLL] Server interaction extension, including user identity verification and querying in conjunction with AutoConfig
关注
0
Fork
0
Star
0
using System.Diagnostics;
using System.Net;
using System.Text;
using System.Text.Json;
namespace XFEExtension.NetCore.ServerInteractive.Utilities.Helpers;
/// <summary>服务器交互帮助类。</summary>
public static class InteractiveHelper
{
private const int DefaultMaxResponseBytes = 8 * 1024 * 1024;
private static readonly HttpClient s_client = new() { Timeout = Timeout.InfiniteTimeSpan };
public static Task<(string, HttpStatusCode)> GetServerResponse(string requestAddress, string postBody)
=> GetServerResponse(new Uri(requestAddress, UriKind.Absolute), postBody, CancellationToken.None);
public static async Task<(string, HttpStatusCode)> GetServerResponse(Uri requestAddress, string postBody,
CancellationToken cancellationToken, TimeSpan? timeout = null, int maxResponseBytes = DefaultMaxResponseBytes)
{
using var timeoutSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
timeoutSource.CancelAfter(timeout ?? TimeSpan.FromSeconds(30));
using var content = new StringContent(postBody, Encoding.UTF8, "application/json");
using var response = await s_client.PostAsync(requestAddress, content, timeoutSource.Token).ConfigureAwait(false);
await using var stream = await response.Content.ReadAsStreamAsync(timeoutSource.Token).ConfigureAwait(false);
using var output = new MemoryStream();
var buffer = new byte[16 * 1024];
while (true)
{
var count = await stream.ReadAsync(buffer, timeoutSource.Token).ConfigureAwait(false);
if (count == 0) break;
if (output.Length + count > maxResponseBytes)
throw new HttpRequestException($"服务器响应超过 {maxResponseBytes} 字节限制");
await output.WriteAsync(buffer.AsMemory(0, count), timeoutSource.Token).ConfigureAwait(false);
}
return (Encoding.UTF8.GetString(output.GetBuffer(), 0, checked((int)output.Length)), response.StatusCode);
}
public static Task<(string, HttpStatusCode)> GetServerResponse(string requestAddress, object postBody, JsonSerializerOptions jsonSerializerOptions)
=> GetServerResponse(new Uri(requestAddress, UriKind.Absolute), JsonSerializer.Serialize(postBody, jsonSerializerOptions), CancellationToken.None);
public static Task<(string, HttpStatusCode)> GetServerResponse(Uri requestAddress, object postBody,
JsonSerializerOptions jsonSerializerOptions, CancellationToken cancellationToken)
=> GetServerResponse(requestAddress, JsonSerializer.Serialize(postBody, jsonSerializerOptions), cancellationToken);
public static Uri BuildRequestUri(string baseAddress, string route)
{
ArgumentException.ThrowIfNullOrWhiteSpace(baseAddress);
ArgumentException.ThrowIfNullOrWhiteSpace(route);
var normalizedBase = baseAddress.EndsWith('/') ? baseAddress : $"{baseAddress}/";
return new Uri(new Uri(normalizedBase, UriKind.Absolute), route.TrimStart('/'));
}
public static string GetStopWatchTime(Stopwatch stopwatch)
{
if (stopwatch.Elapsed.TotalSeconds > 1) return $"{stopwatch.Elapsed.TotalSeconds:F1} s";
if (stopwatch.Elapsed.TotalMilliseconds > 1) return $"{stopwatch.Elapsed.TotalMilliseconds:F1} ms";
return stopwatch.Elapsed.TotalMicroseconds > 1
? $"{stopwatch.Elapsed.TotalMicroseconds:F1} μs"
: $"{stopwatch.Elapsed.TotalNanoseconds:F1} ns";
}
}
using System.Diagnostics;
using System.Net;
using System.Text;
using System.Text.Json;
namespace XFEExtension.NetCore.ServerInteractive.Utilities.Helpers;
/// <summary>服务器交互帮助类。</summary>
public static class InteractiveHelper
{
private const int DefaultMaxResponseBytes = 8 * 1024 * 1024;
private static readonly HttpClient s_client = new() { Timeout = Timeout.InfiniteTimeSpan };
public static Task<(string, HttpStatusCode)> GetServerResponse(string requestAddress, string postBody)
=> GetServerResponse(new Uri(requestAddress, UriKind.Absolute), postBody, CancellationToken.None);
public static async Task<(string, HttpStatusCode)> GetServerResponse(Uri requestAddress, string postBody,
CancellationToken cancellationToken, TimeSpan? timeout = null, int maxResponseBytes = DefaultMaxResponseBytes)
{
using var timeoutSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
timeoutSource.CancelAfter(timeout ?? TimeSpan.FromSeconds(30));
using var content = new StringContent(postBody, Encoding.UTF8, "application/json");
using var response = await s_client.PostAsync(requestAddress, content, timeoutSource.Token).ConfigureAwait(false);
await using var stream = await response.Content.ReadAsStreamAsync(timeoutSource.Token).ConfigureAwait(false);
using var output = new MemoryStream();
var buffer = new byte[16 * 1024];
while (true)
{
var count = await stream.ReadAsync(buffer, timeoutSource.Token).ConfigureAwait(false);
if (count == 0) break;
if (output.Length + count > maxResponseBytes)
throw new HttpRequestException($"服务器响应超过 {maxResponseBytes} 字节限制");
await output.WriteAsync(buffer.AsMemory(0, count), timeoutSource.Token).ConfigureAwait(false);
}
return (Encoding.UTF8.GetString(output.GetBuffer(), 0, checked((int)output.Length)), response.StatusCode);
}
public static Task<(string, HttpStatusCode)> GetServerResponse(string requestAddress, object postBody, JsonSerializerOptions jsonSerializerOptions)
=> GetServerResponse(new Uri(requestAddress, UriKind.Absolute), JsonSerializer.Serialize(postBody, jsonSerializerOptions), CancellationToken.None);
public static Task<(string, HttpStatusCode)> GetServerResponse(Uri requestAddress, object postBody,
JsonSerializerOptions jsonSerializerOptions, CancellationToken cancellationToken)
=> GetServerResponse(requestAddress, JsonSerializer.Serialize(postBody, jsonSerializerOptions), cancellationToken);
public static Uri BuildRequestUri(string baseAddress, string route)
{
ArgumentException.ThrowIfNullOrWhiteSpace(baseAddress);
ArgumentException.ThrowIfNullOrWhiteSpace(route);
var normalizedBase = baseAddress.EndsWith('/') ? baseAddress : $"{baseAddress}/";
return new Uri(new Uri(normalizedBase, UriKind.Absolute), route.TrimStart('/'));
}
public static string GetStopWatchTime(Stopwatch stopwatch)
{
if (stopwatch.Elapsed.TotalSeconds > 1) return $"{stopwatch.Elapsed.TotalSeconds:F1} s";
if (stopwatch.Elapsed.TotalMilliseconds > 1) return $"{stopwatch.Elapsed.TotalMilliseconds:F1} ms";
return stopwatch.Elapsed.TotalMicroseconds > 1
? $"{stopwatch.Elapsed.TotalMicroseconds:F1} μs"
: $"{stopwatch.Elapsed.TotalNanoseconds:F1} ns";
}
}