しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

ASP.NET SignalR 2.0 が公開されました

Windows 8.1 や Visual Studio 2013 のリリースと同時に ASP.NET 周りも大幅にアップデートされたのですが、SignalR 2.0 で追加された機能が実に便利そうだったので紹介したくなりました。

とりあえず、まずはリリースノートを確認しておきましょう。

Release 2.0.0 · SignalR/SignalR · GitHub

例外のハンドリング改善も非常に喜ばしいですが、注目は「ユーザー」へ簡単にメッセージを送信できるようになったことでしょうか。

ここで言うユーザーとは、HttpContext.User のことです。フォーム認証や Windows 認証などを使っている場合に、ASP.NET が自動的にセットしてくれる、あのユーザーです。

そして SignalR 2.0 では「ユーザー」に対してメッセージを送信するための Clients.User/Users メソッドが追加されました。

ちょっとわかりにくいと思うので図にしてみます。

f:id:shiba-yan:20131021003326p:plain

例えば userB から userA にメッセージを送る場合、今まではコネクション ID とユーザー情報をストレージなどでマッピングしておく必要がありました。何故なら、コネクション ID はクライアントとの接続ごとに生成されるユニークな値だからです。

そして、そのコネクション ID に対して ASP.NET SignalR 2.0 リリース候補版が公開されました - しばやん雑記 でも紹介したようなコードで送信を行う必要があったのですが、SignalR 2.0 でユーザーと言う概念が追加されたので、userA という名前だけわかっていれば一括で送信できるという訳です。

ちなみに SignalR 2.0 ではユーザーでコネクションをグルーピングするために、IUserIdProvider というインターフェースが追加されました。

public interface IUserIdProvider
{
    string GetUserId(IRequest request);
}

デフォルトの実装は HttpContext.User.Identity.Name プロパティの値を返すようになっています。

Windows 認証やフォーム認証では問題なく動作すると思いますが、ACS などを使ったクレームベース認証の場合は Identity.Name が空になる場合があり、その場合は認証が通っていてもユーザーを判別できないので、ClaimTypes.NameIdentifier を使って独自に実装しましょう。

// IUserIdProvider の実装を入れ替える
GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => new ClaimsUserIdProvider());

ClaimsUserIdProvider というクラスを実装した場合、このようなコードで入れ替えが可能です。プロバイダ自体の実装はめんどくさいので省略します!