main
wanggaofeng 12 months ago
parent a7ce33dd5f
commit 0786050265

@ -0,0 +1,92 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
}
},
"source": [
"## HttpClient 概述"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 作用"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## 整体理解"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 前世今生"
]
},
{
"cell_type": "markdown",
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
},
"vscode": {
"languageId": "polyglot-notebook"
}
},
"source": [
"## 架构图"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 相关资源"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"name": "python"
},
"polyglot_notebook": {
"kernelInfo": {
"defaultKernelName": "csharp",
"items": [
{
"aliases": [],
"name": "csharp"
}
]
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}

@ -0,0 +1,58 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
}
},
"source": [
"# HttpClient 使用原则"
]
},
{
"cell_type": "markdown",
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
},
"vscode": {
"languageId": "polyglot-notebook"
}
},
"source": [
"## 1、复用"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"name": "python"
},
"polyglot_notebook": {
"kernelInfo": {
"defaultKernelName": "csharp",
"items": [
{
"aliases": [],
"name": "csharp"
}
]
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}

@ -11,6 +11,7 @@ global using System.Net.Http;
global using System.Net.Http.Json; global using System.Net.Http.Json;
global using System.Net.Http.Headers; global using System.Net.Http.Headers;
global using HttpClientStudy.Config;
global using HttpClientStudy.Model; global using HttpClientStudy.Model;
global using HttpClientStudy.Core; global using HttpClientStudy.Core;

@ -3,7 +3,7 @@
/// <summary> /// <summary>
/// 简单 HttpClient 包装类 /// 简单 HttpClient 包装类
/// </summary> /// </summary>
public class SimpleHttpClient public class BaseHttpClient
{ {
#region Get请求 #region Get请求
public string Get(string url) public string Get(string url)

@ -30,11 +30,11 @@ namespace HttpClientStudy.Core
/// </list> /// </list>
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// 简化处理 /// 错误处理
/// </remarks> /// </remarks>
public class HttpError public class HttpError
{ {
// 定义一个 HttpClient 实例,共享 // 定义一个 HttpClient 共享实例
public static HttpClient HttpClient = new HttpClient(new SocketsHttpHandler() { PooledConnectionLifetime = TimeSpan.FromMinutes(1) }) public static HttpClient HttpClient = new HttpClient(new SocketsHttpHandler() { PooledConnectionLifetime = TimeSpan.FromMinutes(1) })
{ {
BaseAddress = new Uri(WebApiConfigManager.GetWebApiConfig().BaseUrl) BaseAddress = new Uri(WebApiConfigManager.GetWebApiConfig().BaseUrl)
@ -61,7 +61,6 @@ namespace HttpClientStudy.Core
{ {
var response = await HttpClient.GetAsync("http://localhost:30"); var response = await HttpClient.GetAsync("http://localhost:30");
} }
catch (Exception ex) catch (Exception ex)
{ {
// 捕获异常,处理 // 捕获异常,处理

@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HttpClientStudy.Core.Utils
{
/// <summary>
/// 启动工具类
/// </summary>
public static class StartupUtility
{
/// <summary>
/// 启动webapi项目
/// (出现webapi项目启动命令行窗口)
/// </summary>
public static void StartWebApiProject()
{
string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName;
//webapi项目不在运行状态则启动webapi项目
if (webAppIsRunningByMutex() == false)
{
//VS项目根目录
string vsProjectPath = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory)!.Parent!.Parent!.Parent!.Parent!.FullName;
//webapi项目根项目
string webApiProjectPath = Path.Combine(vsProjectPath, projectAndMutexName);
//启动命令信息
var prossInfo = new System.Diagnostics.ProcessStartInfo("dotnet", $"run --project {webApiProjectPath}")
{
UseShellExecute = true,
CreateNoWindow = false,
RedirectStandardOutput = false
};
//启动
System.Diagnostics.Process.Start(prossInfo);
}
//由进程名判断
//bool webAppIsRunningByProcessName()
//{
// return Process.GetProcessesByName(projectAndMutexName).ToList().Count == 0;
//}
//由互斥锁判断
bool webAppIsRunningByMutex()
{
bool createdResult = true;
//创建互斥锁
using (var mutex = new Mutex(true, projectAndMutexName, out createdResult))
{
if (createdResult)
{
mutex.ReleaseMutex();
}
}
//互斥锁是否创建成功
return !createdResult;
}
}
/// <summary>
/// 关闭webapi项目
/// (出现webapi项目启动命令行窗口)
/// </summary>
public static void ExitWebApiProject()
{
string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName;
//webapi为运行状态则关闭
if (webAppIsRunningByMutex())
{
var webApiProcess = System.Diagnostics.Process.GetProcessesByName(projectAndMutexName);
if (webApiProcess != null && webApiProcess.Length>0)
{
webApiProcess[0].Kill();
}
}
//由进程名判断
//bool webAppIsRunningByProcessName()
//{
// return Process.GetProcessesByName(projectAndMutexName).ToList().Count == 0;
//}
//由互斥锁判断
bool webAppIsRunningByMutex()
{
bool createdResult = true;
//创建互斥锁
using (var mutex = new Mutex(true, projectAndMutexName, out createdResult))
{
if (createdResult)
{
mutex.ReleaseMutex();
}
}
//互斥锁是否创建成功
return !createdResult;
}
}
}
}

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HttpClientStudy.UnitTest.Fixtures
{
[CollectionDefinition("App")]
public class AppCollectionFixture : ICollectionFixture<AppFixture>
{
}
}

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HttpClientStudy.UnitTest.Fixtures
{
public class AppFixture : IDisposable
{
public AppFixture()
{
}
public void Dispose()
{
}
}
}

@ -43,8 +43,4 @@
<ProjectReference Include="..\HttpClientStudy.WebApp\HttpClientStudy.WebApp.csproj" /> <ProjectReference Include="..\HttpClientStudy.WebApp\HttpClientStudy.WebApp.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="HttpRequests\" />
</ItemGroup>
</Project> </Project>

@ -3,10 +3,10 @@
/// <summary> /// <summary>
/// SimpleHttpClient 测试类 /// SimpleHttpClient 测试类
/// </summary> /// </summary>
public class SimpleHttpClientTest public class BaseHttpClientTest
{ {
private readonly ITestOutputHelper _logger; private readonly ITestOutputHelper _logger;
public SimpleHttpClientTest(ITestOutputHelper outputHelper) public BaseHttpClientTest(ITestOutputHelper outputHelper)
{ {
_logger = outputHelper; _logger = outputHelper;
} }
@ -14,7 +14,7 @@
[Fact] [Fact]
public void Get_Test() public void Get_Test()
{ {
SimpleHttpClient client = new SimpleHttpClient(); BaseHttpClient client = new BaseHttpClient();
var result = client.Get(WebApiConfigManager.GetWebApiConfig().BaseUrl + "/api/Simple/GetAccount"); var result = client.Get(WebApiConfigManager.GetWebApiConfig().BaseUrl + "/api/Simple/GetAccount");
@ -25,7 +25,7 @@
[Fact] [Fact]
public void GetJson_Test() public void GetJson_Test()
{ {
SimpleHttpClient client = new SimpleHttpClient(); BaseHttpClient client = new BaseHttpClient();
var result = client.GetJson<BaseResult<string>>(WebApiConfigManager.GetWebApiConfig().BaseUrl + "/api/Simple/GetAccount"); var result = client.GetJson<BaseResult<string>>(WebApiConfigManager.GetWebApiConfig().BaseUrl + "/api/Simple/GetAccount");

@ -24,14 +24,6 @@ namespace HttpClientStudy.UnitTest.HttpResponses
client.PostAsync("http://www.baidu.com", content); client.PostAsync("http://www.baidu.com", content);
} }
[Fact]
public async void Test2()
{
HttpClient client = new HttpClient();
var dd = await client.PostAsJsonAsync("url", new { Name = "" }, CancellationToken.None);
}
} }
public class Demo public class Demo

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace HttpClientStudy.UnitTest
{
public class StartupTest
{
[Fact]
public void StartWebApiProject()
{
}
}
}

@ -1,5 +1,7 @@
using System.Diagnostics; using System.Diagnostics;
using HttpClientStudy.Core.Utils;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@ -41,15 +43,15 @@ namespace HttpClientStudy.UnitTest
public void ConfigureHost(IHostBuilder hostBuilder) public void ConfigureHost(IHostBuilder hostBuilder)
{ {
//确保启动 webapi 项目 //确保启动 webapi 项目
StartWebApiProject(); StartupUtility.StartWebApiProject();
hostBuilder hostBuilder
//主机配置 //主机配置设置
.ConfigureHostConfiguration(builder => .ConfigureHostConfiguration(builder =>
{ {
}) })
//应用配置 //应用配置设置
.ConfigureAppConfiguration((context, builder) => .ConfigureAppConfiguration((context, builder) =>
{ {
@ -65,21 +67,16 @@ namespace HttpClientStudy.UnitTest
}) })
.ConfigureTestServices(a => .ConfigureTestServices(a =>
{ {
Console.WriteLine("+++++++++++++++++++++++++++++++++");
a.BuildServiceProvider().GetRequiredService<IHostApplicationLifetime>().ApplicationStopping.Register(() =>
{
Console.WriteLine("=========================");
});
}) })
.UseStartup<WebApiStartup>(); .UseStartup<WebApiStartup>()
;
//配置默认配置项
//webHostBuilder.ConfigureAppConfiguration((context, configBuilder) =>
//{
// configBuilder.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
// configBuilder.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
//});
//webHostBuilder.ConfigureServices(services =>
//{
// services.AddHealthChecks();
//});
}); });
} }
@ -89,62 +86,10 @@ namespace HttpClientStudy.UnitTest
/// <param name="services"></param> /// <param name="services"></param>
public void ConfigureServices(IServiceCollection services, HostBuilderContext context) public void ConfigureServices(IServiceCollection services, HostBuilderContext context)
{ {
Debugger.Log(1, "DI", "ConfigureServices"); services.BuildServiceProvider().GetRequiredService<IHostApplicationLifetime>().ApplicationStopping.Register(() =>
}
/// <summary>
/// 启动webapi项目
/// (出现webapi项目启动命令行窗口)
/// </summary>
private void StartWebApiProject()
{
string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName;
//webapi项目不在运行状态则启动webapi项目
if (webAppIsRunningByMutex() == false)
{
//VS项目根目录
string vsProjectPath = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory)!.Parent!.Parent!.Parent!.Parent!.FullName;
//webapi项目根项目
string webApiProjectPath = Path.Combine(vsProjectPath, projectAndMutexName);
//启动命令信息
var prossInfo = new ProcessStartInfo("dotnet", $"run --project {webApiProjectPath}")
{
UseShellExecute = true,
CreateNoWindow = false,
RedirectStandardOutput = false
};
//启动
Process.Start(prossInfo);
}
//由进程名判断
//bool webAppIsRunningByProcessName()
//{
// return Process.GetProcessesByName(projectAndMutexName).ToList().Count == 0;
//}
//由互斥锁判断
bool webAppIsRunningByMutex()
{
bool createdResult = true;
//创建互斥锁
using (var mutex = new Mutex(true, projectAndMutexName, out createdResult))
{
if (createdResult)
{ {
mutex.ReleaseMutex(); Console.WriteLine("=========================");
} });
}
//互斥锁是否创建成功
return !createdResult;
}
} }
private class WebApiStartup private class WebApiStartup
@ -156,7 +101,7 @@ namespace HttpClientStudy.UnitTest
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)
{ {
app.Run(static context => context.Response.WriteAsync("xxxxxx"));
} }
} }
} }

@ -1,3 +1,7 @@
using System.Diagnostics;
using HttpClientStudy.Core.Utils;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
// Add services to the container. // Add services to the container.
@ -20,4 +24,36 @@ app.UseAuthorization();
app.MapControllers(); app.MapControllers();
Process currentProcess = Process.GetCurrentProcess();
currentProcess.EnableRaisingEvents = true;
currentProcess.Exited += (s, r) =>
{
Console.WriteLine("000000000000000000000000000000000000");
};
// 获取 IHostApplicationLifetime 实例
var applicationLifetime = app.Services.GetRequiredService<IHostApplicationLifetime>();
// 注册应用程序关闭事件
applicationLifetime.ApplicationStopping.Register(() =>
{
//关闭WebApi
StartupUtility.ExitWebApiProject();
});
applicationLifetime.ApplicationStopped.Register(() => {
Console.WriteLine("xxxxxxxxxxxxxxxxxxxx");
});
// 注册 AppDomain 的未处理异常事件
AppDomain.CurrentDomain.UnhandledException += (s,e)=>
{
Console.WriteLine("退出");
};
//确保启动WebApi程序
StartupUtility.StartWebApiProject();
app.Run(); app.Run();

Loading…
Cancel
Save