SignalR connection freeze other ajax requests

asp.net-mvc, jquery, signalr

Solution

I have another explanation for what might have caused the problem.

Since the question was asked in 2013 I assume that the author already found the solution for his problem. But since it took me several hours to dig into mine, I believe it is my duty to share my experience.

Architecture overview: Asp.Net SPA application with AngularJS on client side and WebApi 2.0 and SignalR 2.1 on server side.

Problem symptoms: the application starts and functions normally but after some while all requests (SignalR and WebApi) get stuck. By 'stuck' I mean that WebApi requests are being made on the client but controller methods never get called. The first one to get frozen is always the SignalR request.

After doing some search I've found the most probable reason for these symptoms. This was the "Session State Blocking" issue described in detail in this post by John Culviner.

Since my application was not using sessions I simply switched them to read-only mode on application level:

protected void Application_Start()
{
    // Some extra initialization here
    Context.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.ReadOnly);
}

This did not help.

I continued my research and I believe that by that time I've read every article or bug report with keywords SignalR, connection, stuck, freeze, hang. Nothing seemed to be related with my case. So instead of searching what might be the problem with the technology in use, I started to analyze what might be wrong with my own code. And there it was.

My problem has a good description in this article by Shaun. Here is the overview. In standard MVC world SignalR manages its connection itself. It will disconnect itself automatically when you move to another page. So you could just create the connection and forget about it. Unfortunatelly this is not true for SPA/AngularJS applications. SignalR connection will never know that the page inside SPA was changed and will never disconnect itself. When you return to the page a new SignalR connection will be created. In my observations you need to do this around 10 times to make the pipe that serves the requests stuck.

So all you have to do here is creating a stop function for SignalR connection and calling it manually before changing the page inside SPA:

stop: function() {
    if (connection && connection.state && connection.state !== 4 /* disconnected */) {
        connection.stop();
    }
},

In controller:

$scope.$on('$destroy', function() {
    clientPushHubProxy.stop();
});

Problem

I develop an asp.net mvc application with the real-time messaging system based on the SignalR (jquery.signalR-2.0.0-beta2.js). The problem is that all partial views cannot be loaded after the SignalR connection started. In this case all ajax requests after the $.connection.hub.start({ transport: 'longPolling'}).done(function () { applicationHub.server.connectUser(); }) stay in pending state. Is it posible to make this requests async or is it a bug in the SignalR? Thanks for your help! SignalR call: ``` <script type="text/javascript"> $(document).ajaxStop(function () { var applicationHub = $.connection.applicationHub; if ($.connection.hub && $.connection.hub.state == $.signalR.connectionState.disconnected) { registerConversationClientMethods(applicationHub); $.connection.hub.start({ transport: 'longPolling'}).done(function () { applicationHub.server.connectUser(); }) .fail(function () { }); } }); </script> ``` Ajax call which renders a partial view: function LoadActivities(id, type, container, action, loaderpath) { ``` var url = action + '/?id=' + id + '&type=' + type; var targetDiv = container; var ajaxLoading = "<img id='ajax-loader' src='" + loaderpath + "' height='6' width='50' style='margin:5px;'>"; $(targetDiv).html("<div align='center'>" + ajaxLoading + "</div>"); $.get(url, null, function (result) { $(targetDiv).html(result); }); ``` }

Original source