1

私のアプリにはたくさんの UserGroups があります。

これらのユーザー グループの 1 つまたは多数に通知を送信できる管理ページがあります。

WebAPIメソッドへのAJAX呼び出しを介してデータベースに保存された後、管理者が通知を投稿できるハブがあります。これが Ajax 成功セクションに返されたら、サーバー ハブでメソッドを呼び出して、リアルタイムで 1 つ以上のグループに通知を送信します。グループは、int を .ToString() で変換するだけでグループ名を作成する int の配列で示されます。

クライアントのホームページには、通知を表示するウィジェットがあります。一部のユーザーは複数の userGroup の一部になることができますが、ページの上部に、現在表示している UserGroupd を指定するドロップダウン リストがあります。したがって、それらは多くの UserGroups の一部である可能性がありますが、一度に表示できるのは 1 つだけです。

したがって、私は Jabbr Chatrooms のようにやっていると思いますが、アプリの意図が異なるため、あまり設定したくありません。そのため、クライアントがログインすると、ドロップダウンリストの Selected 項目の値に基づいてグループに参加します。クライアントとしてページを更新するたびに、「Join」サーバー メソッドが新しい connectionId で再度呼び出されることに気付きました。これは正しいですか?実際よりも多くの接続を持ちたくありません。また、クライアントがドロップダウンリストを変更したときに、クライアントをグループから切断し、新しいグループに再参加させる必要があります。

デモを探していますが、非常に簡単なデモまたは非常に洗練されたデモを見つけました。サイトには SignalR 機能を追加する予定の他の領域があるため、オブジェクトをロックダウンしたくないため、最初はその中間を目指しています。モデルしすぎ。

だから私のハブで私は得た:

public void Join(string groupName) {
  Groups.Add(Context.ConnectionId, groupName);
}

public void SendNotificationsToGroups(string title, string description, int[] groups) {
        foreach (int i in groups) {
            Clients.OthersInGroup(i.ToString()).addMessage(Title, description);
        }
}

管理ページは SendNotificationsToGroups を呼び出し、これは正常に機能します。ご覧のとおり、通知をブロードキャストするグループである int の配列を渡します。GroupNames を作成するために int を .ToString するだけです。

クライアントは次のことを行います。

var Hub = $.connection.myHub;

Hub.client.addMessage = function (title, description) {
  $('#Notification').find('tr:first').before('<tr><td>'+title+description'</td></tr>');
}

$.connection.hub.start().done(function () {
    var groupId = $('#userGroupID').val();
    newsHub.server.join(groupId);
}

私の主な関心事は、 addMessage 部分が機能するため、 join メソッドです!! 管理者が通知を送信し、クライアントがそれらを確認します。問題は、クライアントがブラウザを更新した場合、サーバーで Join が再度呼び出され (ブレークポイントが設定されています)、新しい Context.ConnectionId が含まれていることです。これは悪いですか?これにより、必要以上の接続が発生していますか。ウィンドウが閉じられてクライアントがページを離れた場合に接続を確実にするために行う必要があるjavascript/jQuery呼び出しはありますか?ブラウザの更新の問題はどうですか?

アイデアをありがとう。

4

2 に答える 2

0

私がそれを解決した方法は、ユーザーのセッションと connectionId をユーザーとの 1 対多のテーブルに格納することでした。たとえば、上記に加えて、ホスト、接続時間、切断時間、ユーザー エージェントなどの追加情報を格納する PersonSession テーブルを作成できます。

OnConnected()次のコードを使用して、メソッドでセッションを取得できます。

var session = Context.RequestCookies.ContainsKey("ASP.NET_SessionId") ? Context.RequestCookies["ASP.NET_SessionId"].Value : null;

それをconnectionIdとともにdbに保存します。このOnDisconnected()メソッドでは、DisconnectTiemstamp を使用してこのレコードを更新するだけです。

次に、それらが更新されると、以前のレコードを確認できます (私はいつでも 1 人のユーザーに対して最大 3 つのレコードを保持しています)、同じセッションがあるかどうかを確認し、同じセッションがある場合は更新しません。これが新しいセッションであることを確認し、更新を行います。

if (session != null)
{
     var MyInActiveSessions = p.PersonSessions.Where(x=>x.DisconnectTimestamp != null);
                            bUpdateStatus = !MyInActiveSessions.Any(x => x.SessionID != null &&          x.SessionID == session);
}

また、ASP.net はログアウトしても古いセッション Cookie を保持するため、ログイン時にセッション Cookie を強制的に再生成する必要があることに注意してください。これを行うには、いくつかのことを行う必要があります。

  1. ログイン コードで、Session 変数に任意のランダムな値を入力して、ASP.NET に強制的に Cookie を生成させます (例: Session['0'] = 0;) 。
  2. ログアウト コードで、セッションを破棄し、Cookie を応答に追加します。

    Session.Abandon(); Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));

  3. 最後に、Web.config で、セッションが自動的に再生成されることを確認します。

<sessionState mode="InProc" cookieless="false" regenerateExpiredSessionId="true"></sessionState>

お役に立てれば。

于 2013-08-16T23:32:54.797 に答える
0

SignalRは、ウィンドウのアンロード イベントをフック.stop()し、接続で呼び出しますが、非同期メッセージで行うため、すぐには発生しない可能性があります。また、サーバー側は、ハウスキーピング作業の一環として、「デッド」接続を自動的に検出して除外します。

とは言っても、すべてのページ ナビゲーションで切断/再接続するのではなく、可能であれば SignalR 接続を維持することをお勧めします。常に接続を切断して再接続すると、目的が果たせなくなり、ページ ナビゲーション間でいくつかのメッセージを見逃す可能性があります。

于 2013-07-12T00:21:58.413 に答える