如何动态地将集线器添加到SignalR并具有不同的范围

时间:2014-04-07 12:26:59

标签: angularjs signalr dashboard signalr-hub

我尝试使用小部件(构建为指令)构建仪表板。我希望在稍后阶段能够动态添加小部件,但我只喜欢活动小部件(和集线器)来接收数据,因此如果小部件不活动我不会#39;想要集线器注册。

例如,在使用该应用程序的用户期间,将有一个全局signalR上下文,以及页面特定的上下文,将根据需要生成/销毁。

enter image description here

这是我最好的尝试ATM ...这是不行的

工厂

   (function () {
    'use strict';

    angular.module('app').factory('hubFactory', ['permissionSvc', 'common', hubFactory]);

    function hubFactory(permissionSvc, common) {

        var connection = [];

        return {
            context: function (name) {

                if (!connection[name]) {
                    var conn = $.connection;
                    conn.hub.url = common.serviceUrl + '/signalr';
                    conn.hub.start();

                    conn.prototype.addHub = function (hubName, options) {

                        // defaults
                        var opts = {
                            authorize: true
                        };

                        angular.extend(opts, options);

                        if (opts.authorize) {
                            permissionSvc.createPrefilter();
                        }

                        var hub = conn[hubName];

                        var run = function () {
                            hub.server.initialise();
                        };

                        return {
                            hub: hub,
                            run: run
                        };
                    };

                    connection[name] = conn;
                }

                return connection[name]();
            }
        };
    }
})();

widget指令控制器

 controller: function ($scope) {               

               var context = hubFactory.context('dashboard');

               var instance = context.addHub('agreementApprovalsHub');

               instance.hub.client.getAllUnapprovedAgreements = function (data) {

                    $scope.data = data;
                };

               instance.run();
            } 

以下需要在启动的done方法中调用...但是,如果我想,在页面加载时启动连接,然后根据需要添加集线器(或者我认为错了?)

存在各种问题:

  

var run = function(){                                   hub.server.initialise();                               };

VS

  

var run = function(){conn.hub.start()。done(function(){                                   hub.server.initialise(); });                               };

TBH,感觉就像是在屠杀代码,并且需要在这个阶段从头开始...... 我对如何处理这一切感到非常困惑,如果可能的话,我很困惑。

2 个答案:

答案 0 :(得分:4)

我认为我有一个更优雅的解决方案。

<强>服务

 app.factory("signalrFactory", function ($rootScope, $http, $timeout) {
    var factory = {};
    factory.connection = $.connection;

    var startDoneFunctions = [];
    var debounce;

    factory.start = function (done) {
        factory.connection.hub.stop();

        if (done) {
            if (startDoneFunctions.indexOf(done) == -1) {
                startDoneFunctions.push(done);
            }
        }
        if (debounce) $timeout.cancel(debounce);
        debounce = $timeout(function () {
            factory.connection.hub.start().done(function () {
                for (var x = 0; x < startDoneFunctions.length; x++) {
                    startDoneFunctions[x]();
                }
            });
        }, 100);
    };

    return factory;
});

使用

controller('customerSummary', function ($scope, signalrFactory) {
        $scope.customerHub = signalrFactory.connection.customerHub;
        $scope.customer;
        $scope.beingEditedText = "";



        $scope.customerHub.client.beingEdited = function (text) {
            $scope.beingEditedText = text;
        };
        $scope.customerHub.client.doneEditing = function () {
            $scope.beingEditedText = "";
        };

        $scope.customerHub.client.updateCustomer = function (customer) {
            $scope.customer = customer;
            $scope.$apply();
        };

        $scope.init = function (id) {
            signalrFactory.start(function () {
                $scope.customerHub.server.getCustomer(id);

            });
        };
    });

这种方式允许在需要时添加,而不必在引导程序中添加每个集线器。我现在可以从任何地方使用不同的done()方法。

答案 1 :(得分:1)

注意

虽然下面的解决方案起初对我有用。我选择使用above提供的解决方案,最终效果很好。

<小时/>

原始答案

我对signalR的初步了解略有不足。我最终也为此创建了一个提供程序,所以我可以提前配置它。

<强>配置

app.config(['signalrSvcProvider', function (signalrSvcProvider) {
    signalrSvcProvider.start(['global','dashboard']);
}]);

<强>提供商

(function () {
    'use strict';

    angular.module('app').provider('signalrSvc', signalrSvc);

    function signalrSvc() {

        var self = this;

        self.hubs = [];

        this.start = function (hubs) {

            var connection = $.hubConnection("someurl/signalr");

            // convert hubNames to actual hub proxies, and append default client communication functions
            $.each(hubs, function (idx, hub) {
                var proxy = connection.createHubProxy(hub);

                // a minimum of one client function needs to be registered to be able to complete the connection
                proxy.on('pingBack', function (data) { console.log(hub.hubName + ", connected: " + data); });
                proxy.on('receiveError', function (data) { console.log(hub.hubName + ", error: " + data); });

                self.hubs[idx] = proxy;
            });

            // add security token before attmpting connect
            $.ajaxPrefilter(function (options) {
                if (!options.beforeSend) {
                    options.beforeSend = function (xhr) {
                        var token = $.cookie(".cttid").replace(/"/g,'');
                        xhr.setRequestHeader('Authorization', 'Bearer ' + token);
                    };
                }
            });

            // connects and run initialise for each hub
            connection.start({ transport: 'longPolling' })
                .done(function () {
                    $.each(self.hubs, function (idx, hub) {
                        hub.invoke('initialise');
                    });
                });
        };

        this.$get = ['filterFilter', function (filterFilter) {
            return {
                hub: function (name) {
                    return filterFilter(self.hubs, { hubName: name }, true)[0];
                }
            };
        }];
    }

})();

<强>用法

var hub = signalrSvc.hub('dashboard');

hub.on('getAllUnapprovedAgreements', function (data) {
      //do something
});