2015-12-17 2 views
4

Предположим, у меня есть два или более концентраторов в моем серверном приложении. Мой Javascipt клиент (Угловая SPA) initialy требуется подключение к первому ступице, и нужно подписаться на способ, как это:Подключиться к концентратору SignalR после подключения

connection = $.hubConnection(appSettings.serverPath); 
firstHubProxy = connection.createHubProxy('firstHub'); 
firstHubProxy('eventFromFirstHub', function() { 
     console.log('Method invokation from FirstHub'); 
      }); 
connection.start().done(function (data) { 
       console.log("hub started"); 
      }); 

Все работает отлично. Теперь пользователь моей угловой SPA может решить поставить виджет на своей странице, которая должна subcribe к способу из второго хаба:

secondHubProxy = connection.createHubProxy('firstHub'); 
secondHubProxy('eventFromSecondHub', function() { 
     console.log('Method invokation from SecondHub'); 
      }); 

метод из второго хаба не работает. Я думаю, потому что он был создан после connection.start().

Мой пример упрощен, в моем реальном приложении будет 20+ концентраторов, на которые пользователи могут подписаться или не подписаться, добавив или удалив виджеты на свою страницу.

Насколько я могу сказать, у меня есть два варианта:

  1. вызова connection.stop(), а затем connection.start(). Теперь обе подписки на концентратор работают. Это просто не так, потому что на всех концентраторах происходит событие OnConnected(), и мое приложение будет запускаться и останавливаться все время.
  2. создать объекты-прокси-концентраторы для всех возможных концентраторов, подписаться на манекен метод на всех возможных концентраторах, поэтому при необходимости приложение может подключиться к концентратору . Это также не очень хорошо, потому что i необходимо создать 20+ прокси-серверов, в то время как мне может понадобиться только несколько из тех.

Кто-нибудь знает о шаблоне, который я могу использовать для достижения этого? Или я пропустил что-то очень простое здесь?

ответ

4

Лично я использую # 2. У меня есть сервис-концентратор, который подписывается на все клиентские методы. Любой из моих других угловых компонентов затем втягивает эту службу концентратора и подписывается на ее события по мере необходимости.

Вот оно;

hub.js

(function() { 
    'use strict'; 

    angular 
     .module('app') 
     .factory('hub', hub); 

    hub.$inject = ['$timeout']; 

    function hub($timeout) { 
     var connection = $.connection.myHubName; 

     var service = { 
      connect: connect, 
      server: connection.server, 
      states: { connecting: 0, connected: 1, reconnecting: 2, na: 3, disconnected: 4 }, 
      state: 4 
     }; 

     service = angular.extend(service, OnNotify()); 

     activate(); 

     return service; 

     function activate() { 
      connection.client.start = function (something) { 
       service.notify("start", something); 
      } 

      connection.client.anotherMethod = function (p) { 
       service.notify("anotherMethod", p); 
      } 

      // etc for all client methods 

      $.connection.hub.stateChanged(function (change) { 
       $timeout(function() { service.state = change.newState; }); 
       if (change.state != service.states.connected) service.notify("disconnected"); 
       console.log("con:", _.invert(service.states)[change.oldState], ">", _.invert(service.states)[change.newState]); 
      }); 

      connect(); 
     } 

     function connect() { 
       $.connection.hub.start({ transport: 'auto' }); 
     } 
    } 
})(); 

OnNotify

var OnNotify = function() { 
    var callbacks = {}; 
    return { 
     on: on, 
     notify: notify 
    }; 

    function on(name, callback) { 
     if (!callbacks[name]) 
      callbacks[name] = []; 
     callbacks[name].push(callback); 
    }; 

    function notify(name, param) { 
     angular.forEach(callbacks[name], function (callback) { 
      callback(param); 
     }); 
    }; 
} 

Тогда я могу подписаться на вещи, как это необходимо, например, в контроллере;

(function() { 
    'use strict'; 

    angular 
     .module('app') 
     .controller('MyController', MyController); 

    MyController.$inject = ['hub']; 

    function MyController(hub) { 
     /* jshint validthis:true */ 
     var vm = this; 
     vm.something = {}; 

     hub.on('start', function (something) { 
      $timeout(function() { 
       console.log(something); 
       vm.something = something; 
      }); 
     }); 
    } 
})(); 
+0

Спасибо за ваш пример. Таким образом, это также означает, что вы используете только один концентратор в своем серверном приложении? – Jeroen1984

+1

Да, но применяется то же самое «подписаться на все клиентские методы». –

+0

Хорошо, я понял. Я настрою его немного, поэтому изначально только подключение запускается и создается прокси-сервер. Таким образом, я могу позволить своим контроллерам подписываться (.on) и не подписывать (.off) на требуемые события хаба, с необходимостью жестко кодировать все возможные клиентские методы (например, вы выполняете функцию active()). – Jeroen1984

Смежные вопросы