【问题标题】:SignalR call OnDisconnect only after user closing the page/tabSignalR 仅在用户关闭页面/选项卡后调用 OnDisconnect
【发布时间】:2016-11-21 12:04:28
【问题描述】:

所以我正在使用 signalR 来创建在线用户列表。 我使用stopCalled 来避免页面刷新就像断开连接一样,但现在用户永远不会断开连接..

public override Task OnDisconnected(bool stopCalled)
{
    var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
    var currentUser = manager.FindByName(Context.User.Identity.Name);
    string name = currentUser.NickName;
    if (!(stopCalled))
    {
        var item = users.SingleOrDefault(x => x.Nick == name);
        if (item != null)
            users.Remove(item);
        userNames.Remove(name);
        Clients.All.hubReceived(users);
    }     
    return base.OnDisconnected(stopCalled);
}

用户只应在单击按钮(注销按钮)时断开连接 或者当他关闭标签/页面时。 我能做什么?

【问题讨论】:

    标签: c# jquery asp.net webforms signalr


    【解决方案1】:

    stopCalled 表示客户端是否为disconnected gracefully or not,因此您当前的方法将仅删除那些连接已断开的用户(例如:网络掉线)。

    对于所有在线用户的列表,计算每个用户的连接数。

    OnConnected

    • 如果在列表中没有找到用户,添加count = 1的用户
    • 如果用户在列表中,则增加计数

    OnDisconnected

    • 减少该用户的计数
    • 如果该用户为count = 0,则将该用户从列表中删除

    【讨论】:

    • 所以我试着按照你说的做..但它不起作用,因为回发导致计数下降到 0,从列表中删除然后再次连接..所以用户“闪烁" 刷新时从 0 到 1,这是我的问题:/
    • 好的。在这种情况下,还要使用在OnConnectedOnReconnected 中更新的LastConnected 时间戳。在OnDisconnected 中,如果计数为零,请不要删除用户。实现一个每隔x minutes 运行的自动作业,以删除具有count = 0LastConnected 的用户多于x minutes 之前的用户。使用自动作业调度程序来执行此操作,例如 FluentScheduler
    • 或者更简单,在刷新当前用户时增加一点延迟,这样它就不会闪烁了
    • 我不知道该怎么做,您认为可以将超时设置为“删除用户”jquery 函数,并检查用户连接或其他内容吗?我已经有一个多星期的麻烦了.. FluentScheduler 对我来说看起来有点太复杂了,我不确定你的第二条评论是什么意思
    • 来吧,没那么难。你得到了你需要的一切,只要把你的背放进去
    【解决方案2】:

    如果用户在线,那么他打开了多少个窗口都没有关系。 您应该通过他们的联系in database 来跟踪在线用户。

    如果用户刷新窗口,你会创建一个新的连接,所以之前的连接最终会断开。

    类似这样,我试着猜猜你应该编码什么。

    您应该在数据库OnlineUser 中创建一个表,其中包含ConnectionIdUserId

    public override Task OnConnected()
    {
        var onlineUserManager = NewOnlineUserManager<OnlineUser>(new OnlineUserStore<OnlineUser>(new ApplicationDbContext()));
        var onlineUser = onlineUserManager.FindByConnectionId(Context.ConnectionId);
    
        if (onlineUser == null)
        {
            var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
            var currentUser = manager.FindByName(Context.User.Identity.Name);
    
            onlineUser = new OnlineUser
            {
                ConnectionId = Context.ConnectionId,
                UserId = currentUser.Id
            };
    
            onlineUserManager.Save(onlineUser);
        }
    
        return base.OnConnected();
    }
    
    public override Task OnDisconnected(bool stopCalled)
    {
        if (stopCalled)
        {
            var onlineUserManager = NewOnlineUserManager<OnlineUser>(new OnlineUserStore<OnlineUser>(new ApplicationDbContext()));
            var onlineUser = onlineUserManager.FindByConnectionId(Context.ConnectionId);
    
            if (onlineUser != null)
            {
                onlineUserManager.Remove(onlineUser);
            }
        }
    
        return base.OnDisconnected(stopCalled);
    }
    

    您可能需要进行一些更改以支持一个用户的多个连接。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-19
      • 1970-01-01
      • 2014-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多