在单个页面中管理多个SignalR连接

时间:2018-06-26 10:35:43

标签: javascript c# asp.net asp.net-web-api signalr

I'm experiencing intermittent signalr connection problems

有时会失败,有时却不会...

这是设置...

我有一个订单列表,每个订单都有一个唯一的信号发送器连接。当前在一个页面上有230个订单。建立信号发送器连接的目的是使用户可以查看每个订单(正在查看,编辑等)的任何实时更新。我决定为每个订单建立一个单独的连接,以便不必管理当前正在查看,编辑等的订单。到目前为止,对于已成功连接的订单,更新是正确且顺畅的。

Here is my list中有另一个查看订单的用户的样本(正在显示该用户的照片)

这是我的连接到信号中心的代码

crimeassure.factory('hubProxy', ['$rootScope', function ($rootScope) {

  function hubProxyFactory(hubName) {

      var _hubConnection = $.hubConnection();
      _hubConnection.logging = true;
      var _hubProxy = _hubConnection.createHubProxy(hubName);

      return {
          on: function (eventName, callback, failCallback) {
              _hubProxy.on(eventName, function (result) {
                  $rootScope.$apply(function () {
                      if (callback) {
                          callback(result);
                      }
                  });                     
              })
          },
          invoke: function (methodName, data) {
              _hubProxy.invoke(methodName, data)
              .done(function (result) {
                  //$rootScope.$apply(function () {
                  //    if (callback) {
                  //        callback(result);
                  //    }
                  //});
              });
          },
          start: function (successCallback, failCallback) {                  
              _hubConnection.start({ transport: 'webSockets' }).done(successCallback).fail(failCallback);
          },              
          hubConnection: _hubConnection,

      };
  };

  return hubProxyFactory; 

}]);

crimeassure.directive('componentLiveUpdates', function () {
    return {
        restrict: 'E',
        scope: {
            componentId: '=',               
        },
        templateUrl: '/scripts/templates/directive-templates/component-live-updates.html',
        controllerAs: 'vm',
        bindToController: true,
        controller: ["$scope", "$rootScope", "appData", "hubProxy",
            function componentLiveUpdates($scope, $rootScope, appData, hubProxy) {
                var vm = (this);
                var user = appData.getCurrentUser();
                vm.componentActivity = [];

                var reQueueHub = hubProxy('researcherExpressQueueHub');

                var componentActivityChanged = function (component) {
                    if (component.ActivityValue === 'ComponentModalClose') {
                        var idx = vm.componentActivity.indexOf(component);
                        vm.componentActivity.splice(idx, 1);
                    }

                    if (component.ActivityValue === 'ComponentModalOpen') {
                        vm.componentActivity.push(component);
                    }
                }

                var successCallback = function () {
                    console.log('connected to signalR, connection ID =' + reQueueHub.hubConnection.id + '--' + vm.componentId);
                    reQueueHub.invoke('joinGroup', vm.componentId);

                    $rootScope.reQueueHubs.push({
                        ComponentId: vm.componentId,
                        Hub: reQueueHub
                    });
                }

                var failCallback = function (e) {
                    console.log('Error connecting to signalR = ' + vm.componentId);
                    console.log(e);

                    //startHubConnection();
                }

                var startHubConnection = function () {
                    reQueueHub.start(successCallback, failCallback);
                }

                var initialize = function () {
                    reQueueHub.on('updateComponentActivity', componentActivityChanged);

                    startHubConnection();
                }

                initialize();
            }],
    }
});

这是我的中心班

public class ResearcherExpressQueueHub : Hub
{

    public void UpdateComponentActivity(ComponentItem item)
    {
        Clients.Group(item.ComponentId.ToString()).updateComponentActivity(item);
    }

    public void ComponentModalOpen(ComponentItem item)
    {
        item.Activity = ComponentActivity.ComponentModalOpen;
        Clients.Group(item.ComponentId.ToString()).updateComponentActivity(item);
    }

    public void ComponentModalClose(ComponentItem item)
    {
        item.Activity = ComponentActivity.ComponentModalClose;
        Clients.Group(item.ComponentId.ToString()).updateComponentActivity(item);
    }

    public Task JoinGroup(string componentId)
    {
        return Groups.Add(Context.ConnectionId, componentId);
    }

    public Task LeaveGroup(string componentId)
    {
        return Groups.Remove(Context.ConnectionId, componentId);
    }
}

我的问题是

  1. 为什么我遇到断开连接“在建立连接之前WebSocket已关闭”

  2. 我的方法是解决此类需求的最佳方法吗?

1 个答案:

答案 0 :(得分:1)

使用Signalr的分组机制,而不为您的用例创建多个连接!

IIS和浏览器都有一些限制。某些浏览器的连接数限制为4或5。您可以通过打开多个不同的浏览器自己进行测试。

有关分组的详细信息:

在Signalr中使用组非常简单。您可以在这里找到详细信息:https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/working-with-groups