optimization request http

This commit is contained in:
Aigio Liu
2021-03-03 23:57:59 +08:00
parent 4024236000
commit ef8afedab1
18 changed files with 541 additions and 152 deletions
@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using System.Application.Services;
using System.Application.Services.Implementation;
using System.Application.UI;
@@ -15,7 +16,12 @@ namespace Microsoft.Extensions.DependencyInjection
/// <returns></returns>
public static IServiceCollection AddDesktopLogging(this IServiceCollection services)
{
services.AddLogging(AppHelper.Configure);
var (minLevel, cfg) = AppHelper.Configure();
services.AddLogging(cfg);
services.Configure<LoggerFilterOptions>(o =>
{
o.MinLevel = minLevel;
});
return services;
}
@@ -41,18 +47,6 @@ namespace Microsoft.Extensions.DependencyInjection
return services;
}
/// <summary>
/// 添加 通用 Http 服务
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddHttpService(this IServiceCollection services)
{
services.AddHttpClient(); // 添加 System.Net.Http.HttpClient / HttpClientFactory
services.AddSingleton<IHttpService, HttpServiceImpl>();
return services;
}
/// <summary>
/// 添加 Steam 相关助手、工具类服务
/// </summary>
@@ -1,21 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
namespace System.Application.Services
{
public interface IHttpService
{
public static IHttpService Instance => DI.Get<IHttpService>();
Task<T?> GetAsync<T>(string requestUri, CancellationToken cancellationToken = default) where T : notnull;
}
#if DEBUG
[Obsolete("use IHttpService.Instance", true)]
public class HttpServices
{
}
#endif
}
@@ -1,100 +0,0 @@
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace System.Application.Services.Implementation
{
internal sealed class HttpServiceImpl : HttpService, IHttpService
{
const string TAG = "HttpS";
const string Accept = MediaTypeNames.JSON;
readonly JsonSerializer jsonSerializer = new JsonSerializer();
public HttpServiceImpl(ILoggerFactory loggerFactory, IHttpPlatformHelper http_helper, IHttpClientFactory clientFactory) : base(loggerFactory.CreateLogger(TAG), http_helper, clientFactory)
{
}
public async Task<T?> GetAsync<T>(string requestUri, CancellationToken cancellationToken) where T : notnull
{
HttpRequestMessage? request = null;
HttpResponseMessage? response = null;
bool notDispose = false;
try
{
request = new HttpRequestMessage(HttpMethod.Get, requestUri);
request.Headers.Accept.ParseAdd(Accept);
request.Headers.UserAgent.ParseAdd(http_helper.UserAgent);
var client = CreateClient();
response = await client.SendAsync(request,
HttpCompletionOption.ResponseHeadersRead,
cancellationToken)
.ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
if (response.Content != null)
{
var rspContentClrType = typeof(T);
if (rspContentClrType == typeof(string))
{
return (T)(object)await response.Content.ReadAsStringAsync();
}
else if (rspContentClrType == typeof(byte[]))
{
return (T)(object)await response.Content.ReadAsByteArrayAsync();
}
else if (rspContentClrType == typeof(Stream))
{
notDispose = true;
return (T)(object)await response.Content.ReadAsStreamAsync();
}
var mime = response.Content.Headers.ContentType?.MediaType ?? Accept;
switch (mime)
{
case MediaTypeNames.JSON:
case MediaTypeNames.XML:
case MediaTypeNames.XML_APP:
{
using var stream = await response.Content
.ReadAsStreamAsync().ConfigureAwait(false);
using var reader = new StreamReader(stream, Encoding.UTF8);
switch (mime)
{
case MediaTypeNames.JSON:
{
using var json = new JsonTextReader(reader);
return jsonSerializer.Deserialize<T>(json);
}
case MediaTypeNames.XML:
case MediaTypeNames.XML_APP:
{
var xmlSerializer = new XmlSerializer(typeof(T));
return (T)xmlSerializer.Deserialize(reader);
}
}
}
break;
}
}
}
}
catch (Exception e)
{
Log.Error(TAG, e, "GetAsync Fail.");
}
finally
{
if (!notDispose)
{
request?.Dispose();
response?.Dispose();
}
}
return default;
}
}
}
@@ -76,15 +76,21 @@ namespace System.Application.UI
/// </summary>
static LoggerFilterOptions LoggerFilterOptions => DI.Get<IOptions<LoggerFilterOptions>>().Value;
internal static void Configure(ILoggingBuilder builder)
internal static (LogLevel minLevel, Action<ILoggingBuilder> cfg) Configure()
{
var logLevel = DefaultLoggerMinLevel;
builder.SetMinimumLevel(logLevel);
SetNLoggerMinLevel(logLevel);
var minLevel = DefaultLoggerMinLevel;
// 可以多个日志提供同时用,比如还可以在 Win 平台再添加一个 Windows 事件日志
Action<ILoggingBuilder> cfg = builder =>
{
builder.SetMinimumLevel(minLevel);
SetNLoggerMinLevel(minLevel);
builder.AddNLog(); // 添加 NLog 日志
// 可以多个日志提供同时用,比如还可以在 Win 平台再添加一个 Windows 事件日志
builder.AddNLog(); // 添加 NLog 日志
};
return (minLevel, cfg);
}
/// <summary>
@@ -4,7 +4,6 @@ using System.Application.Services;
using System.Application.UI.Resx;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
@@ -32,11 +31,10 @@ namespace System.Application.UI.ViewModels
set => this.RaiseAndSetIfChanged(ref _steamUsers, value);
}
internal async override Task Initialize()
{
SteamUsers = new ObservableCollection<SteamUser>(steamService.GetRememberUserList());
if (SteamUsers == null || SteamUsers.Count < 1)
if (!SteamUsers.Any_Nullable())
{
return;
}
@@ -55,9 +53,9 @@ namespace System.Application.UI.ViewModels
users[i].WantsOfflineMode = temp.WantsOfflineMode;
users[i].SkipOfflineModeWarning = temp.SkipOfflineModeWarning;
users[i].OriginVdfString = temp.OriginVdfString;
users[i].AvatarMediumStream = string.IsNullOrEmpty(users[i].AvatarMedium) ? null : await httpService.GetAsync<Stream>(users[i].AvatarMedium);
users[i].AvatarMediumStream = string.IsNullOrEmpty(users[i].AvatarMedium) ? null : await httpService.GetImageAsync(users[i].AvatarMedium, ImageChannelType.SteamAvatars);
}
SteamUsers = new ObservableCollection<SteamUser>(users.OrderByDescending(o => o.RememberPassword).ThenByDescending(o => o.LastLoginTime).ToList());
}
}
}
}