连接启动后连接到SignalR Hub

时间:2015-12-17 08:28:28

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

假设我的服务器应用程序中有两个或更多个集线器。我的javascipt客户端(Angular SPA)首先需要连接到第一个集线器,并且需要订阅这样的方法:

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

一切都很好。现在我的Angular SPA的用户可能决定在他的页面上放置一个小部件,这需要从第二个集线器订阅一个方法:

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

第二个集线器的方法不起作用。我猜是因为它是在connection.start()之后创建的。

我的示例已经简化,在我的真实应用中,将有20多个集线器,用户可以通过向其页面添加或删除小部件来订阅或不订阅。

据我所知,我有两个选择:

  1. 调用connection.stop()然后调用connection.start()。现在两个集线器订阅都正常。这感觉不对,因为在所有集线器上,OnConnected()事件都会触发,我的应用程序将一直启动和停止。
  2. 为所有可能的集线器创建集线器代理对象,订阅虚拟对象 所有可能的集线器上的方法,因此应用程序可以subcibe到集线器 方法如果需要的话。这也感觉不对,因为我 需要创建20多个集线器代理,而我可能只需要几个 那些。
  3. 有人知道我可以用来完成这个的模式吗?或者我在这里错过了一些非常简单的东西?

1 个答案:

答案 0 :(得分: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;
            });
        });
    }
})();