当前位置: 首页 > 编程语言 > C#

SignalROnDisconnected-处理聊天室“用户在线”的可靠方法?

时间:2023-04-10 23:42:04 C#

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_connections=newDictionary();publicintCount{get{return_connections.Count;}}publicvoidAdd(Tkey,stringconnectionId){lock(_connections){HashSet连接;如果(!_connections.TryGetValue(key,outconnections)){connections=newHashSet();_connections.Add(键,连接);}lock(connections){connections.Add(connectionId);}}}publicIEnumerableGetConnections(Tkey){HashSet连接;如果(_connections.TryGetValue(key,outconnections)){returnconnections.ToList();}返回Enumerable.Empty();}publicvoidRemove(Tkey,stringconnectionId){lock(_connections){HashSet连接;if(!_connections.TryGetValue(key,outconnections)){返回;}lock(connections){connections.Remove(connectionId);如果(connections.Count==0){_connections.Remove(key);}}}}}根据dfowler建议更新,另一种方法是实现数据库内映射而不是内存中映射,这将使用更多元数据来识别僵尸连接我希望能够解决内存中问题,而不是重建已经实施的推荐方法。试试这个例子:https://github.com/DamianEdwards/NDCLondon2013/tree/master/UserPresenceC#学习教程就是这样:SignalROnDisconnected-处理聊天室“用户在线”的可靠方法?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: