我目前将用户保存在名为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();
}
}
答案 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.");
}
}