[英]HttpWebRequest.GetResponse() keeps getting timed out
我编写了一个简单的 C# 函数,通过以下 API 调用从 MtGox 检索交易历史:
https://data.mtgox.com/api/1/BTCUSD/trades?since=<trade_id>
此处记录: https : //en.bitcoin.it/wiki/MtGox/API/HTTP/v1#Multi_currency_trades
这是功能:
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;
}
我从 tid=0 (trade id) 开始获取数据(从一开始)。 对于每个请求,我都会收到一个包含 1000 个交易详细信息的响应。 对于下一个请求,我总是从上一个响应中发送交易 ID。 它正好适用于 4 个请求和响应。 但在那之后,以下行抛出“System.Net.WebException”,表示“操作已超时”:
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
以下是事实:
关于什么可能是错误的任何想法?
我有同样的问题。 对我来说,修复就像在 using 块中包装 HttpWebResponse 代码一样简单。
using (HttpWebResponse response = (HttpWebResponse) request.GetResponse())
{
// Do your processings here....
}
详细信息:当对同一主机发出多个请求并且WebResponse
未正确处理时,通常会发生此问题。 这就是using
块将正确处理WebResponse
对象并从而解决问题的地方。
有两种超时。 客户端超时和服务器超时。 你有没有试过做这样的事情:
request.Timeout = Timeout.Infinite;
request.KeepAlive = true;
尝试这样的事情......
我只是在通过 ssl 在 LINUX 服务器上调用 REST 服务时遇到了类似的麻烦。 在尝试了许多不同的配置方案后,我发现我必须在 http 头中发送一个 UserAgent。
这是我调用 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;
}
}
这不是解决方案,而只是替代方案:这些天我几乎只使用 WebClient 而不是 HttpWebRequest。 尤其是用于 POST 和 PUT 的 WebClient.UploadString 和 WebClient.DownloadString。 这些只是获取和返回字符串。 这样我就不必处理流对象,除非我得到一个 WebException。 如有必要,我还可以使用 WebClient.Headers["Content-type"] 设置内容类型。 using 语句还通过为我调用 Dispose 使生活更轻松。
很少为了性能,我将 System.Net.ServicePointManager.DefaultConnectionLimit 设置为高,而是使用 HttpClient 及其异步方法进行同步调用。
这就是我现在要做的
string GetTradesOnline(Int64 tid)
{
using (var wc = new WebClient())
{
return wc.DownloadString("https://data.mtgox.com/api/1/BTCUSD/trades?since=" + tid.ToString());
}
}
还有 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;
}
错误处理
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);
}
对于它的价值,我每次使用它时都会遇到相同的超时问题,即使调用通过了我正在调用的服务器。 我的问题是我将 Expect 设置为 application/json,而这不是服务器返回的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.