Signalr: ASP.NET Hub.OnDisconnected not called when .NET client disconnects due to Internet connectivity/process killed

Created on 7 Jul 2014  路  19Comments  路  Source: SignalR/SignalR

Repro steps:

  • Add this method to the Hub on the ASP.NET side:

public override Task OnDisconnected()

  • Deploy the server app into an Azure Website
  • Create a .NET (C#) client and connect to the now-deployed ASP.NET app
  • Verify that OnConnected is called on the Hub on ASP.NET - so far so good
  • Now, kill the C# client process using task manager/stop in the VS debugger/etc.
  • OnDisconnected on the ASP.NET server side is _never_ called even after waiting hours.
  • This is with the latest stable version of SignalR. This causes significant issues in my app.

Questions:

  • Is this a known issue? It's a pretty serious problem
  • Are there any workarounds?
Bug

All 19 comments

In SignalR 2.1.0, there is a new overload to OnDisconnected that takes a bool indicating whether the client disconnected gracefully or not. The reasoning behind this change is explained in the "Breaking Changes" section of the 2.1.0 release notes.

Your new OnDisconnected method could look something like this:

``` C#
public virtual Task OnDisconnected(bool stopCalled)
{
if (stopCalled)
{
// We know that Stop() was called on the client,
// and the connection shut down gracefully.
}
else
{
// This server hasn't heard from the client in the last ~35 seconds.
// If SignalR is behind a load balancer with scaleout configured,
// the client may still be connected to another SignalR server.
}

return base.OnDisconnected(stopCalled);

}
```

@pfletcher We need to doc this as a breaking change

Does this mean that the following method doesn't get called anymore?

public override Task OnDisconnected()
{
}

If so, that is kind of weird because the base method is still there - I can see it here:

https://github.com/SignalR/SignalR/blob/2.1.0/src/Microsoft.AspNet.SignalR.Core/Hubs/HubBase.cs#L50

Isn't that a bug?

I am using 2.1.0 of the client and the server packages.

Thanks.

@halter73 explained the change pretty (as does the release notes) it's by design. Both methods are there. The older one will be called less than it was before (that's the change).

So if I use the new one, is it guaranteed to be called anytime there is a client disconnect? Or will there be cases that are still not covered?

Yes, it will be called in all cases. There's only 2 cases really.

Ok after more thought we need to revert some behavior here. OnDisconnected should be called as much as it was called before. What we have today is a massive regression and it doesn't need to be. The behavior change was intended to alert users of the fact that OnDisconnected would be called more often in the scale out case.

@davidfowl Agreed, this was an oversight.

This makes sense - it definitely seems like a bug that the old method is no longer called, and there isn't documentation or a deprecated notice on the old method. I will try using the other method in the mean time and confirm that that works.

Yeah that fixed it - this is definitely a bug.

I struggled a few hours with this. I am using SignalR 2

On a basic script you need to define at least one client callback for events to be raised on the hub..... I eventually found this while running an example from here.

chat = $.connection.chatHub;

// Need at least one callback for events to be raised on the hub
chat.client.void = function () { };

$.connection.hub.logging = true;
$.connection.hub.start(); //.done(function () {

Now, after all that digging, my breakpoints finally get hit on the OWIN C# server.

public override Task OnConnected()
{
   //logic code removed for brevity
   return base.OnConnected();
}

public override Task OnDisconnected(bool stopCalled)
{ 
   //logic code removed for brevity
   return base.OnDisconnected(stopCalled);
}

Hello All,
I am using SignalR 2.2.1 and I'm seeing this issue using a javascript client in a chrome browser. After turning on the signalr logging I do see the connection being aborted because of a timeout but the OnDisconnected event is never called on the hub. Is this still an issue. I have also tried using the javascript onbeforeunload to manually call disconnect on the hub but this did not work. Every once in a while while reproducing this issue I do see the following error in the SignalR logs. SignalR.HubDispatcher "Error creating Hub", but this error is not seen every time.

Hub Code:

public override Task OnDisconnected(bool stopCalled)
{
try
{
if (stopCalled)
{
Log.Warning("Client {ConnectionId} explicitly closed the connection.", Context.ConnectionId);
}
else
{
Log.Warning("Client {ConnectionId} timed out.", Context.ConnectionId);
}
return base.OnDisconnected(stopCalled);
}
catch (Exception exception)
{
Log.Error(exception, "Error OnDisconnected");

            throw new HubException(exception.Message);
        }
    }

SignalR Logs:
SignalR.Transports.TransportHeartBeat Information: 0 : Connection 71162383-1336-457c-92a5-3e7ed55c9f8f is New.
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(71162383-1336-457c-92a5-3e7ed55c9f8f)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(71162383-1336-457c-92a5-3e7ed55c9f8f)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(71162383-1336-457c-92a5-3e7ed55c9f8f)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(71162383-1336-457c-92a5-3e7ed55c9f8f)
SignalR.Transports.ServerSentEventsTransport Information: 0 : Abort(71162383-1336-457c-92a5-3e7ed55c9f8f)
SignalR.Transports.TransportHeartBeat Information: 0 : Removing connection 71162383-1336-457c-92a5-3e7ed55c9f8f
SignalR.Transports.ServerSentEventsTransport Information: 0 : End(71162383-1336-457c-92a5-3e7ed55c9f8f)
SignalR.Transports.ServerSentEventsTransport Verbose: 0 : DrainWrites(71162383-1336-457c-92a5-3e7ed55c9f8f)
SignalR.Transports.ServerSentEventsTransport Information: 0 : CompleteRequest (71162383-1336-457c-92a5-3e7ed55c9f8f)

@blindberg74 Are you sure that OnConnected was called on the same hub for the same client before disconnecting?

Yes I have verified that the initial connection was made.

Yes, I met the problem too.

There's any recommendation to deal with the cases when the OnDisconnected is invoked without calling the Stop on the Client? I want to try to inform my client that he's no longer recognized by the Server.

@blindberg74 @halter73 Is there any progress on this? I am using SignalR 2.2.2 and having the same issue. My .Net client connects and server OnConnected fires properly, however when connection.Stop() on client, OnDisconnected() is never hit.

Is there any news?

This issue was closed a while ago, please file a new issue with a description of the expected behavior and the actual behavior. If possible, please collect client and server traces as described in the SignalR Tracing documentation and attach them to the issue.

Was this page helpful?
0 / 5 - 0 ratings