在signalR中有时断开不连接

时间:2012-11-06 00:19:54

标签: c# asp.net signalr

我目前将用户保存在名为OnlineUsers的表中。当一个人连接或断开时,它会将userid和他的connectionid添加到表中,但由于某种原因(我相信当多个浏览器窗口打开时),Disconnect功能有时不会触发,将用户留在表中并使其显示为“online” “当他们真的不是。有没有人遇到过这个问题,什么是解决这个问题的好方法?

更新**(抱歉没有放入代码,我应该首先完成它)

以下是我在表格中添加和删除的数据库函数:

    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)上,这似乎发生在我打开多个浏览器窗口并且我立即关闭它们时,用户将卡在数据库中。< / p>

如果需要,这是我的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();
        }
    }

1 个答案:

答案 0 :(得分: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.");
    }
}