HTTP Put リクエストを 60 秒ごとに RoR Web サイト/アプリに送信する必要があるクライアント側コードに奇妙な問題があります。
問題は、クライアント側のアプリがいくつかのリクエストを Web サイトにプッシュすることです (2 から 9 のリクエストの任意の場所)。その後、クライアント側のコードは、最初の数回のプッシュが成功した後、http put リクエストの送信を停止します。
情報: クライアント側アプリは C# Windows アプリケーションです。Web サイトは RoR 3.2 を実行しています。
http putを送信するc#コード
static void HttpPutRequest(string Json)
{
Logger("Sending JSON: " + Json);
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://miningmonitor.herokuapp.com/workers/update");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "PUT";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
Logger("To URL: " + httpWebRequest.Address.ToString());
streamWriter.WriteLine(Json);
streamWriter.Flush();
streamWriter.Close();
try
{
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
var wRespStatusCode = httpResponse.StatusCode;
Logger("Website return code: " + wRespStatusCode.ToString());
}
catch (WebException we)
{
var wRespStatusCode = ((HttpWebResponse)we.Response).StatusCode;
Logger(" Exception and Website return code: " + wRespStatusCode.ToString());
}
}
}
catch (WebException we2)
{
var GetRequestStreamExp = ((HttpWebResponse)we2.Response).StatusCode;
Logger(" Exception trying to setup httpWebRequest.GetRequestStream: " + GetRequestStreamExp.ToString());
}
}
クライアント側の C# ロギング ステートメント
Sending JSON: {"worker_user_name":"test:worker1","hashrate":"1.91","accepted":"5953","rejected":"152","hw_errors":"0","num_gpu":"3","gpus":["72.00","0.64","73.00","0.64","74.00","0.63"]}
To URL: https://miningmonitor.herokuapp.com/workers/update
Website return code: OK
Sending JSON: {"worker_user_name":"test:worker1","hashrate":"1.91","accepted":"5956","rejected":"152","hw_errors":"0","num_gpu":"3","gpus":["72.00","0.64","73.00","0.64","74.00","0.62"]}
To URL: https://miningmonitor.herokuapp.com/workers/update
Website return code: OK
Sending JSON: {"worker_user_name":"test:worker1","hashrate":"1.91","accepted":"5964","rejected":"152","hw_errors":"0","num_gpu":"3","gpus":["72.00","0.64","73.00","0.64","74.00","0.63"]}
To URL: https://miningmonitor.herokuapp.com/workers/update
Website return code: OK
Sending JSON: {"worker_user_name":"test:worker1","hashrate":"1.91","accepted":"5970","rejected":"152","hw_errors":"0","num_gpu":"3","gpus":["72.00","0.64","73.00","0.64","74.00","0.63"]}
To URL: https://miningmonitor.herokuapp.com/workers/update
Website return code: OK
Sending JSON: {"worker_user_name":"test:worker1","hashrate":"1.91","accepted":"5978","rejected":"152","hw_errors":"0","num_gpu":"3","gpus":["72.00","0.64","73.00","0.64","74.00","0.63"]}
To URL: https://miningmonitor.herokuapp.com/workers/update
Website return code: OK
Sending JSON: {"worker_user_name":"test:worker1","hashrate":"1.91","accepted":"5989","rejected":"153","hw_errors":"0","num_gpu":"3","gpus":["72.00","0.64","73.00","0.64","74.00","0.63"]}
To URL: https://miningmonitor.herokuapp.com/workers/update
Website return code: OK
Sending JSON: {"worker_user_name":"test:worker1","hashrate":"1.91","accepted":"5995","rejected":"153","hw_errors":"0","num_gpu":"3","gpus":["72.00","0.64","73.00","0.64","74.00","0.63"]}
To URL: https://miningmonitor.herokuapp.com/workers/update
Website return code: OK
Sending JSON: {"worker_user_name":"test:worker1","hashrate":"1.91","accepted":"5999","rejected":"153","hw_errors":"0","num_gpu":"3","gpus":["72.00","0.64","73.00","0.63","74.00","0.63"]}
Sending JSON: {"worker_user_name":"test:worker1","hashrate":"1.91","accepted":"6009","rejected":"153","hw_errors":"0","num_gpu":"3","gpus":["72.00","0.64","73.00","0.64","74.00","0.63"]}
Sending JSON: {"worker_user_name":"test:worker1","hashrate":"1.91","accepted":"6015","rejected":"153","hw_errors":"0","num_gpu":"3","gpus":["72.00","0.63","73.00","0.64","74.00","0.63"]}
Sending JSON: {"worker_user_name":"test:worker1","hashrate":"1.91","accepted":"6021","rejected":"153","hw_errors":"0","num_gpu":"3","gpus":["72.00","0.64","73.00","0.64","74.00","0.63"]}
Sending JSON: {"worker_user_name":"test:worker1","hashrate":"1.91","accepted":"6029","rejected":"153","hw_errors":"0","num_gpu":"3","gpus":["72.00","0.64","73.00","0.64","74.00","0.64"]}
その時点から、そのjsonを作成するだけで送信されません。
put リクエストの送信を示すサーバー ログ
Aug 13 10:31:52 miningmonitor heroku/router: at=info method=PUT path=/workers/update host=miningmonitor.herokuapp.com fwd="198.244.99.204" dyno=web.1 connect=8ms service=101ms status=200 bytes=2005
これを 60 秒ごとに実行する方法は、C# でタイマーを使用することです。しかし、コードが using ステートメントの入力を停止し、JSON 文字列の送信を停止する理由がわかりません。これは、C# コードのログ ステートメントで確認できます。using ステートメントがどのように機能するのかよくわかりません。オンラインで見つけた例からそのステートメントを変更して、http 要求を送信しました。したがって、誰かが using ステートメントについても説明できれば、それは素晴らしいことです。
タイマーコードを追加します。
public void update(string user_worker)
{
System.Timers.Timer timer = new System.Timers.Timer(60000);
timer.Elapsed += (sender, e) =>
{
//query the miner for summary and gpucount information
String SummaryQuery = QueryMiner("summary");
String gpuNum = FindKey(QueryMiner("gpucount"), "Count");
//String PoolQuery = QueryMiner("pools");
int numgpus = Convert.ToInt32(gpuNum);
//Array of strings to hold each gpu query
String[] gpuQueries = new String[numgpus];
//add the GPU queries into the array
for (int i = 0; i < numgpus; i++)
gpuQueries[i] = QueryMiner("gpu|" + i);
//now add information specific to each gpu to a list
List<string> gpuList = new List<string>();
for (int i = 0; i + 1 <= gpuQueries.Length; i++)
{
gpuList.Add(FindKey(gpuQueries[i], "Temperature"));
gpuList.Add(FindKey(gpuQueries[i], "MHS 5s"));
}
//set all the values that we have gotten from the queries
this.worker_user_name = user_worker;
this.hashrate = FindKey(SummaryQuery, "MHS av");
this.accepted = FindKey(SummaryQuery, "Accepted");
this.rejected = FindKey(SummaryQuery, "Rejected");
this.hw_errors = FindKey(SummaryQuery, "Hardware Errors");
this.num_gpu = gpuNum;
this.gpus = gpuList.ToArray();
//create JSON from the workerUpdate object
string JSON = JsonConvert.SerializeObject(this);
//send to website
HttpPutRequest(JSON);
};
timer.Start();
}
ログで例外をキャッチしました。例外は以下です。しかし、それが何を意味するのかわかりません。
Exception: System.NullReferenceException: Object reference not set to an instance of an object.
at MiningMonitorClientW.WorkerUpdate.HttpPutRequest(String Json)
at MiningMonitorClientW.WorkerUpdate.<>c__DisplayClass1.<update>b__0(Object sender, ElapsedEventArgs e)
更新:さらにデバッグを行ったところ、エラーが発生すると、この行までコードが実行されることに気付きました
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
おそらく、ストリーム書き込みを作成しようとしていて、ストリームを要求しているときに、null 応答が返されますか? わからない。ただし、例外は何かがnullであると言っています。