34

I have multiple javascript blocks with signalR functions.

I don't know the order of execution so that i want to start the hub with

$.connection.hub.start();

if it isn't started already.

How can i check if the hub is already started? Starting it multiple times it it throws an error.

daniel
  • 34,281
  • 39
  • 104
  • 158

3 Answers3

87

There are a few ways to approach this problem. The first is to create your own connection status tracking variables, which you set with the connection callback events:

$.connection.hub.start().done(function() { ConnectionStarted = true; })

You can check ConnectionStarted before attempting to start the connection. Unfortunately, this won't work well, as start() is asynchronous and so many instances could try to start a connection before one has finished and set ConnectionStart to true.

So, working solutions. There are two.

First, have every instance use its own connection object (ie: don't use the default $.connection.hub, but instead use manual connection creator:

var localConnection = $.hubConnection(); 
var localHubProxy= localConnection.createHubProxy('HubNameHere');

This isn't great, as most browsers have a limited number of connections allowed per page, and also because it is generally overkill.

IMO, the best solution is to use the single automatic connection with default proxy ($.connection.hub) and look at the connection state (something I just came across). Each connection object has a state:

$.signalR.connectionState
Object {connecting: 0, connected: 1, reconnecting: 2, disconnected: 4}

So, in each instance, go for something like this?:

if ($.connection.hub && $.connection.hub.state === $.signalR.connectionState.disconnected) {
  $.connection.hub.start()
}

Also note that when you create a connection, it will sit in state "disconnected" / 4 until start is called on it. Once start is called, the connection will apparently try to reconnect constantly (if it is interrupted) until $.connection.hub.stop() is called (will then go back to state "disconnected").

Refs:

http://www.asp.net/signalr/overview/hubs-api/hubs-api-guide-javascript-client#establishconnection https://github.com/SignalR/SignalR/wiki

CarenRose
  • 1,266
  • 1
  • 12
  • 24
dpb
  • 3,672
  • 2
  • 20
  • 15
7

You can check the connection state in each of your functions like:

function doSomething {
        if ($.connection.hub.state === $.signalR.connectionState.disconnected) {
            $.connection.hub.start().done(function () { myHub.server.myHubMethod(); });
        }
        else {
            myHub.server.myHubMethod();
        }
    }
Owen Pauling
  • 11,349
  • 20
  • 53
  • 64
  • This is not very good as the state could be 'connecting', and you would fire another start, which would crash. Better to do like dpb. Check that it is disconnected before trying to connect. – Bjørn Oct 13 '16 at 09:21
5

You can detect when the hub has started using .done()

$.connection.hub.start().done(function () {
});

using this method, you can do the following (Taken from docs : https://github.com/SignalR/SignalR/wiki/SignalR-JS-Client-Hubs) you can then keep track of if the connection is open yourself.

function connectionReady() {
    alert("Done calling first hub serverside-function");
};

$.connection.hub.start()
                .done(function() {
                    myHub.server.SomeFunction(SomeParam) //e.g. a login or init
                         .done(connectionReady); 
                })
                .fail(function() {
                    alert("Could not Connect!");
                 });
LiamB
  • 18,243
  • 19
  • 75
  • 116
  • 2
    Multiple? Can you explain? – LiamB Feb 25 '13 at 12:24
  • 1
    I have multiple javascript blocks from different server generated partial html pages. I don't know the order of script block execution. So i don't know where to start my hub. – daniel Feb 25 '13 at 12:25
  • Isolate it into either the page it's being called from or into a separate Main.js file. – LiamB Feb 25 '13 at 12:33
  • I'm sorry then nothing else I can suggest, the above code does what the original question asked. If your JS is being dropped in by partials and that JS relies on code elsewhere that sounds like a design problem. – LiamB Feb 25 '13 at 12:37
  • 1
    sorry, but you haven't answered the question. I think you don't understand the problem. Your answer doesn't check if hub is started but only executes `.done()` when the hub is started. That makes a difference. – daniel Feb 25 '13 at 12:43
  • 1
    i have a layout/master page where i start my hub. Then in my partial page i call different signalr functions on that hub. That doesn't sound like a design problem to me. – daniel Feb 25 '13 at 12:56
  • 2
    Done does get fired multiple times you just seem to have a timing issue. Can you create a repro project – davidfowl Feb 25 '13 at 22:08
  • Is possible to check the connection state for each hub ?? right now when i open three tabs(my application sending more than 6 request with same url http://localhost/Microcare/signalr/start?transport=webSockets&clientProtocol=1.5&connectionToken= ... in this way browser limitation exceeds and system gets hangs until i close any one tab – Sajjad Ali Khan Apr 25 '17 at 13:13