2015-12-17 1 views
4

Disons que j'ai deux concentrateurs ou plus dans mon application serveur. Mon client javascipt (SPA angulaire) a besoin d'une connexion initialement la première plaque tournante, et doit souscrire à une méthode comme ceci:Connectez-vous à SignalR Hub après le démarrage de la connexion

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"); 
      }); 

Tout fonctionne très bien. Maintenant, un utilisateur de mon SPA angulaire peut décider de mettre un widget sur sa page, qui doit vous inscrire à une méthode à partir du deuxième centre:

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

La méthode du deuxième hub ne fonctionne pas. Je suppose que parce qu'il a été créé après connection.start().

Mon exemple est simplifié, dans mon application réelle il y aura plus de 20 hubs auxquels les utilisateurs peuvent ou ne peuvent pas s'abonner en ajoutant ou en supprimant des widgets à leur page.

Pour autant que je peux dire que j'ai deux options:

  1. appel connection.stop(), puis connection.start(). Maintenant, les deux abonnements au concentrateur fonctionnent. Cela ne semble pas correct, car sur tous les concentrateurs, l'événement OnConnected() se déclenche et mon application démarre et s'arrête tout le temps.
  2. créer des objets proxy concentrateur pour tous les concentrateurs possibles, abonnez-vous à une méthode factice sur tous les concentrateurs possibles, afin que l'application puisse sous-traiter aux méthodes du concentrateur ultérieurement si vous le souhaitez. Cela ne me semble pas non plus juste, parce que je dois créer 20+ proxys concentrateur, alors que je peux avoir besoin de quelques-uns des .

Est-ce que quelqu'un est au courant d'un modèle que je peux utiliser pour accomplir ceci? Ou est-ce que je manque quelque chose de très simple ici?

Répondre

4

Personnellement, j'utilise # 2. J'ai un service hub souscrit à toutes les méthodes client. N'importe lequel de mes autres composants angulaires tire alors ce service de hub dedans et souscrit à ses événements comme nécessaire.

La voici;

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); 
     }); 
    }; 
} 

Je peux souscrire à des choses au besoin, par exemple dans un contrôleur;

(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

Merci pour votre exemple. Donc, cela signifie également que vous utilisez un seul Hub dans votre application serveur? – Jeroen1984

+1

Oui, mais le même "abonnement à toutes les méthodes client" s'applique. –

+0

Ok, je comprends. Je vais le personnaliser un peu alors au début seulement la connexion démarre et le proxy hub est créé. De cette façon, je peux laisser mes contrôleurs s'abonner (.on) et se désabonner (.off) aux événements concentrés souhaités, sans devoir coder toutes les méthodes clientes possibles (comme vous le faites dans votre fonction active()) – Jeroen1984