-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Description
Describe the bug
I have a small setup where a C# client invokes a server method without parameters, simply waiting for an URL to return (both are v3.0.0-preview5). In my test setup, the server works on that zip file for 100s. During the call, the server prepares a zip file and returns a link to that file once finished. The server frequently sends status updates to the client.
With logs enabled on both sides and also using wireshark, I can see that the client sends pings regularly. However, if I get the source code right, the server does not process these pings due to the pending await call. The following happes:
- after 30s, the server detects that no new message was received but continues without complains (I think this is intended)
- after 60s, the server detects again that no frame was received and tries to abort the connection, but the invoked method continues to run. At this point, the client is not receiving status updates anymore from the server.
- after 90s, the server detects again that no frame was received and tries to abort the connection, but the invoked method continues to run
- after 100s, the invoked method returns, and the connection is actually aborted.
OnDisconnectedAsync
is called. On the client side, the error "A task was cancelled" appears.
I am not sure if this is by design (i.e. 'don't use async/await for very long running methods'), or if this is a bug, since the pings from the client are not processed.
If it is by design, what is the recommended alternative, when a client needs to wait for a long running methods?
To Reproduce
Hub content:
using Microsoft.AspNetCore.SignalR;
using System;
using System.Threading.Tasks;
namespace WebApplication1
{
public class Broadcaster : Hub<IBroadcaster>
{
public Task<string> GetUrl()
{
int counter = 0;
return Task.Run(async () =>
{
for (int i = 0; i < 100; i++)
{
await Task.Delay(TimeSpan.FromSeconds(1));
await this.Clients.Client(this.Context.ConnectionId).SendProgress(counter, "Progress");
counter += 1;
}
return "url";
});
}
}
}
Callback interface:
using System.Threading.Tasks;
namespace WebApplication1
{
public interface IBroadcaster
{
Task SendProgress(double percent, string message);
}
}
Client:
_connection.On("SendProgress", (double percent, string message) =>
{
Console.WriteLine($"{percent,3:0}%: {message}\n");
});
var url = await _connection.InvokeAsync<string>("GetUrl");
Expected behavior
I would expect that during an active connection where the client sends ping messages and server sends status updates, the connection is not cancelled.
Additional context
Include the output of dotnet --info
.NET Core SDK (gemäß "global.json"):
Version: 3.0.100-preview5-011568
Commit: b487ff10aa
Laufzeitumgebung:
OS Name: Windows
OS Version: 10.0.17763
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.0.100-preview5-011568\
Host (useful for support):
Version: 3.0.0-preview5-27626-15
Commit: 61f30f5a23
.NET Core SDKs installed:
2.1.602 [C:\Program Files\dotnet\sdk]
2.2.203 [C:\Program Files\dotnet\sdk]
3.0.100-preview5-011568 [C:\Program Files\dotnet\sdk]
.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0-preview5-19227-01 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0-preview5-27626-15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.0.0-preview5-27626-15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]