首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Xamarin表单中使用HttpClient成功减少DNS刷新超时?

如何在Xamarin表单中使用HttpClient成功减少DNS刷新超时?
EN

Stack Overflow用户
提问于 2018-06-23 02:52:28
回答 2查看 1.2K关注 0票数 0

我正在开发一个相当复杂的Xamarin.Forms应用程序。我们提出了很多REST请求。据报道,我们的应用程序没有及时支持DNS故障转移以实现负载平衡,所以我开始调查。我正在运行dnsmasq,这样我就可以查看应用程序何时发出DNS请求。这段代码目前使用的是HttpWebRequest,我注意到它的查询间隔至少为10分钟。

我理解这一点的部分原因是因为大多数.NET网络部分都使用保持连接。如果我强制报头不使用keepalive,我肯定会看到更高的DNS查询率,但这会增加网络开销,所以这不是一个理想的解决方案。但我最初并没有看到一种清晰的方法来控制HttpWebRequest如何进行DNS查询。

我可以获得它的ServicePoint属性并在其上设置ConnectionLeaseTimeout,这看起来很有希望。不幸的是,这在Xamarin中抛出了NotImplementedException,所以它不会成为任何解决方案的一部分。

我想也许HttpClient会更具可配置性。我看到很多关于如何正确使用它的讨论,如果你这样做,你需要为你希望ServicePointManager.DnsRefreshTimeout频繁更新的用例设置一个较小的值。但这通常是与获取deisred端点的ServicePoint和修改ConnectionLeaseTimeout一起完成的,这是不可能的。

我一直在用一个非常简单的应用程序进行测试,它重用了一个HttpClient,并在我按下按钮时发出相同的请求。用一个按钮把这个ViewModel放在一些Xaml后面:

代码语言:javascript
复制
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会抛出。我希望这段代码只能缓存100ms的DNS请求,我打算在更多面向生产的测试中选择一个更合理的时间框架,比如2-3分钟。但是由于我不能让这个简单的例子像我想要的那样工作,所以增加延迟似乎没有意义。

肯定有人在Xamarin应用程序中遇到过这个问题?我唯一的解决方案是深入研究并尝试使用本机网络构造吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-23 03:15:49

如果你在Android上这样做,DNS会被缓存10分钟,我不相信你有任何从你的应用程序内部访问到期/刷新时间的权限。有许多方法可以强制刷新,但它们都涉及用户操作,如进入网络连接并从静态切换到DHCP和返回等。

我能想到的确保从你的应用程序内部获得新的DNS查找的唯一方法是让10+分钟的DNS条目包含所有别名到你的服务器,并循环通过它们,所以每次你请求DNS查找时,它都是一个新名称,而不是在缓存中。

例如,查找1.server.example.com 2.server.example.com等。每个新名称都将强制执行新的查找,并且不会从缓存中取出,因为它不在那里。

票数 1
EN

Stack Overflow用户

发布于 2018-06-28 23:08:26

似乎Java已经决定了“一些人不正确地实现DNS而忽略TTL”的解决方案是通过确保使用Java的设备不正确地实现DNS来使问题变得更糟。缓存中的所有DNS条目都使用一个TTL。有一些哲学上的争论,以及是什么让我在this question中找到了答案,我将其改编为答案。

在Xamarin项目方面,在某个地方添加以下内容(我在MainActivity早期选择了它):

代码语言:javascript
复制
Java.Security.Security.SetProperty("networkaddress.cache.ttl", "<integer seconds>");

将所有DNS条目的"“替换为所需的TTL。注意,较低的值可能意味着您进行了比以前更多的DNS查询,如果您认真地尝试节省网络字节,这可能是一个问题。

我把Terry Carmen的答案选为“答案”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50994072

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档