简体   繁体   English

连接开始后连接到SignalR Hub

[英]Connect to SignalR Hub after connection start

Let's say i have two or more hubs in my server application. 假设我的服务器应用程序中有两个或更多集线器。 My javascipt client (Angular SPA) initialy needs a connection to the first hub, and needs to subscribe to a method like this: 我的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");
            });

Everything is working fine. 一切都很好。 Now a user of my Angular SPA may decide to put a widget on his page, which needs to subcribe to a method from the second hub: 现在我的Angular SPA的用户可能决定在他的页面上放置一个小部件,这需要从第二个集线器订阅一个方法:

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

The method from the second hub is not working. 来自第二个集线器的方法不起作用。 I guess because it was created after connection.start() . 我猜是因为它是在connection.start()之后创建的。

My example is simplified, in my real appplication there will be 20+ hubs to which users may or may not subscribe by adding or removing widgets to their page. 我的示例是简化的,在我的真实应用中,将有20多个集线器,用户可以通过向其页面添加或删除小部件来订阅或不订阅。

As far as i can tell i have two options: 据我所知,我有两个选择:

  1. call connection.stop() and then connection.start(). 调用connection.stop()然后调用connection.start()。 Now both hub subscriptions are working. 现在两个集线器订阅都正常。 This just doesn't feel right, because on all hubs, the OnConnected() event fires, and my application will be starting and stopping all the time. 这感觉不对,因为在所有集线器上,OnConnected()事件都会触发,我的应用程序将一直启动和停止。
  2. create hub proxy objects for all possible hubs, subscribe to a dummy method on all possible hubs, so the application can subscibe to hub methods later if desired. 为所有可能的集线器创建集线器代理对象,在所有可能的集线器上订阅虚拟方法,因此如果需要,应用程序可以在以后将子集应用于集线器方法。 This also doesn't feel right, because i need to create 20+ hub proxies, while i may need just a few of those. 这也感觉不对,因为我需要创建20多个集线器代理,而我可能只需要其中一些代理。

Is anybody aware of a pattern which i can use to accomplish this? 有人知道我可以用来完成这个的模式吗? Or am i missing something very simple here? 或者我错过了一些非常简单的东西?

Personally I use #2. 我个人使用#2。 I have a hub service that subscribes to all client methods. 我有一个订阅所有客户端方法的集线器服务。 Any of my other angular components then pull that hub service in and subscribe to its events as needed. 然后,我的任何其他角度组件都会将该中心服务拉入其中并根据需要订阅其事件。

Here it is; 这里是;

hub.js 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 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);
        });
    };
}

Then I can subscribe to things as needed, for example in a controller; 然后我可以根据需要订阅内容,例如在控制器中;

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM