Управление несколькими соединениями SignalR на одной странице - PullRequest
0 голосов
/ 26 июня 2018

У меня проблемы с подключением к сигнализатору

иногда не получается, иногда нет ...

Вот настройки ...

У меня есть список заказов, каждый заказ имеет уникальное соединение с сигнализатором. В настоящее время на одной странице 230 заказов. Цель подключения сигнализатора состоит в том, чтобы пользователи могли видеть любые обновления в реальном времени по каждому заказу (кто просматривает, редактирует и т. Д.). Я решил создать отдельное соединение для каждого заказа, чтобы мне не приходилось управлять заказом, который в данный момент просматривается, редактируется и т. Д. На данный момент для заказов, которые успешно подключились, обновления являются правильными и гладкими. ,

Вот мой список с примером другого пользователя, просматривающего заказ (показывается фотография этого пользователя)

Вот мой код, который подключается к концентраторам сигналов

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 голосов
/ 26 июня 2018

Используйте механизм группировки сигнализатора и НЕ создавайте несколько соединений для вашего варианта использования!

Есть ограничения от IIS, а также от браузеров. Некоторые браузеры имеют ограничение в 4 или 5 параллельных подключений. Вы можете проверить это самостоятельно, открыв несколько разных браузеров.

Информация о группировке:

Работать с группами в сигнализаторе действительно просто. Подробности вы найдете здесь: https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/working-with-groups

...