HttpClient - DNS changes are NOT honoured(HttpClient-不支持对DNS的更改)
问题描述
我已经阅读了一些文章以及使用静态HttpClient的陷阱和解决方案。其中一篇文章是-http://byterot.blogspot.ca/2016/07/singleton-httpclient-dns.html
我已经实现了解决方案,并希望进行测试以确保本文提出的内容能够实际工作。
以下是我们试图避免的代码:
Task.Run(async () =>
{
using (var httpClient = new HttpClient(new ApiHandler()))
{
var httpResponse = await httpClient.GetAsync("https://test.com/api/Tiers");
var result = await httpResponse.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
}).ContinueWith(async task =>
{
await Task.Delay(5000);
using (var httpClient = new HttpClient(new ApiHandler()))
{
var httpResponse = await httpClient.GetAsync("https://test.com/api/Tiers");
var result = await httpResponse.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
}).ContinueWith(async task =>
{
await Task.Delay(10000);
using (var httpClient = new HttpClient(new ApiHandler()))
{
var httpResponse = await httpClient.GetAsync("https://test.com/api/Tiers");
var result = await httpResponse.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
});
当我在fiddler中查看流量时:
行为与预期一致。每次创建和处置都会强制在请求和响应完成时建立连接。
正确和建议使用HttpClient的方法是将其设置为静态:
private static readonly HttpClient HttpClient = new HttpClient(new ApiHandler());
static void Main()
{
ServicePointManager
.FindServicePoint(new Uri("https://test.com"))
.ConnectionLeaseTimeout = 1000; // 1 second
ServicePointManager.DnsRefreshTimeout = 1000; // 1 second
Task.Run(async () =>
{
var httpResponse = await HttpClient.GetAsync("https://test.com/api/Tiers");
var result = await httpResponse.Content.ReadAsStringAsync();
Console.WriteLine(result);
}).ContinueWith(async task =>
{
await Task.Delay(5000); // delay 5 seconds
var httpResponse = await HttpClient.GetAsync("https://test.com/api/Tiers");
var result = await httpResponse.Content.ReadAsStringAsync();
Console.WriteLine(result);
}).ContinueWith(async task =>
{
await Task.Delay(10000); // delay 10 seconds
var httpResponse = await HttpClient.GetAsync("https://test.com/api/Tiers");
var result = await httpResponse.Content.ReadAsStringAsync();
Console.WriteLine(result);
});
Console.ReadKey();
}
我预计其行为与上图相同,但它看起来如下所示:
如果我随后添加HttpClient.DefaultRequestHeaders.ConnectionClose = true;
,我会得到所需的结果,但这是我们要避免的-对于创建连接的每个请求响应。
那么在Fiddler中我想要的结果是正确的吗?或者我在设置ConnectionLeaseTimeout
和/或DnsRefreshTimeout
时遗漏了什么?我真的很想测试这个行为,并确保在ServicePointManager
上设置这些属性可以解决HttpClient静态实例的已知DNS问题。
推荐答案
将自身注册为代理。默认情况下,它监听127.0.0.1、端口8888。因此,要为您的案例获取正确的服务点对象,您必须执行以下操作:
ServicePointManager.FindServicePoint(
new Uri("https://test.com"),
new WebProxy(new Uri("http://127.0.0.1:8888")))
.ConnectionLeaseTimeout = 1000; // 1 second
现在您将看到正确的结果。请注意,它不会完全像您预期的那样。第一个请求将打开新连接。即使已过5秒,第二个请求也不会打开新连接。相反,它将在请求时设置Connection: close
头,指示应该关闭连接。然后,下一个请求(第三个)最终将发起新的连接。据我所知,这是ConnectionLeaseTimeout
的预期行为。
这篇关于HttpClient-不支持对DNS的更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:HttpClient-不支持对DNS的更改
基础教程推荐
- 如何使用OpenXML SDK将Excel转换为CSV? 2022-01-01
- C# - 将浮点数转换为整数...并根据余数更改整数 2022-01-01
- Page.OnAppearing 中的 Xamarin.Forms Page.DisplayAlert 2022-01-01
- 创建属性设置器委托 2022-01-01
- 当键值未知时反序列化 JSON 2022-01-01
- 使用 SED 在 XML 标签之间提取值 2022-01-01
- C# - 如何列出发布到 ASPX 页面的变量名称和值 2022-01-01
- 从 VB6 迁移到 .NET/.NET Core 的最佳策略或工具 2022-01-01
- 覆盖 Json.Net 中的默认原始类型处理 2022-01-01
- 我什么时候应该使用 GC.SuppressFinalize()? 2022-01-01