SignalROnDisconnected-处理聊天室“用户在线”的可靠方法?我正在实施一个聊天室。到目前为止一切顺利——用户可以通过JS客户端从他们的浏览器发送消息,我可以用C#客户端做同样的事情——这些消息被广播给其他用户。现在,我正在尝试实施“在线用户”。我的方法如下:我遇到的问题是OnDisconnected并不总是为每个客户端ID调用-陈旧的连接阻止“如果用户没有任何其他连接”位解析为真,那么用户始终“在线”。我能想到的一个hacky解决方案是始终在OnDisconnect上将用户设置为离线-但这意味着如果用户打开两个选项卡并关闭一个选项卡,它们将处于“离线”状态。然后我可以将用户重新设置为在线以发送每条消息,但这似乎完全浪费了处理周期,并且仍然留下了一段时间,用户在实际在线时被视为离线。我相信如果有办法保证为每个客户端调用OnDisconnected,这个问题就会消失。似乎如果我让客户端长时间打开(>10分钟)然后断开连接,OnDisconnected永远不会被调用。我将尝试确定重现步骤并保持更新。那么-这是处理在线状态的有效方法吗?如果是这样,有没有办法确保OnDisconnected最终会为每个连接触发?这个问题让我很担心,因为现有的连接会随着时间的推移继续增长,如果我没记错的话最终会由于未处理的有状态连接而溢出。代码:我正在使用内存中的分组方法。发送消息(C#):privatereadonlystaticConnectionMapping_chatConnections=newConnectionMapping();publicvoidSendChatMessage(stringkey,ChatMessageViewModelmessage){message.HtmlContent=_compiler.Transform(message.HtmlContent);foreach(varconnectionIdin_chatConnections.GetConnections(key)){Clients.Client(connectionId).addChatMessage(JsonConvert.SerializeObject(message).SanitizeData());}}国家管理:publicoverrideTaskOnConnected(){HandleConnection();返回base.OnConnected();}publicoverrideTaskOnDisconnected(){HandleConnection(true);返回base.OnDisconnected();}publicoverrideTaskOnReconnected(){HandleConnection();返回base.OnReconnected();}privatevoidHandleConnection(boolshouldDisconnect=false){if(Context.User==null)return;varusername=Context.User.Identity.Name;var_userService=newUserService();变种键=用户名;如果(shouldDisconnect){_chatConnections.Remove(键,Context.ConnectionId);varexistingConnections=_chatConnections.GetConnections(key);//这就是问题所在-existingConnections有时会达到始终存在连接的程度-就好像从未为该客户端调用OnDisconnected()if(!existingConnections.Any()){//这就是问题所在-existingConnections有时包含连接,尽管没有打开的选项卡/客户端//保存状态服务器端varonlineUserDto=_userService.SetChatStatus(username,false);SendOnlineUserUpdate(_baseUrl,onlineUserDto,false);}}else{if(!_chatConnections.GetConnections(key).Contains(Context.ConnectionId)){_chatConnections.Add(key,Context.ConnectionId);}varonlineUserDto=_userService.SetChatStatus(Context.User.Identity.Name,true);SendOnlineUserUpdate(_baseUrl,onlineUserDto,true);//广播给客户端}}ConnectionMapping:publicclassConnectionMapping{privatereadonlyDictionary
