我担心在C#Signal R集线器类中使用Clients.All
Clients.All.setConnectionStatus(profileId, true);
我在OnConnected()
和OnDisconnected(bool stopCalled)
中都称呼它
显示我已登录用户的在线状态。
OnDisconnected()
并不那么糟糕,因为只有在有人实际注销时才会调用它
例如。
public override Task OnConnected()
{
string profileId = Context.User.Identity.Name;
_connections.Add(profileId, Context.ConnectionId);
Clients.All.setConnectionStatus(profileId, true);
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
string profileId = Context.User.Identity.Name;
_connections.Remove(profileId, Context.ConnectionId);
if (stopCalled == false) // log off only
Clients.All.setConnectionStatus(profileId, false);
return base.OnDisconnected(stopCalled);
}
我的关注->使用浏览器中不断运行的javascript代码来炸毁用户计算机客户端!
场景->如果我有大约1000位用户在线并登录到其他页面,则我将向所有人广播信号R连接Clients.All.setConnectionStatus(profileId, true);
在javascript中心中看起来像这样,很容易最终炸毁用户浏览器,因为它将不断接收这些广播连接状态呼叫!
scope.chat = $.connection.chatHub;
// Receive and set the connection status
scope.chat.client.setConnectionStatus = function(profileId, isConnected) {
// look for prfileId in html
var $profileStatusElement = $(".online-status-profile[data-id='" + profileId + "']");
var $profileChatElement = $(".online-status-chat[data-id='" + profileId + "']");
if (isConnected === true) {
// change the online status
} else {
// change the online status
}
};
我有一个向用户聊天的窗口(在线),如下所示,该窗口在用户名旁边显示用户状态。所以我知道我要发送消息的对象是否在线!
当我第一次加载聊天框时,我会获取在线状态服务器端,但此后取决于我的中心中的OnConnected()
和OnDisconnected()
方法来设置我的联系人的在线状态我正在聊天。
有一种更好的方法,然后将信号广播给我网站上的“所有”在线用户?但是我唯一能想到的方法就是每隔一段时间在一些javascript计时器上轮询状态,但是我讨厌这个主意!
另一种方法是保留每个人正在与谁聊天的内存中集合,但是这看起来可能会变得非常混乱,并且最终可能变得不太准确,因为可能有很多东西在客户端和服务器之间可能会导致中断,从而无法正确管理与谁建立连接的用户的内存中集合!这里的任何想法都将不胜感激!
仅供参考->我还有一个消息页面,其中显示了我与以下用户最近进行的所有对话的列表。在此页面上,我还将显示这些用户的在线状态。在此页面上,我渲染页面之前会获取服务器上每个用户的在线状态,与聊天框相同,但是一旦页面被加载,则取决于OnConnected()
和OnDisconnected(bool stopCalled)
的设置页面上每个用户的在线状态。
答案 0 :(得分:3)
您使用signalR的方式正确。我会根据您的担忧/情况为您提供指导:
我的关注->使用javascript炸毁用户计算机客户端 代码始终在浏览器中运行!
别忘了您正在使用浏览器底层功能(WebSocket),因此除非在客户端加载的页面中运行一些js代码,否则我们别无选择。您可以在此处利用浏览器功能。
场景->如果我有超过1000个用户在线并登录遍历到 不同的页面,我将向所有人广播信号R 连接
Clients.All.setConnectionStatus(profileId, true);
在提出任何解决方案之前,我劝您在应用程序中使用employ grouping logic。 分组减少了同步量。
如果您在一个公共聊天室(可以容纳很多人)中工作,则只需采用服务器端策略,就可以将您的代码变成肮脏的代码!是的,任何浏览或刷新页面的用户都可以对所有客户端进行冗余更新。 最佳解决方案是将页面转到SPA (使用API调用或Ajax调用),而无需刷新页面。 我相信任何实时网络应用程序都应利用现代网络技术。这将解决几乎所有您遇到的问题(例如,无需刷新页面,无需重新运行,无需中断等)。
诸如使用js计时器为用户获取最新状态之类的解决方案并不干净或不可取。