SignalRのパラメータをカスタムオブジェクトで管理する

はじめに

ASP.NET Core SignalRを使った際に、扱うデータをオブジェクトでいい感じに管理したかったので方法を調べました。
JSONをstringifyしてもできますが、オブジェクトとして扱うことで型を厳密に管理したり入力補完を効かせたりできるので、扱うデータはオブジェクトとして管理したほうが良いです。
ドキュメントはこちらです。
docs.microsoft.com

カスタムオブジェクトを作る

IDと名前を扱うシンプルなオブジェクトを作ります。

public class JoinUserRequest
{
    public string ID { get; set; }
    public string Name { get; set; }
}

リクエストをカスタムオブジェクトとして受け取る

リクエストをカスタムオブジェクトとして受け取るコードはこちらです。

public async Task JoinUser(JoinUserRequest req)
{
    Console.WriteLine(req.ID);
    Console.WriteLine(req.Name);
}

JavaScript側からデータを送る際は以下のようなコードで実現できます。

connection.invoke('JoinUser', { ID: 'foo', Name: 'bar' });

データをオブジェクトとして送信する

サーバー側からクライアントに向けてオブジェクトとしてデータを送る際は以下のコードで送信できます。

await Clients.Caller.SendAsync("Joined", new
{
    Succeeded = true,
    Message = "Joined"
});

送信時は受信時のようにあらかじめクラスを宣言せずにオブジェクトを送ることができます。
JavaScript側では以下のようにオブジェクトとして受け取ることができます。

connection.on('Joined', res => {
    if (res.succeeded) {
        console.log(res.message);
    } else {
        console.error(res.message);
    }
});

おわりに

クライアント間でデータをやり取りするだけであればJSONを文字列化して送受信するだけで問題なく実現できます。しかし、クライアント側からデータを送り、サーバー側で何らかの処理をするといった場合にはどのような形式のデータを送るか、あらかじめオブジェクトとして定義しておいたほうが扱いやすいです。今回紹介した方法はASP.NET Core SignalRの標準機能だけでできるもので、Json.NETのようなライブラリも必要ありません。
型を厳密に管理することができるので、例えばクライアント側をTypeScriptで書いている場合などは親和性が高いかもしれませんね。