注目キーワード

地味に必要!UnityにてHTTPリクエストにタイムアウト処理を実装する

IT

UnityでHTTPリクエストの処理を実装する機会があると思います。HTTPリクエストする際、地味に忘れては行けないのが、タイムアウト処理です。

この処理がないと、永遠にサーバーからのレスポンスを待ち続けることになり、ゲームが全く進行しないという大きな不具合につながるからです。

 

この記事では、前半にタイムアウトが必要な理由の解説、後半で、HTTPリクエストの実装方法を解説します。

 

 

タイムアウトが必要な理由

何らかの理由でサーバーから全くレスポンスがないとき、タイムアウトがないと永遠に待ち状態になってしまう。その結果、ユーザーがイライラすることになります。

 

実際に起きたできごと

ゲームアプリを開発していた時の話です。

ゲーム内に戦闘シーン(FFに近いイメージ)があります。戦闘が終わると、戦闘結果をサーバーに送信する仕組みです。戦闘結果がサーバに反映されない限り、先に進めないようになっていました。

 

あるとき、何らかの理由でサーバーから20分経ってもレスポンスがないときがありました。その結果、ゲームの進行が止まり、ユーザーから「30分以上かかってようやくクリアできたのに、フリーズしてしまい先に進めないよ!おかげで、クリアした状態が保存されていないよ!どうしてくれるの!!」というお怒りを頂きました。

 

話がそれますが、PSでよくCDの読み込みに失敗してゲームがフリーズすることがよくありました。フリーズが起きるとこれまで遊んでいたデータが無くなってしまいます。1時間以上の努力が水の泡でした。そのときは、怒り爆発していました。

 

そのように考えると、ユーザーの怒りも相当なものかもしれません。

 

ユーザーからの指摘があってから、タイムアウトの処理が必要と思うようになりました。

リクエストから一定の時間を過ぎたら、タイムアウトしリトライ、もしくはエラーを出力するなどすればよいでしょう。

 

 

 

タイムアウトの実装例

 

UnityWebRequestを使ってタイムアウトを実装してみます。

PHP側は、タイムアウトが発生するかどうかを試すため、10秒ほどプロセスをsleepさせます。

 

■Unity側のソースコード

	//UnityWebRequestでhttpリクエストを実装する
	//UnityWebRequestには、タイムアウト処理が実装されており
	//UnityWebRequestのメンバー変数timeoutに整数を設定するだけです
	IEnumerator UnityWebRequestDownload(string url) {

		UnityWebRequest www = UnityWebRequest.Get(url);

		//タイムアウトを3秒に設定する
		www.timeout = 3;
		Debug.Log("インターネット接続前:" + System.DateTime.Now.ToString());
		//リクエスト開始
		yield return www.Send();

		Debug.Log(www.error + " " + System.DateTime.Now.ToString());
		Debug.Log(www.downloadHandler.text + " " + System.DateTime.Now.ToString());
  	}

 

■PHP側のソースコード

//sleep関数
sleep(10);
echo "sample ok";

 

上記の実装の結果、たしかにタイムアウトが発生することを確認できます。

 

 

補足

HTTPリクエストの処理は、以下のように「WWW」でもリクエスト処理を数行で実装できますが、タイムアウト処理の実装を独自に実装うする必要があり面倒です。タイムアウトが必要な場合は、UnityWebRequestを使うことをおすすめします。

 

	//WWWでhttpリクエスを実装する
	//WWWには、タイムアウト処理がないため独自に作る必要がある。
	IEnumerator WWWDownload(string url) {

		Debug.Log("インターネット接続前:" + System.DateTime.Now.ToString());

		WWW www = new WWW(url);
		yield return www;

		Debug.Log(www.error + " " + System.DateTime.Now.ToString());
		Debug.Log(www.text + " " + System.DateTime.Now.ToString());
  	}

 

まとめ

いかがでしょうか?

UnityでHTTPリクエストの処理を実装するのであれば、サーバーから永遠にレスポンスがないことを考慮してUnityWebRequestなどのタイムアウト処理を入れたほうが無難です。