我正在研究链接检查器,一般情况下我可以执行HEAD请求,但是有些网站似乎禁用了这个动词,所以在失败时我还需要执行一个GET请求(仔细检查链接是否真的死了)
我使用以下代码作为我的链接测试器:
public class ValidateResult
{
public HttpStatusCode? StatusCode { get; set; }
public Uri RedirectResult { get; set; }
public WebExceptionStatus? WebExceptionStatus { get; set; }
}
public ValidateResult Validate(Uri uri, bool useHeadMethod = true,
bool enableKeepAlive = false, int timeoutSeconds = 30)
{
ValidateResult result = new ValidateResult();
HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
if (useHeadMethod)
{
request.Method = "HEAD";
}
else
{
request.Method = "GET";
}
// always compress, if you get back …Run Code Online (Sandbox Code Playgroud) 您何时需要调整这两个设置(如下)?这两个数字对HttpWebRequest我所做的实例意味着什么?
System.Net.ServicePointManager.DefaultConnectionLimitSystem.Net.ServicePointManager.MaxServicePointIdleTime是否ServicePoint请求特定于域名或每个唯一URI的对象?
我有一个用C#编写的ASP.NET 3.5服务器应用程序.它使用HttpWebRequest和HttpWebResponse向REST API发出出站请求.
我已经设置了一个测试应用程序来在不同的线程上发送这些请求(模糊地模仿服务器的并发性).
请注意,这更像是单声道/环境问题,而不是代码问题; 所以请记住,下面的代码不是逐字的; 只是功能位的剪切/粘贴.
这是一些伪代码:
// threaded client piece
int numThreads = 1;
ManualResetEvent doneEvent;
using (doneEvent = new ManualResetEvent(false))
{
for (int i = 0; i < numThreads; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Test), random_url_to_same_host);
}
doneEvent.WaitOne();
}
void Test(object some_url)
{
// setup service point here just to show what config settings Im using
ServicePoint lgsp = ServicePointManager.FindServicePoint(new Uri(some_url.ToString()));
// set these to optimal for MONO and .NET
lgsp.Expect100Continue = false;
lgsp.ConnectionLimit = 100;
lgsp.UseNagleAlgorithm = true; …Run Code Online (Sandbox Code Playgroud) 我正在努力解决这个错误:https:
//github.com/openstacknetsdk/openstack.net/issues/333
该问题涉及ProtocolViolationException以下消息:
HTTP/1.0协议不支持分块编码上载.
我发现我能够可靠地重现我发出生成502响应代码的Web请求的问题,然后调用使用带有分块编码的POST请求.我将其追溯到ServicePoint.HttpBehaviour具有HttpBehaviour.HTTP10502响应之后的值的属性.
我能够使用以下hack解决问题(在catch块中).此代码"隐藏" ServicePoint由失败请求创建的实例ServicePointManager,强制它ServicePoint为下一个请求创建新的实例.
public void TestProtocolViolation()
{
try
{
TestTempUrlWithSpecialCharactersInObjectName();
}
catch (WebException ex)
{
ServicePoint servicePoint = ServicePointManager.FindServicePoint(ex.Response.ResponseUri);
FieldInfo table = typeof(ServicePointManager).GetField("s_ServicePointTable", BindingFlags.Static | BindingFlags.NonPublic);
WeakReference weakReference = (WeakReference)((Hashtable)table.GetValue(null))[servicePoint.Address.GetLeftPart(UriPartial.Authority)];
if (weakReference != null)
weakReference.Target = null;
}
TestTempUrlExpired();
}
Run Code Online (Sandbox Code Playgroud)
问题:
我正在 WinForms 中重写一些 Web 处理代码并从 HttpWebRequest 切换到 HttpClient。我需要的最后一件事我似乎无法找到如何完成。
在 HttpWebRequest 中,我可以从我连接的 Web 服务器捕获证书并显示它:
...
HttpWebRequest request = CreateHttpRequest(destUri);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
cert = request.ServicePoint.Certificate;
if (cert != null)
{
cert2 = new X509Certificate2(cert);
X509Certificate2UI.DisplayCertificate(cert2);
}
...
Run Code Online (Sandbox Code Playgroud)
我找不到使用 HttpClient 捕获证书的等效方法:
//... Use HttpClient.
using (HttpClient client = new HttpClient())
{
using (HttpResponseMessage response = await client.GetAsync(destUri))
{
using (HttpContent content = response.Content)
{
string result = await content.ReadAsStringAsync();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我在这里如何/在哪里可以做到这一点?我不知道如何访问 ServicePoint.Certificate。
为什么当客户端连接到'localhost'上的服务时,System.Net.ServicePoint.ConnectionLimit使用'7FFFFFFF'(Int32.MaxValue/2147483647),而如果服务在远程计算机上运行,它决定使用'2'作为默认值?
最初我认为如果没有设置servicepoint.connectionlimit,它将是ServicePointManager.DefaultConnectionLimit.但是,我刚刚意识到(一旦我从客户那里得到了一个问题),那就是它的Int32.MaxValue/2147483647.
我做了一些研究(详情请参考下面的链接),但是我无法找到它用于int32.maxvalue的原因.我可以猜测它可能是为了更好的性能,因为输入请求和响应消息不会越过边界.
我的问题:
一些与此相关的有用链接:
在httpwebrequest中创建TCP连接的方式和位置,以及它与servicepoint的关系如何?
http://blogs.microsoft.co.il/idof/2011/06/20/servicepointmanagerdefaultconnectionlimit-2-depends/
http://msdn.microsoft.com/en-us/library/system.net.servicepoint.connectionlimit(v=vs.110).aspx
http://arnosoftwaredev.blogspot.com/2006/09/net-20-httpwebrequestkeepalive-and.html
Reflector的代码片段
public int ConnectionLimit
{
get
{
if ((!this.m_UserChangedLimit && (this.m_IPAddressInfoList == null)) && (this.m_HostLoopbackGuess == TriState.Unspecified))
{
lock (this)
{
if ((!this.m_UserChangedLimit && (this.m_IPAddressInfoList == null)) && (this.m_HostLoopbackGuess == TriState.Unspecified))
{
IPAddress address = null;
if (IPAddress.TryParse(this.m_Host, out address))
{
this.m_HostLoopbackGuess = IsAddressListLoopback(new IPAddress[] { address }) ? TriState.True : TriState.False;
} …Run Code Online (Sandbox Code Playgroud) 我正在开发一个ASP.NET Core 2.0 API,我的API需要调用另一个第三方REST API来上传和检索文件,并获取文件列表和状态信息.我将在Azure中托管API,并计划在我的暂存和生产插槽之间进行蓝绿色部署.
似乎最佳实践的一般共识是在Startup.cs - > ConfigureSerrvices方法中通过DI注册设置HTTPClient的Singleton实例,以便提高性能并避免在我新建一个dispose时可能发生的套接字错误通过Using语句与每次使用的HTTPClient连接.这在以下链接中注明;
https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.110).aspx#Anchor_5
http://www.nimaara.com/2016/11/01/beware-of-the-net-httpclient/
但是,如果我这样做,那么当我在Azure中进行蓝绿色部署时,我可能面临一个问题,即Singleton实例不会看到任何DNS更改.这在以下链接中注明;
http://byterot.blogspot.co.uk/2016/07/singleton-httpclient-dns.html
https://github.com/dotnet/corefx/issues/11224
http://www.nimaara.com/2016/11/01/beware-of-the-net-httpclient/
因此,现在普遍的共识是使用静态HTTPClient实例,但控制ServicePoint类的ConnectionLeaseTimeout值,将其设置为较短的值,强制关闭连接以刷新DNS.这篇博客文章甚至讨论了nuget包中的一个漂亮的RestClient组件(Nima的Easy.Common),它正确地解决了ConnectionLeaseTimeout以及缓存的DNS值.
但是,似乎ASP.NET Core 2.0没有完全实现ServicePoint,因此ASP.Net Core 2.0目前不支持这种方法.
任何人都可以建议我在Azure上运行的ASP.NET Core 2.0 API中使用HttpClient的正确方法吗?我希望能够进行蓝绿色部署.那么,我是否应该使用Using语句并在每次使用时新建客户端并且只是遭受性能损失?
看起来似乎必须有一个可靠和高效的解决方案来满足这一共同需求.
design-patterns azure servicepoint dotnet-httpclient asp.net-core-2.0
我想关闭特定连接上的 Nagle 算法(在我的情况下 - 到 ElasticSearch 服务器)。
我的代码目前看起来像这样:
ServicePointManager.FindServicePoint(new Uri(uriWithoutLocalPath)).UseNagleAlgorithm = false;
Run Code Online (Sandbox Code Playgroud)
问题是ServicePoint对象在一段时间后被回收,导致它丢失设置。因此,我不能在系统启动时只运行一次此代码。看来我面前有几个选择:
ServicePoint永远不会回收(可能是个坏主意?我的直觉告诉我)。ServicePoint。我真的不喜欢这些选项中的任何一个,它们要么会影响系统中的其他东西,要么看起来对于我想要做的事情来说太复杂了(比如计时器选项)。在我看来,应该有一个简单的解决方案。想法?
更改ServicePointManager.DefaultConnectionLimit是否仅影响当前进程或整个.NET平台.请提供来源.
servicepoint ×9
c# ×6
.net ×4
asp.net ×2
apache ×1
azure ×1
mono ×1
rest ×1
ssl ×1
web-services ×1