こんにちは。初投稿の ほげたつ(@HogeTatu) です。
コンシューマーやiOS/Android、LAMP系のバックエンドを経験してからヒストリアに入社しました。
UE4はHTTP通信周りに関しても既に揃っているようなので、まずはそこの紹介からやっていきたいと思います。
HTTP通信の概要
HTTPとはクライアントとサーバー間で行うための通信プロトコルの一種です。
以下に示すのが基本の流れとなります。
- クライアントが起点となり、サーバーにリクエストを送信
- サーバーがリクエストを受信
- リクエストに従って、適切に処理
- クライアントへレスポンスを送信
iOS/Androidのゲームでは、サーバーにハイスコア等のゲームデータを保存したり、サーバー側で集計されたランキングデータを受け取ってゲーム画面に反映したり、様々な用途で使用されています。
レスポンスとして返されるデータのフォーマットとしてはJSONが主流となっていました。
最近はパケットのサイズを考慮し、バイナリ形式のフォーマットであるMessagePackを使うところも増えている印象です。
もちろんチート対策として暗号化を実施したりもします。
UE4でHTTP通信を行う
UE4では各プラットフォーム間でのインターフェースの差異を無くすために、HTTPモジュールとしてラッピングされ、プラットフォームネイティブな部分の実装が隠蔽されています。
モジュールは Engine/Source/Runtime/Online/HTTP 以下に展開されています。
上記モジュールはBlueprintから呼び出しできるような仕組みになっていないため、HTTP通信を行いたい場合はC++コードを記述しなければなりません。
これから以下の仕様で簡単なHTTP通信を実装していきます。
- HTTP通信先のURLを指定できる
- 通信メソッド(リクエストタイプ。GET、PUT、POST等)を指定できる
- リクエストパラメータの追加/削除ができる
- 通信成功時にサーバーから受け取ったレスポンスを画面にログ表示する
サーバー上に接続先のプログラムを配置する
今回は PHP で簡単な echo プログラムを作成しました。
- リクエストタイプを出力
- GETパラメータがあれば出力
- POSTパラメータがあれば出力
echo.php
これをサーバー上に配置します。
テスト用のサーバーがあれば問題無いですが、もし無ければ Vagrant + VirtualBox でローカルサーバーを立てたり、Heroku でクラウド上に構築したりするのも良いと思います。
プロジェクトを作成する
「C++」&「Basic Code」でプロジェクトを作成します。
ターゲットの指定等は任意で構いません。
プロジェクトを作成し、Visual Studioからビルドしたら、エディタを起動してください。
HTTP通信用のクラスを編集する
以下の様に HttpRequester.h と HttpRequester.cpp を編集してください。
HttpRequester.h
HttpRequester.cpp
処理の流れに関してはコメントを参照してください。
また、 Http モジュール、Json モジュールを使用するために、プロジェクトの共通ヘッダ( [プロジェクト名].h )を開き、以下の処理を追記してください。
|
#include "Http.h" #include "Json.h" |
更に、各モジュールをリンクするために、プロジェクトファイル( [プロジェクト名.uproject] )を開き、以下の処理を記述してください。
|
"AdditionalDependencies": [ "Engine", "HTTP", "Json" ] |
それぞれ保存して Visual Studio でビルド後、レベルのBlueprintに以下の処理を記述します。

これでエディタ上から実行すると、画面にレスポンスのログが表示されます。

正常にGET通信の内容が出力されていますね。
ちなみにリクエストタイプの設定をGETからPOSTに変更したらレスポンスが変化します。

注意点
通信レスポンスは非同期に処理されるという点に注意してください。
上記 Blueprint 内の「Start Request」を実行しても、すぐには結果が表示されません。
前述した通り、一度サーバーにリクエストを送り、レスポンスが返ってくるまではレスポンスの内容がわからないため、多少のタイムラグはあります。
サーバーが高負荷になったり、通信経路上で遅延が発生した場合は待ちが長くなったり、サーバーまで届かないケースすら発生する可能性があります。
通信上のエラー処理としては、少なくとも以下のケースは想定するようにしてください。
- 通信経路上での遅延によるタイムアウト
- サーバーへのリクエストが通信経路上でロストし、届かない場合
- サーバーからのレスポンスが通信経路上でロストし、届かない場合
- サーバー側の処理になんらかの不具合があり、正常なレスポンスが返ってこなかった場合
面倒なのが、これに対してどう処理するのかがケースによって変わるという点です。
例えば 2 のケースだとそもそもサーバーまでリクエストが届いていないので、同じ内容のリクエストを再送すれば問題ありません。
ただし 3 のケースだとサーバー側は正常に処理されているので、再送されてしまうと問題がありますね。
(例えばポイントを加算するというリクエストを送った場合、二重に処理されて二倍ポイントが加算されてしまいます)
ひとまず再送し、サーバー側で同じリクエストを処理しないようにするという選択肢が有力ですが、少なからずクライアント側の対応も発生します。
通信でサーバーにパラメータを保存するといった場合は上記に関してお気をつけ下さい。
終わりに
今回はUE4でHTTP通信を使うにあたっての基礎を書きました。
次回はもうちょっと具体的に中身がどうなっているのか、HttpManagerは何をやっているのかを書いていこうと思います。