Skip to content

SignalR Core Abort() leads to undefined state #21422

@Tommigun1980

Description

@Tommigun1980

Describe the bug

Calling Abort() in a hub leads to the client's connection status being set to Reconnecting, but only sometimes is a reconnection attempt made. Client's Closed callback is not invoked when this happens. Stopping the connection on the client, while in this state, throws an exception (this part is correct I guess).

Expected behaviour:
When Abort() is called in a hub on server:
Client's Closed callback should get invoked, and client's status should be set to Disconnected. Client should not try to reconnect. It is problematic that it ends up in a Reconnecting state and sometimes tries to reconnect, while completely skipping the closed callback.

To Reproduce

In server's hub, call the following. (Please note that I am actually calling Abort() from outside the hub, by storing the context of the hub in a ConcurrentDictionary in a singleton service as per #5333, until there is a real way to disconnect clients outside the hub. I would assume the bug is exposed even when just calling Abort() inside a hub such as:).

this.Context.Abort();

On client:

        public async Task Connect()
        {
            // close existing connection to allow for a new token
            if (this.connection != null)
            {
                if (this.connection.State != HubConnectionState.Disconnected)
                    await this.connection.StopAsync();
                await this.connection.DisposeAsync(); // TODO: is this needed??
                this.connection = null;
            }

            this.connection = new HubConnectionBuilder()
                .WithUrl("someUrl", (options) =>
                    .options.AccessTokenProvider = () => Task.FromResult("SomeToken");
                )
                .WithAutomaticReconnect()
                .Build();

            this.connection.Closed -= this.OnConnectionClosed;
            this.connection.Closed += this.OnConnectionClosed;
            await this.connection.StartAsync();
        }

        private Task OnConnectionClosed(Exception exception)
        {
            Console.WriteLine($"Connection closed: {exception}");
            if (exception is HubException)
            {
                // cleanup here
            }
            return Task.CompletedTask;
        }

Further technical details

  • ASP.NET Core version:
    3.1.2

  • Include the output of dotnet --info:
    .NET Core SDK (reflecting any global.json):
    Version: 3.1.200
    Commit: c5123d973b

Runtime Environment:
OS Name: Mac OS X
OS Version: 10.15
OS Platform: Darwin
RID: osx.10.15-x64
Base Path: /usr/local/share/dotnet/sdk/3.1.200/

Host (useful for support):
Version: 3.1.2
Commit: 916b5cba26

.NET Core SDKs installed:
3.1.200 [/usr/local/share/dotnet/sdk]

.NET Core runtimes installed:
Microsoft.AspNetCore.App 3.1.2 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.16 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.17 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.2 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

  • The IDE (VS / VS Code/ VS4Mac) you're running on, and it's version:
    VS For Mac 8.6 Preview (build 4387)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions