次のAPI呼び出しでMtGoxから取引履歴を取得する簡単なC#関数を作成しました。
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(取引ID)から始めています。各リクエストに対して、1000件の取引詳細を含むレスポンスを受け取ります。私は常に次のリクエストの前のレスポンスからトレードIDを送信します。正確に4つの要求と応答に対して正常に機能します。しかし、その後、次の行は「System.Net.WebException」をスローして、「操作がタイムアウトしました」と言っています
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
事実は次のとおりです。
間違っている可能性のあるアイデアはありますか?
タイムアウトには2種類あります。クライアントのタイムアウトとサーバーのタイムアウト。このようなことをしようとしましたか?
request.Timeout = Timeout.Infinite;
request.KeepAlive = true;
このようなものを試してみてください...
私はまったく同じ問題を抱えていました。私にとっては、修正はブロックを使用してHttpWebResponseコードをラップするのと同じくらい簡単でした。
using (HttpWebResponse response = (HttpWebResponse) request.GetResponse())
{
// Do your processings here....
}
詳細:この問題は、通常、同じホストに対して複数のリクエストが行われ、WebResponse
が適切に処理されない場合に発生します。 using
ブロックがWebResponse
オブジェクトを適切に破棄し、問題を解決する場所です。
Sslを介したLINUXサーバー上のREST Service。
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;
}
}
それが価値があるのは、呼び出しが呼び出しているサーバーに到達したにもかかわらず、使用するたびにタイムアウトに関する同じ問題が発生することでした。私の場合の問題は、Expectがapplication/jsonに設定されていたが、サーバーが返すものではなかったということでした。
これは解決策ではなく、単なる代替策です。最近では、ほとんどHttpWebRequestではなくWebClientのみを使用しています。特にPOSTおよびPUTとWebClient.DownloadStringのWebClient.UploadString。これらは単純に文字列を取得および返します。また、必要に応じてWebClient.Headers ["Content-type"]でコンテンツタイプを設定することもできます。
まれにパフォーマンスを向上させるために、System.Net.ServicePointManager.DefaultConnectionLimitを高く設定し、代わりにHttpClientを使用して、同時呼び出しにAsyncメソッドを使用します。
これが今のやり方です
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);
throw; // re-throw without changing the stack trace
}