我在我的项目中使用Signalr,我在桌面上显示所有在线用户, 当用户更改页面时,将触发已断开连接的事件,然后连接。
在我看来,它不是很干净,因为用户被删除然后添加。 为了解决这个问题,我添加了一个计时器数组,当用户卸载页面时,我添加了 如果此用户仍然在线(在我的用户阵列中),将在5秒之后检查的计时器,如果不是,则视图将通知他已断开连接。 在OnConnected事件中,我将检查我的计时器阵列中是否存在计时器并将其处理,但是当我多次刷新并且用户未被删除时,有时它不起作用...
感谢您的帮助。
这里是我的代码示例:
private static readonly ConcurrentDictionary<string, ConnectTimer> ConnectionTimers = new ConcurrentDictionary<string, ConnectTimer>();
private class ConnectTimer : Timer
{
public ConnectTimer(double interval) : base(interval) { }
public object Id { get; set; }
}
private void OnVisitorDisconnected(Visitor visitor, string connectionId)
{
visitor.ConnectionIds.RemoveWhere(cid => cid.Equals(connectionId));
if (visitor.ConnectionIds.Any())
return;
Visitor removedVisitor;
Visitors.TryRemove(visitor.Id.ToString(), out removedVisitor);
/*********only after timer tick ****/
var timer = new ConnectTimer(DISCONNECT_TIMEOUT);
timer.Elapsed += VisitorDisconnected_Tick;
timer.Id = visitor.Id.ToString();
timer.Enabled = true;
ConnectionTimers[visitor.Id.ToString()] = timer;
/********************************/
}
public void VisitorDisconnected_Tick(Object source, ElapsedEventArgs e)
{
var timer = (ConnectTimer)source;
var visitorId = timer.Id.ToString();
var visitor = Visitors.FirstOrDefault(v => v.Key == visitorId);
if (visitor.Value != null)
{
ConnectTimer removedTimer;
ConnectionTimers.TryRemove(visitor.Id.ToString(), out removedTimer);
if (removedTimer != null)
{
removedTimer.Enabled = false;
removedTimer.Dispose();
}
return;
}
var ids = Agents.Values.Select(c => c.ConnectionIds).SelectMany(agentConnections => agentConnections).ToList();
Clients.Clients(ids).visitorDisconnected(visitorId);
}