UE4: FHttpModule 系の HTTP リクエスト機構を使い "同期処理" する方法
概要
UE4 で HTTP リクエストを飛ばしたい場合、 HTTP モジュールを有効化し、 FHttpModule::Get
で得たオブジェクトから FHttpModule::CreateRequest
し、 IHttpRequest
のプラットフォームのオブジェクトを得て URL 等の必要なリクエストパラメーター及び OnProcessRequestComplete
等を設定した後、 ProcessRequest
する。
この UE4 の HTTP モジュールは "非同期処理" を前提に実装され、インターフェースが提供され、 examples でも非同期処理で HTTP モジュールを扱っている例が幾つか見当たる。
この記事では "諸事情により UE4 の HTTP モジュールを同期処理したい場合" に遭遇した際にどのような実装を行えば良いか整理する。
実装
同期処理でも非同期処理でも同様の部分:
// 1. リクエストを生成 auto request = FHttpModule::Get().CreateRequest(); // 2. リクエストを設定 request->OnProcessRequestComplete().BindLambda( /* 省略 */ ); request->SetURL( /* 省略 */ ); /* 省略 */ // 3. リクエストの開始処理を呼ぶ request->ProcessRequest();
同期処理したい場合に加える必要のある実装:
// 4.a. HTTP モジュールを強制的に作動させる FHttpModule::Get().GetHttpManager().Flush( false );
別の実装方法:
// 4.b. HTTP モジュールを "ちまちま" と強制的に作動させる do { std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); FHttpModule::Get().GetHttpManager().Tick( 0.010f ); } while ( request->GetStatus() == EHttpRequestStatus::Processing );
概説
IHttpRequest::ProcessRequest
はFHttpManager
へ自身のスマートポインターを登録し処理開始させるなどするFHttpManager::Flush
は保持中のIHttpRequest
のスマートポインター群のレスポンス取得処理が完了するまで自身のTick
をマシン時間で進めるFHttpManager::Tick
は保持中のIHttpRequest
のスマートポインター群のレスポンス取得処理を進め、IHttpRequest
オブジェクトのTick
も呼ぶIHttpRequest::Tick
レスポンス取得、ステータス更新、タイムアウト処理などを進める
と、いうわけで簡単に同期処理として HTTP モジュールを使いたい場合には非同期処理の実装に加えて FHttpModule::Get().GetHttpManager().Flush( false )
を呼べば良い。
参考
- FHttpModule | Unreal Engine
- FHttpManager | Unreal Engine
- IHttpRequest | Unreal Engine
- EHttpRequestStatus::Type | Unreal Engine
Note: 実際にこのような実装が可能かはそれぞれのソースコードの実装詳細を読んで確認している。