HubConnection.Stop() is a long lasting method. It seems to take longer then Connect.
Shouldn't this method be async ?
After some more testing, Ive also noticed that Stop() takes a long time to run. Like 40 seconds. Making my users wait 40 seconds while the disconnect magic happens seems wrong.
I am using a WinRT / Metro client.
@gissues:{"order":25,"status":"backlog"}
Stop is taking 40 seconds? That's unexpected. it sends a web request to the server (/abort) and waits for at most 2 seconds. We'll look into it.
We experience the same issue intermittently. Maybe 1 out of 500 times or something similar.
When it hangs, our call stack is (typed manually, hope I get it right):
SignalR.Client.Connection.Stop();
SignalR.Client.Transports.HttpBasedTransport.Stop()
SignalR.Client.Http.HttpWebRequestwrapper.Abort()
System.Net.Browser.ClientHttpWebRequest.Abort()
MS.Internal.InternalWebRequest.Abort()
MS.Internal.XcpImports.WebRequest_Abort()
We've waited a like 30 seconds and the thread is still in this location.
A laymans observation
1) SignalR issues an /abort
2) 2 seconds later there is a timeout before the server has not responded. Could be because the local web server is slow or network unreliable.
3) SignalR calls httpRequest.Abort() which in turn calls Abort on the HttpWebRequest. According to the MSDN docs, this could in some cases lead to a deadlock. http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.abort.aspx mentions:
"The Abort method will synchronously execute the callback specified to the BeginGetRequestStream or BeginGetResponse methods if the Abort method is called while either of these operations are outstanding. This can lead to potential deadlock issues."
@halter73 Let's make start async.
This is happening to me consistently - .Stop from the .NET client takes ~ 30 seconds to execute
It seems that the Stop() method will hang if you execute it during receiving a message from the server. I think it's quite common scenario. For example in a code like this the Stop() usually halts for 20 to 30 seconds:
hubProxy.On<string>("Disconnect", (result) =>
{
connection.Stop();
});
@kallehiitola Having the same issue in 2.0.3 in the .NET client. Even when specifying a timeout it never ever returns if the channel is busy.
@peters can you paste a sample of the code you have here? This bug is fixed for async scenarios but if you're waiting on a hub invocation and then calling stop inside a related On handler it will still deadlock.
@DamianEdwards After furter investigation we discovered that the issue was indeed a deadlock occuring. We use quartz to schedule jobs, and these jobs use signalr. So if we shutdown the scheduled jobs while calling stop on the signalr connection simultaneously, well don't do it :-1:
The solution was to ensure that we always wait for all quartz jobs to finish before stopping the signalr connection. So we actually discovered a bug in our code ;)
Side note: The quartz jobs was pumping significant amount of data so it's probably blocking the connection pump indefenitly. We don't care about loosing data since what we are pumping is persisted to disk before dispatching anyway.
HI,
Is this still an issue? I am using the SignalR PCL library version 2.1.2 (mainly because I could not get the 2.2.0 nuget package to install). Is there fix for this coming along in v 2.2.1.
I am seeing the HubConnection.Stop() method hanging (and never returning) even if there is no messages being sent or received on that connection. This is even when I specify a timeout. However I am making web api requests through other httpclient connections on other threads. This is in an iOS app.
Is there anyway to stop this deadlock when calling stop. This is a major issue for me at the moment, and I am hoping someone can help.
@sisterray Do you have a stack trace showing where HubConnection.Stop() is hanging?
All I am doing is calling Stop on my HubConnection. I am using a timeout of 3 seconds. If I attempt to do this with other web api requests in progress (different threads using separate HttpClients) it hangs. If I do not have other web api requests in progress it times out correctly.
Do you think this change Remove _stateLock from Connection.Stop to prevent deadlocks during Abort would have fixed this in 2.2.0? If so can you tell me when 2.2.1 is likely to be released. I think 2.2.1 fixes the issue which prevents me installing it using nuget into my Xamarin project
I am finding that this is not always happening e.g hanging. I am assuming it the deadlock issue described in this thread.
@sisterray It seems pretty likely that this is fixed in 2.2.0. Unfortunately, I can't give you an exact date on the 2.2.1 release other than to say it's definitely not going to happen before next Thursday.
Have you tried changing your portable profile? http://stackoverflow.com/a/32123476/719967
If that doesn't work, you can always try a nightly: https://www.myget.org/F/aspnetwebstacknightly/
Thanks @halter73 I tried getting this working a while ago. I'm using mvvmcross and the profiles seem to clash. I'll maybe try to download the 2.2.0 nugget package locally and temporary use the library directly to see if it fixes it.
Hey I am facing same problem. Any way around this issue?
You could try a couple of things
Since I have done this the issue has gone.
I have this issue aswell. Sometimes connection.Stop() executes in a few seconds, other times it can take up to 30.
Edit: I am using 2.2.1, so it hasn't been fixed.
@apathytomorrow - you might be hitting a different issue. Without details it is not possible to tell what's happening.
2.4.0 Still the same issue long hubConnection.Stop(); of application in Xamarin.Froms ;/
SignalR version 2.2.3
In case of Timeout after 50 seconds (Keeping print preview window open for more than 50 seconds in IE 11 and then closing it causes timeout exception),
SignalR calls the stop method without notifying the server.
connection.stop(/* async / false, / notifyServer */ false);
Because of which server Hub method,
public override Task OnDisconnected(bool stopCalled)
is not called immediately.
And after this the client disconnect method is called,
$.connection.hub.disconnected(function () {
//start new connection
$.connection.hub.start({ transport: 'longPolling', xdomain: true }, function () {});
});
The problem is that I am maintaining list of user depending upon session and connecting Ids on server when hub server method
public override Task OnConnected()
is called.
And I do remove it on hub server method:
public override Task OnDisconnected(bool stopCalled)
is called.
And in case of timeout, the hub server method: public override Task OnDisconnected(bool stopCalled)
is not called immediately.
And from the client disconnected method I am starting a new signalR connection,
As the user is already present in list I am facing , user duplication issue.
In short,
When timeout occurs, after Hub Server method : public override Task OnDisconnected(bool stopCalled) is called, then only I need to raise a new start request from client side.
How can I achieve this,
What I am doing currently is calling the start after 35 seconds as signalR connection timeout is 30seconds by default.
$.connection.hub.disconnected(function () {
window.setTimeout(function () {
$.connection.hub.start({ transport: 'longPolling', xdomain: true }, function () {});
}, 35000);
return true;
});
Any other way I can achieve this instead if waiting for 35 seconds.
Most helpful comment
You could try a couple of things
Since I have done this the issue has gone.