Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SignalR: How to add client call after the hub is started?

First off, I just started trying to add SignalR 2 to my existing Angular SPA project.

I have a main controller which starts the hub right away that is feeding some messages to the client. Inside, I have several sub pages and each could subscribe to a different hub for services. The problems is that the client doesn't receive message because it is hooked up after the hub is already started in the main controller.

As a test, if I comment out the hub start in the main controller, the one in the sub controller works fine.

From what I read, it is by design that you have to hook up all client calls before starting the hub. I don't understand...if it is a service, I should be able to subscribe or unsubscribe anytime after the hub is started. Why not? How to workaround?

like image 827
newman Avatar asked Sep 20 '14 04:09

newman


1 Answers

Because no response in the 12 hours (which is quite unusual in so), I had to dig around myself. I think, I was misled by the answers from SO on related questions that you have to subscribe all client call before starting the connection, as mentioned e.g. here. I found in Hubs API Guide, one section says

Define method on client (without the generated proxy, or when adding after calling the start method)

So, it is possible to add client method after connection is started. The trick is to use so-called "without the generated proxy". That limitation is for "with generated proxy".

The following is my working example taken from SignalR get started tutorial.

This is the main controller using "with generated proxy":

$.connection.statusHub.client.updateStatus = function (status) {
    $scope.status = status;
    $scope.$apply();
}
$.connection.hub.start();

This is in a subcontroller using "without generated proxy":

var connection = $.hubConnection();
var proxy = connection.createHubProxy('stockTickerHub');
proxy.on('updateStockPrice', function (stock) {
    var st = $scope.stocks.firstOfKey(stock.symbol, 'symbol');
    st.lastPrice = stock.lastPrice;
    $scope.$apply();
});

var hub = $.connection.stockTickerHub;
connection.start().done(function () {
    hub.server.getAllStocks().done(function (stocks) {
        $scope.stocks = stocks;
    });
});

Note that it doesn't work if I use "with generated proxy" in the subcontroller like this:

var hub = $.connection.stockTickerHub;
hub.client.updateStockPrice = function (stock) {
    var st = $scope.stocks.firstOfKey(stock.symbol, 'symbol');
    st.lastPrice = stock.lastPrice;
    $scope.$apply();
};

$.connection.hub.start().done(function () {
    hub.server.getAllStocks().done(function (stocks) {
        $scope.stocks = stocks;
    });
});

To prove the limitation of "with generated proxy" mode, this code works if I comment out the one in the main controller.

By the way, I was so confused by the term with or without generated proxy in the Guide, and in both cases, it is still called xxxProxy. Can't they find a better name? Or somebody has an explanation?

like image 199
newman Avatar answered Sep 22 '22 07:09

newman