はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】YetAnotherHttpHandlerを用いてHTTP/2を扱えるHttpClientを作成する

はじめに

今回はYetAnotherHttpHandlerを用いてUnityでHTTP/2を扱う方法を紹介したいと思います。

背景

まず.NETが提供するHttpClientですが、.NET Core3.0以降であればHTTP/2に対応しています。
HttpClient クラス (System.Net.Http) | Microsoft Learn

var client = new HttpClient
{
    BaseAddress = new Uri("https://localhost:5001"),
    DefaultRequestVersion = new Version(2, 0)
};

using var response = await client.GetAsync("/");
Console.WriteLine(response.Content);

.NET Core 3.0 の新機能 - .NET | Microsoft Learn


現在対応しているUnityのランタイムの最新は.NET Standard2.1ですが、まだHttpClientがHTTP/2に対応していません。(全てはMonoのせい)
learn.microsoft.com

UnityでHttp/2を扱いたい場合はどうすればよいのかという話になるわけですが、そこでYetAnotherHttpHandlerが登場します。

概要

YetAnotherHttpHandlerによりUnity(.NET Standard2.1)でHTTP/2を利用することができるようになります。ライブラリが提供するYetAnotherHttpHandlerHttpMessageHandlerを継承しており、HttpClientのコンストラクタに渡すだけでHTTP/2を利用するようになります。

// .NETの内部実装
public HttpClient(HttpMessageHandler handler)  : this(handler, true){ }
// YetAnotherHttpHandlerの内部実装
public class YetAnotherHttpHandler : HttpMessageHandler

https://github.com/dotnet/runtime/blob/0154a2f3403d94ea6d6f93f5a774b6e366969e0a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClient.cs#L142-L151
github.com

つまりユーザーはいつも通りHttpClientを利用するので、使い心地をほとんど変える必要がないという素晴らしさです。

YetAnotherHttpHandler brings the power of HTTP/2 to Unity and .NET Standard.

This library enables the use of HTTP/2, which Unity does not support. It allows you to use grpc-dotnet instead of the deprecated C-core gRPC library. It can also be used for asset downloading via HTTP/2, providing more functionality to your projects.

The library is implemented as a HttpHandler for HttpClient, so you can use the same API by just replacing the handler. (drop-in replacement)

YetAnotherHttpHandlerはHTTP/2のパワーをUnityと.NET Standardにもたらします。 このライブラリはUnityがサポートしていないHTTP/2の使用を可能にします。 非推奨のCコアgRPCライブラリの代わりにgrpc-dotnetを使用することができます。 また、HTTP/2経由のアセットダウンロードにも使用でき、プロジェクトにさらなる機能を提供します。 このライブラリはHttpClientのHttpHandlerとして実装されているので、ハンドラを置き換えるだけで同じAPIを使用できます。 (ドロップイン置き換え)

https://github.com/Cysharp/YetAnotherHttpHandler

環境

  • Unity 2021.3 (LTS) or later

Architecture/Platformの対応について詳細はreadmeをご覧ください。
Builder in hyper_util::client::legacy - Rust

インストール方法

最近CySharpさんはNuGetForUnityやUnityNuGetを採用してきていますが、私は考え方が古いのかUPMの方が良いのかなとまだ思ってます... (何故かライブラリを信用できない)

というわけでUPMでインストールするには以下のURLをUnity Package ManagerのAdd package from git URL...に入力してください。

https://github.com/Cysharp/YetAnotherHttpHandler.git?path=src/YetAnotherHttpHandler
UPMによるインストール

追加で依存先のライブラリをインポートする必要があります。

Releasesに依存先のdllを含めた.unitypackageを上げておいてくれてるみたいです。Cysharp.Net.Http.YetAnotherHttpHandler.Dependencies.unitypackageをインストールしてUnityへインポートすればOKです。
github.com


それかnuget.orgから直接取ってくる手法も一応あります。Download packageを押して以下の手順で操作をします。

  • .nupkgをダウンロード
  • 拡張子を.zipに変更して展開
  • system.io.pipelines.8.0.0/lib/netstandard2.0/System.IO.Pipelines.dllをUnityのPluginsフォルダに配置
  • system.runtime.compilerservices.unsafe.6.0.0/lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dllを同様にPluginsフォルダに配置

使い方

YetAnotherHttpHandlerを生成して、HttpClientのコンストラクタに渡してあげます。

using System.Net.Http;
using Cysharp.Net.Http;
using UnityEngine;

public class Sample : MonoBehaviour
{
    private async void Start()
    {
        using var handler = new YetAnotherHttpHandler();
        using var httpClient = new HttpClient(handler);

        // 適当にブログのページを取得します。HTTP/2に対応していることは確認済です。
        var result = await httpClient.GetAsync("https://www.hanachiru-blog.com/");

        // HTTP message version : 2.0
        var version = result.Version;
        Debug.Log(version);

        var content = await result.Content.ReadAsStringAsync();
        Debug.Log(content);
    }
}

github.com

HTTP/2で通信に成功している

正しく通信できることを確認できました。

さいごに

readmeに書かれている通り、Grpc.Netに移行でHTTP/2が必要になり利用されるケースが多いようです。

そこら辺も詳しくreadmeにかかれているので、気になる方はチェックしてみてください。
github.com