C++でWebAPIと通信する機能を作成した際、環境要因で(?)
WebAPIからのレスポンスを受信できないという現象があり、
解決に手間取ったので、方法を備忘録として残しておきます。
前提条件
・C++でHTTP(S)通信を行うため、Microsoft提供のcpprestsdkを使用
・cpprestsdkのDLLはNuGetで取得(version:2.5.0)
・WindowsXP(Embedded)で発生(ただし1回目の通信は成功し、2回目以降で失敗)
発生した現象について
実装していたコードはざっくり記載するとこんな感じです。
http_client_config cfg;
http_client client(L"URL文字列", cfg)
auto request = client.request(method::Post, L"", postData.serialize(), L"application/json");
request.then([](http_response response)
{
// 受信時の処理(ローカル変数に受信時のJSON文字列を保持)
}.wait();
このコード、Windows10(64bit)では問題なく動作しました。
しかし問題となっている環境(WindowsXP)では、何故か受信しないように見えるパターンが存在しました。
Wiresharkを入れて通信を監視してみましたが、クライアント - WebAPI間ではHTTPレスポンスも
受信できており、直前・直後のTCP通信も正常のため、何故??という状態になりました。
対処法
WebAPIからのレスポンス待機を行う部分について、別の書き方ができるか調べてみた結果
以下に変更するとうまくいきました。
変更前
request.then([](http_response response)
{
// 受信時の処理(ローカル変数に受信時のJSON文字列を保持)
}.wait();
変更後
// ここでリクエスト送信+レスポンス待機
auto resp = request.get();
// 待機完了後、レスポンスのJSON文字列を取得
auto respJson = resp.extract_json().get();
get() 内部でレスポンス待機処理が記載されており、
問題が発生したコードと機能の実装は変わらないと言えます。
内部処理のため直接原因は分からないままでしたが、「http_client.request」が
タスクチェーンで「wait」「then」の組み合わせとなった場合に、問題の現象が発生するのかもしれません。
なお、別の書き方として以下の様な方法もありました。
while(!request.is_done())
{
// 待機処理
}
こちらのコードも問題の現象は発生しなくなりますが、「request.is_done()」が完了済みと
判断する時点が分からないため、不要な通信が発生する可能性があるという点で、
使用は控えるべきかと思います。
今回はこのへんで。ではまた!
0 件のコメント:
コメントを投稿