Question

In jquery.signalR-1.1.3.js the longpolling error function passes back the response text instead of the entire jqXHR object.

Is there a good way to determine in the hub error handler what the error actually is?

$.connection.hub.error(function (error) {
            system.log('SignalR error: ' + error);
        });

I've used the SignalR [Authorize] attribute to return a HTTP 403 Forbidden when a connection should be refused, but in my client all I get is the IIS error page response page in the error object because SignalR doesn't pass back the entire response object see below: $(instance).triggerHandler(events.onError, [data.responseText]);. This happens in a tight loop because SignalR just keeps trying to reconnect a few hundred/thousand/whatever times until the reconnect timeout passes.

I'd like to be able to tell that it's a 403, or whatever custom status code I might return, and then let my app respond accordingly...in this case, quit trying to reconnect and log out.

Here's the longpolling transport's error handler:

error: function (data, textStatus) {
// Stop trying to trigger reconnect, connection is in an error state
// If we're not in the reconnect state this will noop
window.clearTimeout(reconnectTimeoutId);
reconnectTimeoutId = null;

if (textStatus === "abort") {
    connection.log("Aborted xhr requst.");
    return;
}

// Increment our reconnect errors, we assume all errors to be reconnect errors
// In the case that it's our first error this will cause Reconnect to be fired
// after 1 second due to reconnectErrors being = 1.
reconnectErrors++;

if (connection.state !== signalR.connectionState.reconnecting) {
    connection.log("An error occurred using longPolling. Status = " + textStatus + ". " + data.responseText);
    $(instance).triggerHandler(events.onError, [data.responseText]);
}

// Transition into the reconnecting state
transportLogic.ensureReconnectingState(instance);

// If we've errored out we need to verify that the server is still there, so re-start initialization process
// This will ping the server until it successfully gets a response.
that.init(instance, function () {
    // Call poll with the raiseReconnect flag as true
    poll(instance, true);
});

}

And the Server side hub authorization code

public override bool AuthorizeHubConnection(Microsoft.AspNet.SignalR.Hubs.HubDescriptor hubDescriptor, Microsoft.AspNet.SignalR.IRequest request)
{
    // If we want them to connect, return true, else false
    // Asp.NET will return a 403 if we return false here
    return false;
}

A couple of questions arise...

  1. Why does signalR reconnect in a tight loop like that?
  2. Is there a better way to control the signalR connection lifecycle based upon the Authorization of the hub connection?
Was it helpful?

Solution

  1. It's a bug that was fixed in 2.0 and it will be fixed in 1.1.5
  2. Yes, make sure you don't render the page that attempts to make the SignalR connection if the user isn't authorized.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top