确定信号R的连接状态而无需广播Clients.All.someMethod()并消耗客户端资源

时间:2018-11-09 01:01:15

标签: javascript asp.net-mvc signalr signalr-hub signalr.client

我担心在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()方法来设置我的联系人的在线状态我正在聊天。

enter image description here

有一种更好的方法,然后将信号广播给我网站上的“所有”在线用户?但是我唯一能想到的方法就是每隔一段时间在一些javascript计时器上轮询状态,但是我讨厌这个主意!

另一种方法是保留每个人正在与谁聊天的内存中集合,但是这看起来可能会变得非常混乱,并且最终可能变得不太准确,因为可能有很多东西在客户端和服务器之间可能会导致中断,从而无法正确管理与谁建立连接的用户的内存中集合!这里的任何想法都将不胜感激!

仅供参考->我还有一个消息页面,其中显示了我与以下用户最近进行的所有对话的列表。在此页面上,我还将显示这些用户的在线状态。在此页面上,我渲染页面之前会获取服务器上每个用户的在线状态,与聊天框相同,但是一旦页面被加载,则取决于OnConnected()OnDisconnected(bool stopCalled)的设置页面上每个用户的在线状态。

enter image description here

1 个答案:

答案 0 :(得分:3)

您使用signalR的方式正确。我会根据您的担忧/情况为您提供指导:

  

我的关注->使用javascript炸毁用户计算机客户端   代码始终在浏览器中运行!

别忘了您正在使用浏览器底层功能(WebSocket),因此除非在客户端加载的页面中运行一些js代码,否则我们别无选择。您可以在此处利用浏览器功能。

  

场景->如果我有超过1000个用户在线并登录遍历到   不同的页面,我将向所有人广播信号R   连接Clients.All.setConnectionStatus(profileId, true);

在提出任何解决方案之前,我劝您在应用程序中使用employ grouping logic分组减少了同步量

如果您在一个公共聊天室(可以容纳很多人)中工作,则只需采用服务器端策略,就可以将您的代码变成肮脏的代码!是的,任何浏览或刷新页面的用户都可以对所有客户端进行冗余更新。 最佳解决方案将页面转到SPA (使用API​​调用或Ajax调用),而无需刷新页面。 我相信任何实时网络应用程序都应利用现代网络技术。这将解决几乎所有您遇到的问题(例如,无需刷新页面,无需重新运行,无需中断等)。

诸如使用js计时器为用户获取最新状态之类的解决方案并不干净或不可取。