Help us understand the problem. What is going on with this article?

UnityでHTTPリクエストを処理してみる

More than 1 year has passed since last update.

Unityのゲームを動かしている間に外からHTTPでメッセージを送って制御したりするのをやりたかったので、ゲーム内でHTTPリクエストを処理する方法を調べました。

.NETに標準で搭載されているHttpListenerを使うことでHTTPリクエストを受け付ける処理を書くことができます。最近のUnityではスクリプトランタイムを.NET 4.6環境に設定することができてasync/awaitを使うこともできるので、より簡潔な方法で記述することができるようになりました。

本記事ではさらにUnityのイベントシステムと組み合わせることで、クリックイベントなどと同じような感覚でHTTPリクエストを処理できるようなしくみを作ってみました。

HTTPサーバーのコンポーネントを作る

まず、以下のようなスクリプトを書きます。

HttpServer.cs
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();
  }
}

そして、シーンに空のゲームオブジェクトを作成して、上記スクリプトをアタッチします。

キャプチャ.PNG

こんな感じになると思います。

HTTPリクエストを処理する

もう一つ空のゲームオブジェクトを作り、以下のようなスクリプトを書きます。

MyRequestHandler.cs
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)の部分の右下の+アイコンを選択して項目を一つ増やします。
2.PNG

None (Object)の右の丸いポチを選択して、先程HTTPリクエストを処理するスクリプトを設定したゲームオブジェクトを選択します。
3.PNG

No FunctionのドロップダウンからMyRequestHandler→OnRequestの順に辿ります。
4.PNG

こんな感じになったらOKです。
5.PNG

動かしてみる

さてここまでできたら、ゲームを動かしてみましょう。ブラウザを開いてhttp://localhost:8080/にアクセスしてみてください。その後Unityエディターにフォーカスを戻さないとスクリプトが動かないのでHTTPレスポンスが返らないので注意してください。
ブラウザにHello from Unity!という文字が出ていれば成功です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした