我正在开发一个相当复杂的 Xamarin.Forms 应用程序。我们提出了很多 REST 请求。据报道,我们的应用程序没有及时尊重用于负载平衡的 DNS 故障转移,因此我开始调查。我正在运行 dnsmasq,所以我可以查看应用程序何时发出 DNS 请求。该代码目前正在使用HttpWebRequest,我注意到它至少间隔 10 分钟进行 DNS 查询。
我理解部分原因是因为大多数 .NET 网络位使用 keepalive 连接。如果我强制标头不使用 keepalive,我当然会看到更高的 DNS 查询率,但这会增加网络开销,因此这不是理想的解决方案。但我最初并没有看到一种明确的方法来控制如何HttpWebRequest进行 DNS 查询。
看起来很有希望我可以获得它的ServicePoint属性并设置ConnectionLeaseTimeout它。不幸的是,这会NotImplementedException导致 Xamarin,因此它不会成为任何解决方案的一部分。
我认为这可能HttpClient会更可配置。我看到很多关于如何正确使用它的讨论,如果你这样做,你需要为ServicePointManager.DnsRefreshTimeout你希望 DNS 频繁更新的用例设置一个较小的值。但这通常与获取ServicePoint所需端点的 和 修改 一起完成ConnectionLeaseTimeout,这是不可能的。
我一直在使用一个非常简单的应用程序进行测试,该应用程序重用 HttpClient 并在我按下按钮时发出相同的请求。用一个按钮将这个 ViewModel 放在一些 Xaml 后面:
using System;
using Xamarin.Forms;
using System.Net.Http;
using System.Net;
namespace TestDns {
public class MainPageViewModel {
private const string _URL = "http://www.example.com";
private HttpClient _httpClient;
private ServicePoint _sp;
public MainPageViewModel() {
var sp = ServicePointManager.FindServicePoint(new Uri(_URL));
_sp = sp;
//_sp.ConnectionLeaseTimeout = 100; // throws NIE
_httpClient = new HttpClient();
ServicePointManager.DnsRefreshTimeout = 100;
}
public Command WhenButtonIsClicked {
get {
return new Command(() => SendRequest());
}
}
private async void SendRequest() {
Console.WriteLine($"{_sp.CurrentConnections}");
var url = "http://www.example.com";
var response = await _httpClient.GetAsync(url);
Console.WriteLine($"{response.Content}");
}
}
}
没想到ConnectionLeaseTimeout扔了 我希望这段代码只缓存 100 毫秒的 DNS 请求,我打算在更多面向生产的测试中选择一个更合理的时间范围,比如 2-3 分钟。但是由于我无法让这个简单的示例像我想要的那样运行,所以增加延迟似乎没有实际意义。
肯定有人在 Xamarin 应用程序中遇到过这个问题?我唯一的解决方案是深入研究并尝试使用本机网络结构吗?
GCT1015
相关分类