Unityのゲームを動かしている間に外からHTTPでメッセージを送って制御したりするのをやりたかったので、ゲーム内でHTTPリクエストを処理する方法を調べました。
.NETに標準で搭載されているHttpListener
を使うことでHTTPリクエストを受け付ける処理を書くことができます。最近のUnityではスクリプトランタイムを.NET 4.6環境に設定することができてasync/await
を使うこともできるので、より簡潔な方法で記述することができるようになりました。
本記事ではさらにUnityのイベントシステムと組み合わせることで、クリックイベントなどと同じような感覚でHTTPリクエストを処理できるようなしくみを作ってみました。
HTTPサーバーのコンポーネントを作る
まず、以下のようなスクリプトを書きます。
using System.Net;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
[System.Serializable]
public class OnRequestEvent : UnityEvent<HttpListenerContext> { }
public class HttpServer : MonoBehaviour
{
private HttpListener httpListener = new HttpListener();
// エディター上から設定する
public int port = 8080;
public string path = "/";
public bool startOnAwake = true;
// リクエスト処理するイベントハンドラー。エディター上から設定する。
public OnRequestEvent OnRequest;
void Start()
{
httpListener.Prefixes.Add("http://*:" + port + path); // http://*:8080/ のようになる
// コンポーネントの開始時に自動起動
if (startOnAwake)
{
StartServer();
}
}
// リクエストの受け付けを開始する
public async Task StartServer()
{
httpListener.Start();
while (true)
{
// リモートからの接続を待機
var context = await httpListener.GetContextAsync();
// 着信ログを表示
Debug.Log("Request path: " + context.Request.RawUrl);
OnRequest.Invoke(context);
}
}
// サーバーを停止する
public void StopServer()
{
httpListener.Stop();
}
// 破棄時にサーバーを止める
void OnDestroy()
{
StopServer();
}
}
そして、シーンに空のゲームオブジェクトを作成して、上記スクリプトをアタッチします。
こんな感じになると思います。
HTTPリクエストを処理する
もう一つ空のゲームオブジェクトを作り、以下のようなスクリプトを書きます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
public class MyRequestHandler : MonoBehaviour
{
public string message = "Hello from Unity!";
public void OnRequest(HttpListenerContext context)
{
// message の内容をバイト配列に変換してレスポンスを返す
var data = System.Text.Encoding.UTF8.GetBytes(message);
context.Response.StatusCode = 200;
context.Response.Close(data, false);
}
}
スクリプト同士をくっつける
最後に、HTTPサーバーのスクリプトとHTTPリクエストを処理するスクリプトをくっつけます。HTTPサーバーのゲームオブジェクトを選択してインスペクターのOn Request (HttpListenerContext)の部分の右下の+アイコンを選択して項目を一つ増やします。
None (Object)の右の丸いポチを選択して、先程HTTPリクエストを処理するスクリプトを設定したゲームオブジェクトを選択します。
No FunctionのドロップダウンからMyRequestHandler→OnRequestの順に辿ります。
動かしてみる
さてここまでできたら、ゲームを動かしてみましょう。ブラウザを開いてhttp://localhost:8080/にアクセスしてみてください。その後Unityエディターにフォーカスを戻さないとスクリプトが動かないのでHTTPレスポンスが返らないので注意してください。
ブラウザにHello from Unity!
という文字が出ていれば成功です。