Liberent-Dev’s blog

株式会社リベル・エンタテインメントのテックブログです。

DFrameを試してみる

こんにちは!
システム開発部のK.Mです。

今回の記事の経緯

以前こちらの記事にてMemoryPackの記事を書きましたが、サーバがC#で動いておりMemoryPackでリクエストとレスポンスをやり取りする形になっていると、MemoryPackを扱うためにどうしてもC#が必要になってきます。

その場合に少し困るのが負荷テストです。
LocustやGatling、JMeterを使用する場合、C#でテストシナリオが書けないので、一時的にリクエストとレスポンスをJson形式にして負荷テストすることになるのですが、その場合だとMemoryPackを含めた本番想定の負荷テストが出来ない状況になってしまいます。

そのため、C#にてテストシナリオを書けてMemoryPackでのやり取りが出来るものを検討する必要があります。
その際の検討段階に上がってきたのが、DFrameとなります。
(neuecc氏の術中にはまっていっている感じがしますが・・・)

neuecc氏が書いたDFrameの記事はこちら
githubこちら

続きを読む

UnityでHTTP通信

こんにちは!
システム開発部のK.Mです。

今回の記事の経緯

UnityではUnityWebRequest()という通信するためのAPIが標準で用意されていますが、
HTTP/1.1だったりスレッド周りで画像などのリソースを大量にDLする時に使い勝手が悪かったりで、何とか簡単に通信出来ないのか?というお話です。

確認環境

OS:Mac
Unity:2021.3.12f1

単純にAPIと通信するなら

UnityWebRequest()で十分だと考えています。
しかし、画像などのアセットデータの小サイズ・多数を同タイミングでDLしたいとかだったり、非同期で通信したいとかのケースで困りがちです。
また、Unityのバージョンによっては不具合があったりで、正常に動かないこともあったりもするので要注意となります。参考1 参考2

諸々考えるとアセットの多重DLなどの処理には、HTTP/2で通信したいところです。

手っ取り早くHTTP/2で接続したい

BestHTTP/2などの外部アセットを使うのが手っ取り早いです。
ただ、ブラックボックスな外部アセットを使用したくない・使用できない場合はどうしたら良いのでしょうか?

Unity標準でHTTP/2対応してないの?

Unity2021.3のバージョンの場合、.NET Standard2.1(.NET4.x)に対応しているようなのでHttpClientを使ってHTTP/2が使えないのかと考えつきました?

2018.3以前だと.NET3.5なので、HTTP/2はそもそもサポートされていないので論外。

その1:.NETで使えるHttpClient

バージョン指定のためのプロパティが増えているので、それを使えばHTTP/2が使えそうなので試してみました。

上記のようにUnityではエラーが出てしまっており、.NET Standard2.1のHttpClientにはバージョン指定のプロパティが存在しませんでした。 そのため、現時点でのUnity標準のHttpClientではHTTP/2は使えないようです。

.NET5以上であれば、DefaultRequestVersionというプロパティが存在しているので、

static readonly HttpClient httpClient = new HttpClient();
{
    DefaultRequestVersion = new Version(2, 0)
};

という形でHTTP/2の指定が可能となっている。

または、HttpRequestMessageにもVersionが存在するので定義時に指定も可能になっています。

var request = new HttpRequestMessage(HttpMethod.Get, requestEndPoint) { Version = new Version(2,0) };

var request = new HttpRequestMessage(HttpMethod.Get, requestEndPoint);
request.Version = new Version(2,0);

という形で指定が可能となっています。

一先ず、UnityではHttpClientDefaultRequestVersionは使えないが、HttpRequestMessageでバージョンを指定する形は可能そうなのでやってみました。

実装一部抜粋

// HttpClient定義
static readonly HttpClient httpClient = new HttpClient();
---
// HttpRequestMessage宣言時にバージョン指定してログでバージョン確認
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestEndPoint) { Version = new Version(2,0) };
UnityEngine.Debug.Log("Request HTTP/" + request.Version);

HTTP/1.1HTTP/2のどちらかになったかは、レスポンスとして受け取るHttpResponseMessageのResult内のVersionに情報が入っていますので

// レスポンス内容からバージョン出力
response = httpClient.SendAsync(request);
UnityEngine.Debug.Log("Response HTTP/" + response.Result.Version);

のようにログ出力して動作させてみます。

結果、リクエスト時にはHTTP/2で指定しているにも関わらずレスポンスにてHTTP/1.1になってしまっておりました。

比較確認のために、.NET7のc#(コンソールアプリ)で同じような形で実装して確認すると下記にように、HTTP/2で動いていましたので、Unityの.NETだとやはりダメなようです。

その2:gRPC

少し途方に暮れていましたが、Unityが対応しているgRPCでHTTP/2が使えるじゃないか!ということで試してみようと調査してみましたが、
Grpc.Net.Clientでは、HttpClientが内部で動いている
という情報があり、Unity標準で使えるgRPCが結局HTTP/1.1までしか出来なさそうなので断念しました。

念のため、事の真相を確かめるべくGrpc.Net.Clientの軽くソースコードを覗いてみました。Grpc周りのソースコード

HttpVersion: HTTP protocol Version used to set HttpRequestMessage.Version on the underlying gRPC HTTP request. gRPC-Web doesn't require a specific version and doesn't override the default unless specified.

最終奥義:自前でHTTP/2が使えるように実装する

現時点でのUnityだとアセットストアから外部アセットを導入する以外には簡単にHTTP/2は使えなさそうなので、

  • libcurlなどをラッパーにして独自で実装する
  • nugetで色々パッケージを入れて整合性を取っていく

という方法もありそうですが、OS毎の考慮が必要だったりと中々に茨の道になりそうかと考えており、今回の記事上ではここまでとしたいです。

結論

早く、Unityで.NET CoreCLRを使えるように頑張っていただきたいものです。


リベル・エンタテインメントでは、このような最新技術などの取り組みに興味のある方を募集しています。もしご興味を持たれましたら下記サイトにアクセスしてみてください。
https://liberent.co.jp/recruit/

Matrixプロトコルを試してみよう -サーバー編-

はじめに

こんにちは。
システム開発部のこたつみかんと申します。

前回からだいぶ時間が経ってしまいましたが、今回はMatrixプロトコルのサーバー側実装を動かしてみます。
さまざまな理由でMatrixを取り巻く環境は大きく変わり、国内でも徐々に注目されるようになりました。
思ったより簡単にできますので、この機会にぜひ試してみてください。

Matrixのサーバー実装

現在Matrixのサーバー実装としてよく挙げられるものは以下の3つです。

  • Synapse
    • リファレンス実装です
    • 枯れているため動作も安定しており、このような記事ではよく紹介されます
    • Python3で開発されています
  • Conduit
    • 軽量なサーバー実装です
    • 2023年4月現在ベータ版です
    • 1クライアント1サーバーのような構成を意図しているため、システム要件は低いですが負荷への耐性が高いわけではありません
    • ドイツ連邦教育省の支援を受けています
    • Rustで開発されています
  • Dendrite
    • 第二世代のリファレンス実装として開発されています
    • 2023年4月現在ベータ版です
    • Goで開発されています

正式リリースされているのはSynapseのみという状況ですが、どのプロジェクトも活発に開発されています。

環境を構築してみる

それでは実際に環境を構築してみましょう。
現在はどの実装もDockerでの導入を紹介されるケースが多いのですが、動作の仕組みを確認するという意味で通常のインストールを行ってみます。
今回は軽量でご家庭での利用にも適したConduitを選んでみました。
公式の導入手順に沿ってDebian 11への導入を行っています。
なお、matrix-docker-ansible-deployも便利そうだったので試しに使ってみましたが、導入中にエラーが出て進行不能となってしまったため、残念ながら今回はご紹介できませんでした。

サーバー名を決める

導入中にサーバー名を設定する場面がありますので、インストール前にサーバー名を決めておいてください。
決まったらDNSにレコードを追加しておくのを忘れずに。

Conduitをインストールする

ConduitはLinuxで動作します。
パッケージは公式からdebが提供されています。
x86に加えてarmv7、armv8用もありますので、Raspberry Piのようなシングルボードコンピューターへの導入も可能です。
なお現在のビルドはDebian 11向けとなっていますので、glibcのバージョンが古い場合は自前でコンパイルが必要となります。

サービスを動かす準備をする

インストールが終了したら、サービスを動かすための準備をします。
まずは外部とのやり取りを行うため、ファイアウォールなどでポート番号443と8448を開放する設定を行います。

次にconduitを動かすためのconduitユーザーを作成します。

$ sudo adduser --system conduit --no-create-home

続いてsystemdへの登録を行います。
/etc/systemd/system/conduit.service を作成し、以下の通り設定を行います。

[Unit]
Description=Conduit Matrix Server
After=network.target


[Service]
Environment="CONDUIT_CONFIG=/etc/matrix-conduit/conduit.toml"
User=conduit
Group=nogroup
Restart=always
ExecStart=/usr/sbin/matrix-conduit


[Install]
WantedBy=multi-user.target

設定したら、

$ sudo systemctl daemon-reload

で反映させます。

Conduitの設定を行う

Conduit側の設定を行います。
設定ファイルは /etc/matrix-conduit/conduit.toml に作成します。

[global]
# The server_name is the pretty name of this server. It is used as a suffix for user
# and room ids. Examples: matrix.org, conduit.rs


# The Conduit server needs all /_matrix/ requests to be reachable at
# https://your.server.name/ on port 443 (client-server) and 8448 (federation).


# If that's not possible for you, you can create /.well-known files to redirect
# requests. See
# https://matrix.org/docs/spec/client_server/latest#get-well-known-matrix-client
# and
# https://matrix.org/docs/spec/server_server/r0.1.4#get-well-known-matrix-server
# for more information


# YOU NEED TO EDIT THIS
server_name = “サーバー名"


# This is the only directory where Conduit will save its data
database_path = "/var/lib/matrix-conduit/"
database_backend = "rocksdb"


# The port Conduit will be running on. You need to set up a reverse proxy in
# your web server (e.g. apache or nginx), so all requests to /_matrix on port
# 443 and 8448 will be forwarded to the Conduit instance running on this port
# Docker users: Don't change this, you'll need to map an external port to this.
port = 6167


# Max size for uploads
max_request_size = 20_000_000 # in bytes


# Enables registration. If set to false, no users can register on this server.
allow_registration = true


allow_federation = true


trusted_servers = ["matrix.org"]


#max_concurrent_requests = 100 # How many requests Conduit sends to other servers at the same time
#log = "warn,state_res=warn,rocket=off,_=off,sled=off"


address = "127.0.0.1" # This makes sure Conduit can only be reached using the reverse proxy
#address = "0.0.0.0" # If Conduit is running in a container, make sure the reverse proxy (ie. Traefik) can reach it.

設定ファイルを編集したらパーミッションを設定します。

$ sudo chown -R root:root /etc/matrix-conduit
$ sudo chmod 755 /etc/matrix-conduit
$ sudo mkdir -p /var/lib/matrix-conduit/
$ sudo chown -R conduit:nogroup /var/lib/matrix-conduit/
$ sudo chmod 700 /var/lib/matrix-conduit/

リバースプロキシを設定する

Conduit自体はlocalhostの6167ポートで動いていますので、外部から到達できるようになんらかのWebサーバーでリバースプロキシを作ります。
今回はCaddyを使ってみます。
Caddyは設定が簡単でかつ証明書処理がデフォルトで自動化されており、HTTPS対応のサイトをすぐに準備できます。
/etc/caddy/Caddyfile に以下の設定を記載します。

サーバー名, サーバー名:8448 {
        reverse_proxy /_matrix/* 127.0.0.1:6167
}

記載したら設定を反映させます。

$ sudo systemctl enable caddy

動かしてみよう

これで設定は終わりです。
動かしてみましょう。

$ sudo systemctl start conduit

Elementで接続してみます。
指定したサーバー名を記入して、続行するを押してみましょう。
接続できました。

他のサービスとのBridgeやその他のオプションに対応するためにはさらに設定が必要なのですが、テキストメッセージのやり取りを行うだけであればこれで環境の構築は完了となります。

まとめ

いかがだったでしょうか。
思ったより簡単に動かすことができたかと思います。
大型連休中ですので、この機会にぜひmatrixを試してみてください。


リベル・エンタテインメントでは、このような最新技術などの取り組みに興味のある方を募集しています。もしご興味を持たれましたら下記サイトにアクセスしてみてください。 https://liberent.co.jp/recruit/

ASP.NET Coreを初めて触りつつMemory Packを試してみた2

こんにちは!
システム開発部のK.Mです。

前置き

前々回前回のMemoryPackの記事にて、MemoryPackを色々触ってみましたが、まだ少しやり残したことがありましたので、やり残した分の内容となっております。

速度確認

公式では数倍違うという記載になっておりましたが、実際のところどれ位違うのかをMessagePackとMemoryPackで速度計測してみました。

下記の3ケースで後述しているデータ構造体40万件をサーバから送り、クライアント(Unity)にてデシリアライズ処理をする箇所にて計測しています。

  • MessagePack(未圧縮:約20MBのデータサイズ)
  • MemoryPack(未圧縮:約14MBのデータサイズ)
  • MessagePack(LZ4圧縮:約4MBのデータサイズ)
    • 念のため参考用

MemoryPackの圧縮がLZ4がデフォルトで記事作成している現在未対応になっているので、対応されるのを期待したいところです!

  • https://neue.cc/2022/11/04_memorypack.html

    MemoryPackの実装と統合された効率的な圧縮については、現在BrotliEncode/Decodeのための補助クラスを標準で用意しています。しかし、性能を考えるとLZ4やZStandardを使えたほうが良いため、将来的にはそれらの実装も提供する予定です。

続きを読む

ASP.NET Coreを初めて触りつつMemory Packを試してみた for Unity

こんにちは!
システム開発部のK.Mです。

前置き

liberent-dev.hatenablog.com

前回のMemoryPackの記事にて、APIとwebにてMemoryPackを使用したシリアライズ・デシリアライズの実装をしました。

今回はAPIをそのまま使用して、UnityにてMemoryPackデータをデシリアライズしてコンソールや画面上に表示するということをやっていきます。

前回同様、サーバ・バックエンドは触ったことはあるけど、Unity/C#は初めて使う人を想定しております。

開発環境

Unityのインストール

MemoryPackがUnityのバージョン2021.3以上のものが対象になっているため、2021.3以上のものをインストールしていきます。

Unityを直接インストールせずに、UnityHubというものをインストールしたうえで2021.3以上のものをUnityHubから指定してインストールする手順となります。

  1. Unityのダウンロードページへアクセスします。
  2. Mac用のダウンロードのリンクを選択します。(Mac以外であれば、各OS用のリンクを選択してください。)
  3. UnityHubSetup.dmgがダウンロードされるので、ダウンロード後に実行します。
  4. セットアップ画面が表示されるので[Agree]を選択します。
  5. 処理中画面が出たのち、少し待つとApplicationsへドラッグ&ドロップする画面が表示されるので、UnityHubアイコンをApplicationsへドラッグ&ドロップします。
  6. コピー中画面が表示されるので、少し待つとApplicationsにUnityHubがインストールされます。
  7. UnityHubをインストールする画面を閉じます。
  8. Launchpadを開いて、UnityHubがインストールされていることを確認、選択して起動します。
    (もし起動時に下記のような開いても良いかの確認ダイアログが出た場合は[開く]を選択してください)
  9. UnityHub起動後にUnityのアカウントにログインをする画面が表示されるため、Unityアカウントを作成します。
    UnityHub画面の[アカウントを作成]のリンクか、こちらからUnityIDを作成してください。
  10. UnityID作成後、UnityHubにてサインインします。
  11. サインイン後に初回起動時にエディターインストール画面が表示されるので2021.3以上のバージョンになっているのを確認して、[Unityエディターをインストール]ボタンを選択しインストールを行います。
  12. 初回起動のインストール画面からインストールをすると、Androidビルドに必要なものがインストールされていないので、下記の操作して別途インストールする必要があります。
    1. エディター一覧の右側にある歯車ボタンを選択し、モジュールを加えるを選択します。
    2. 追加するモジュール一覧画面が表示されるので、Android Build Supportにチェックを入れて次へを選択します。
    3. 利用規約画面が表示されるので同意部分のチェックボタンをONにして[インストール]ボタンを選択するとインストールが開始されるので、終了するまで待ちます。
    4. インストール完了後、UnityHubのエディター一覧にてAndroidの表示があればOKです。

上記でUnity関連のインストールが完了となります。

続きを読む