1

私は .Net Framework 4.5.2 を使用しています。Web アプリケーションから、Windows フォーム デスクトップ アプリケーションから接続されているユーザーに通知を送信する通知システムの作成を開始します。

調査の結果、適切なソリューションは、接続されたクライアントに送信する前に通知をフィルタリングすることをサポートしているため、signalR を使用していることがわかりました。

しかし、ここでの私の懸念は次のとおりです。WebアプリケーションでHUBクラスを作成したとき、サーバーに接続して通知を受信するクライアントを検出するメソッドOnConnectedを実装し、接続されたユーザーを辞書に収集することを考えました(メモリ) 接続されたユーザーをメモリ変数 (辞書) に設定することは信頼できないため、本番環境では実装できないソリューションであることはわかっています。私の場合、接続ユーザー数は 20,000 人以上になる可能性があり、今後さらに増える可能性があります。接続されているすべてのユーザーを追跡する最善の方法を知る必要があります。同時に、スケーラビリティの問題を発生させずに同時リクエストを処理するための最善の方法を知る必要があります。私はこれに慣れていないので、非常に迅速に決定を下す必要があります。

また、ハブ クラスでオーバーライドできる OnReconnect メソッドの使用方法を知る必要があります。

また、iis が何らかの理由でインターネット アプリケーションを再起動した場合に備えて、接続が失われないように処理する方法も知っておく必要があります。

4

1 に答える 1

3

ユーザーへの接続のマッピングは、目的に応じて複数の方法で実行できます。

メモリー内ストレージ:
これを行う最善の方法は、並行辞書を使用することです。これにより、スレッドセーフな操作が可能になりますが、あなたが言ったように、膨大な数の接続に対する最適なソリューションではありません。

永続的な外部ストレージ
マッピングをデータベースに保持します。
良い点:マッピングは複数の Web サーバーで利用可能です
悪い点:データベースに多くのストレスがかかり、多くのクリーンアップが必要です

シングル ユーザー グループ ユーザー
ごとに 1 つのグループを作成します。これは最もシンプルで実用的なソリューションです。

良い点:
~ 使用と実装が非常に簡単
~ SignalR は、切断時にグループから接続を削除するほどスマートです ~
最後の接続を削除すると、グループは削除されます
~ Identity を使用する場合、一意のグループ名を[1] [2]を主張し、次のような方法でハブ内に取得します。

public static class IdentityExtensions
{
    public static string GetSignalRUniqueGroup(this IIdentity identity)
    {
        var claimsIdentity = identity as ClaimsIdentity;
        var claim = claimsIdentity?.FindFirst("uniqueSignalRGroup");
        if (claim == null) return null;

        try
        {
            return claim.Value;
        }
        catch
        {
            return null;
        }
    }
}

(それほどではない)悪い点:どのユーザーがどのグループに参加するかに注意する必要があります。!しない!クライアント側でグループ参加機能を実装します。代わりに、OnConnected と OnReconnected を使用して接続をグループに追加します。

public override Task OnConnected()
{
    string userGroup = Context.User.Identity.GetSignalRUniqueGroup();
    if(userGroup != null) 
    {
        Groups.Add(Context.ConnectionId, userGroup);
    }

    return base.OnConnected();
}

public override Task OnReconnected()
{
    string userGroup = Context.User.Identity.GetSignalRUniqueGroup();
    if(userGroup != null) 
    {
        Groups.Add(Context.ConnectionId, userGroup);
    }       
    return base.OnReconnected();
}

public override Task OnDisconnected(bool stopCalled)
{
    //You should not manually remove the user from the group when the user disconnects. 
    //This action is automatically performed by the SignalR framework.
    return base.OnDisconnected(stopCalled);
}

他の質問については、これを読むことができます: SignalR での接続有効期間イベントの理解と処理

于 2016-05-26T10:25:33.633 に答える