休日使って2日間格闘してた

MagicOnionを業務で使う

MagicOnionは、基本的にUnity+.NET(C#)で使われるんですが、主にゲーム(Unity)で使われるライブラリなのでめっちゃ速い。
サンプルコードもめっちゃUnity(クライアント)+C#(サーバー)が多い。
Unityなしでなんとか使えるようにならないか。MagicOnion使って業務アプリを構築できないかと試行錯誤してみた。
github.com

今回の環境は

  • Visual Studio 2022
  • .NET 6
  • サーバー側はコンソールアプリケーション
  • クライアント側はWindows Form アプリケーション
  • DBアクセス先はSQL Server 2022
  • DBとの接続はDapper

そんな環境。

ハマったところのまとめ。

Dapper.FastCRUD.ModelGenerator でマッピングするクラスを生成していると、MessagePackのMessagePackObject属性が付かず、MessagePackを使ってそのままORMクラスをクライアント側に渡すことができないっぽいので、データを橋渡しするためのクラスを一つ作って間に挟んであげるとうまくいく感じ。

T4テキストテンプレートを改造してみたけど、ちょっとでも変えると動かなくなる。自動生成したクラスに、手動で [MessagepackObject] とか [MessagePack.Key(0)] とか追加すると、今度はDapperがおかしくなる予感(たぶん)。

また、Dapper.FastCRUD.ModelGenerator はapp.config(XML形式のconfig)を参照するのに対し、.NET 6 のConfigManagerはJSON形式のappsettings.json を参照するので、両方設定しないといけないのが面倒かな。

Dapperでアクセスする先のDBのテーブルに、スネークケースなテーブル名やフィールド名があると、うまくマッピングしてくれないので、その時は、Dapperのクエリを飛ばす前に、

Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;

を入れてあげると、ちゃんとマッピングしてくれる。
都度入れるとめんどくさいので、SQLクエリ発行用のクラスとメソッド作ってそこでやるか、オーバーライドすればいいのかな(よく知らない)。

…Dapper、なんであんな仕様なんだろ。前はスネークケースでもちゃんとマッピングしてくれたはず…

サーバー側の起動に関しては以下のGistを参照。
特にポート番号等の指定はなさそうだけど、既定だとポート5000で起動する(待ち受けIPアドレスとポートはコンソールに出力されるのでそこで確認)

MagicOnion Server Startup

クライアント側はフォームにボタン貼り付けて、そこのイベントで接続処理するか、フォームのコンストラクタで接続してあげるといいかも。
接続方法は

MagicOnion Client Connection
こんな感じでgRPCのチャンネルを上記のホストとポート名に設定してあげて、作成したIServiceを継承したインターフェイスに対してMagicOnionClient.Create してあげるといいかも。

切断…はコード書いたんですけど切断してくれてるのかなぁ…
まぁアプリ終了すれば切断されるから、今のところ、それ任せにしてるけど(たぶんよくない)。

--余談--
初めてインターフェイスを書いた。