4

現在、ユーザーを OnlineUsers というテーブルに保存しています。人が接続または切断すると、ユーザーIDと彼の接続IDがテーブルに追加されますが、何らかの理由で(複数のブラウザーウィンドウが開いていると思います)、切断機能が起動しないことがあり、ユーザーがテーブルに残り、「オンライン」に表示されます」 彼らが本当にそうでないとき。以前にこの問題に遭遇した人はいますか?この問題を解決する良い方法は何ですか?

更新** (コードを入れなくてすみません、最初からやるべきでした)

テーブルに追加および削除するdb関数は次のとおりです。

    public bool ConnectUser(Guid UserId, String ConnectionId)
            {
                if (!Ent.OnlineUsers.Any(x => x.UserId == UserId && x.ConnectionId == ConnectionId))
                {
                    Ent.OnlineUsers.AddObject(new OnlineUser { UserId = UserId, ConnectionId = ConnectionId });
                    Ent.SaveChanges();
                    return true;
                }
                else
                    return false;
            }
            public void DisconnectUser(Guid UserId, String ConnectionId)
            {
                if (Ent.OnlineUsers.Any(x => x.UserId == UserId && x.ConnectionId == ConnectionId))
                {
                    Ent.OnlineUsers.DeleteObject(Ent.OnlineUsers.First(x => x.UserId == UserId && x.ConnectionId == ConnectionId));
                    Ent.SaveChanges();
                }
            }

これが私のハブクラスの接続および切断タスクです。

 public Task Disconnect()
        {

            disconnectUser();                
            return null;
        }
        public Task Reconnect(IEnumerable<string> connections)
        {
            connectUser();                
            return null;
        }
        public Task Connect()
        {
            connectUser();               
            return null;
        }
private void connectUser()
        {
            if (onlineUserRepository.ConnectUser(MainProfile.UserId, Context.ConnectionId))
            {
                Groups.Add(Context.ConnectionId, Convert.ToString(MainProfile.ChatId));
            }
        }
        private void disconnectUser()
        {
            onlineUserRepository.DisconnectUser(MainProfile.UserId, Context.ConnectionId);
            Groups.Remove(Context.ConnectionId, Convert.ToString(MainProfile.ChatId));
        }

signalR の最新バージョン (0.5.3) を使用していることを確認しました。これは、複数のブラウザー ウィンドウを開いているときにそれらをすべて一度に閉じると、ユーザーがデータベースでスタックしてしまうようです。

これが必要な場合、これは私の Connection Id Generator クラスです:

public class MyConnectionFactory : IConnectionIdGenerator
    {
        public string GenerateConnectionId(IRequest request)
        {            
            if (request.Cookies["srconnectionid"] != null)
            {
                return request.Cookies["srconnectionid"].ToString();
            }

            return Guid.NewGuid().ToString();
        }
    }
4

1 に答える 1

7

あなたの接続ファクトリーは確かに問題だと思います。Cookieが見つからない場合は、先に進んで新しいGUIDを生成しますが、その時点ではすでに手遅れです。

私の理解では、接続IDは初期化中にクライアント(クライアント側ハブ)によって確立され、サーバーで変更することはできません。読むことしかできません。実際には、Cookieが見つからないときに新しいGUIDを返す場合、クライアントIDを変更します。

私の接続ファクトリでは、Cookieが見つからない場合はスローします。Signalrを使用しているページを開くコントローラーアクションで、Cookieが設定されていることを確認します。

これが私の接続ファクトリーです:

public class ConnectionFactory : IConnectionIdGenerator
{
    public string GenerateConnectionId(IRequest request)
    {
        if (request.Cookies["UserGuid"] != null)
            return request.Cookies["UserGuid"].Value;

        throw new ApplicationException("No User Id cookie was found on this browser; you must have cookies enabled to enter.");
    }
}
于 2012-11-09T02:14:35.630 に答える