[英]HttpWebRequest.GetResponse() keeps getting timed out
i wrote a simple C# function to retrieve trade history from MtGox with following API call:我编写了一个简单的 C# 函数,通过以下 API 调用从 MtGox 检索交易历史:
https://data.mtgox.com/api/1/BTCUSD/trades?since=<trade_id>
documented here: https://en.bitcoin.it/wiki/MtGox/API/HTTP/v1#Multi_currency_trades此处记录: https : //en.bitcoin.it/wiki/MtGox/API/HTTP/v1#Multi_currency_trades
here's the function:这是功能:
string GetTradesOnline(Int64 tid)
{
Thread.Sleep(30000);
// communicate
string url = "https://data.mtgox.com/api/1/BTCUSD/trades?since=" + tid.ToString();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string json = reader.ReadToEnd();
reader.Close();
reader.Dispose();
response.Close();
return json;
}
i'm starting at tid=0 (trade id) to get the data (from the very beginning).我从 tid=0 (trade id) 开始获取数据(从一开始)。 for each request, i receive a response containing 1000 trade details.
对于每个请求,我都会收到一个包含 1000 个交易详细信息的响应。 i always send the trade id from the previous response for the next request.
对于下一个请求,我总是从上一个响应中发送交易 ID。 it works fine for exactly 4 requests & responses.
它正好适用于 4 个请求和响应。 but after that, the following line throws a "System.Net.WebException", saying that "The operation has timed out":
但在那之后,以下行抛出“System.Net.WebException”,表示“操作已超时”:
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
here are the facts:以下是事实:
any ideas of what could be wrong?关于什么可能是错误的任何想法?
I had the very same issue.我有同样的问题。 For me the fix was as simple as wrapping the HttpWebResponse code in using block.
对我来说,修复就像在 using 块中包装 HttpWebResponse 代码一样简单。
using (HttpWebResponse response = (HttpWebResponse) request.GetResponse())
{
// Do your processings here....
}
Details : This issue usually happens when several requests are made to the same host, and WebResponse
is not disposed properly.详细信息:当对同一主机发出多个请求并且
WebResponse
未正确处理时,通常会发生此问题。 That is where using
block will properly dispose the WebResponse
object properly and thus solving the issue.这就是
using
块将正确处理WebResponse
对象并从而解决问题的地方。
There are two kind of timeouts.有两种超时。 Client timeout and server timeout.
客户端超时和服务器超时。 Have you tried doing something like this:
你有没有试过做这样的事情:
request.Timeout = Timeout.Infinite;
request.KeepAlive = true;
Try something like this...尝试这样的事情......
I just had similar troubles calling a REST Service on a LINUX Server thru ssl.我只是在通过 ssl 在 LINUX 服务器上调用 REST 服务时遇到了类似的麻烦。 After trying many different configuration scenarios I found out that I had to send a UserAgent in the http head.
在尝试了许多不同的配置方案后,我发现我必须在 http 头中发送一个 UserAgent。
Here is my final method for calling the REST API.这是我调用 REST API 的最终方法。
private static string RunWebRequest(string url, string json)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
// Header
request.ContentType = "application/json";
request.Method = "POST";
request.AllowAutoRedirect = false;
request.KeepAlive = false;
request.Timeout = 30000;
request.ReadWriteTimeout = 30000;
request.UserAgent = "test.net";
request.Accept = "application/json";
request.ProtocolVersion = HttpVersion.Version11;
request.Headers.Add("Accept-Language","de_DE");
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
byte[] bytes = Encoding.UTF8.GetBytes(json);
request.ContentLength = bytes.Length;
using (var writer = request.GetRequestStream())
{
writer.Write(bytes, 0, bytes.Length);
writer.Flush();
writer.Close();
}
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var jsonReturn = streamReader.ReadToEnd();
return jsonReturn;
}
}
This is not a solution, but just an alternative: These days i almost only use WebClient instead of HttpWebRequest.这不是解决方案,而只是替代方案:这些天我几乎只使用 WebClient 而不是 HttpWebRequest。 Especially WebClient.UploadString for POST and PUT and WebClient.DownloadString.
尤其是用于 POST 和 PUT 的 WebClient.UploadString 和 WebClient.DownloadString。 These simply take and return strings.
这些只是获取和返回字符串。 This way i don't have to deal with streams objects, except when i get a WebException.
这样我就不必处理流对象,除非我得到一个 WebException。 i can also set the content type with WebClient.Headers["Content-type"] if necessary.
如有必要,我还可以使用 WebClient.Headers["Content-type"] 设置内容类型。 The using statement also makes life easier by calling Dispose for me.
using 语句还通过为我调用 Dispose 使生活更轻松。
Rarely for performance, i set System.Net.ServicePointManager.DefaultConnectionLimit high and instead use HttpClient with it's Async methods for simultaneous calls.很少为了性能,我将 System.Net.ServicePointManager.DefaultConnectionLimit 设置为高,而是使用 HttpClient 及其异步方法进行同步调用。
This is how i would do it now这就是我现在要做的
string GetTradesOnline(Int64 tid)
{
using (var wc = new WebClient())
{
return wc.DownloadString("https://data.mtgox.com/api/1/BTCUSD/trades?since=" + tid.ToString());
}
}
2 more POST examples还有 2 个 POST 示例
// POST
string SubmitData(string data)
{
string response;
using (var wc = new WebClient())
{
wc.Headers["Content-type"] = "text/plain";
response = wc.UploadString("https://data.mtgox.com/api/1/BTCUSD/trades", "POST", data);
}
return response;
}
// POST: easily url encode multiple parameters
string SubmitForm(string project, string subject, string sender, string message)
{
// url encoded query
NameValueCollection query = HttpUtility.ParseQueryString(string.Empty);
query.Add("project", project);
query.Add("subject", subject);
// url encoded data
NameValueCollection data = HttpUtility.ParseQueryString(string.Empty);
data.Add("sender", sender);
data.Add("message", message);
string response;
using (var wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
response = wc.UploadString( "https://data.mtgox.com/api/1/BTCUSD/trades?"+query.ToString()
, WebRequestMethods.Http.Post
, data.ToString()
);
}
return response;
}
Error handling错误处理
try
{
Console.WriteLine(GetTradesOnline(0));
string data = File.ReadAllText(@"C:\mydata.txt");
Console.WriteLine(SubmitData(data));
Console.WriteLine(SubmitForm("The Big Project", "Progress", "John Smith", "almost done"));
}
catch (WebException ex)
{
string msg;
if (ex.Response != null)
{
// read response HTTP body
using (var sr = new StreamReader(ex.Response.GetResponseStream())) msg = sr.ReadToEnd();
}
else
{
msg = ex.Message;
}
Log(msg);
}
For what it's worth, I was experiencing the same issues with timeouts every time I used it, even though calls went through to the server I was calling.对于它的价值,我每次使用它时都会遇到相同的超时问题,即使调用通过了我正在调用的服务器。 The problem in my case was that I had Expect set to application/json, when that wasn't what the server was returning.
我的问题是我将 Expect 设置为 application/json,而这不是服务器返回的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.