dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.43k stars 10.02k forks source link

[SignalR] Stateful reconnect #46691

Closed BrennanConroy closed 10 months ago

BrennanConroy commented 1 year ago

Allows the server to retain the send buffer while the client is reconnecting and preserve connection state (Context.Items, connection ID, etc.).

Thoughts:

Needs work:

johnkattenhorn commented 1 year ago

Hey @BrennanConroy, we've seen the pull request and the proposal, we think this will be a great feature for our use-case of mobile gaming which we've been working with @kevinguo305 on. We are working on a plan to put a reference architecture to illustrate how to use signalR in gaming.

@kevinguo305 - do you know if the team who built the UnityClient are aware of this work going on this feature ?

BrennanConroy commented 1 year ago

Glad to hear it! Are you in a position to be able to try out .NET previews? We're planning on getting the initial implementation into 8.0-preview5 and would love to find folks to try it out and make sure it works well.

johnkattenhorn commented 1 year ago

Yep - we would be happy to try it out.

BrennanConroy commented 1 year ago

@johnkattenhorn preview 5 is out. To try this out you have to use the .NET client with WebSockets and enable the feature option:

var hubConnection = new HubConnectionBuilder()
    .WithUrl("<hub url>",
             options =>
             {
                options.UseAcks = true;
             })
    .Build();
TimChen44 commented 1 year ago

This capability is too important for Blazor Server, and I hope that in the future, Blazor Server will not cause the entire program to crash due to network reasons.

Webreaper commented 1 year ago

Glad to hear it! Are you in a position to be able to try out .NET previews?

I'd love to try/test this, but for some reason .Net 8 previews still aren't supported by VS for Mac. Maybe in preview 6?

m33p commented 1 year ago

I wanted to give my feedback and this feature. This feature is amazing and a must have. I've been engaging with our VPN team with connection issues to our Blazor application. One of our VPN or firewall is dropping the websocket connection. After testing with this feature turned on the issue isn't even noticeable. Please ship this with .NET 8.

adityamandaleeka commented 1 year ago

That's great to hear @m33p. @johnkattenhorn Have you had a chance to try it as well?

As you've seen, we got the initial implementation out in preview 5 and plan to make some improvements in preview 7. I'm moving the milestone on this issue to reflect that.

johnkattenhorn commented 1 year ago

Hey @adityamandaleeka,

I've asked the team if we have any feedback in this and will come back asap.

agrubbszenzio commented 1 year ago

@johnkattenhorn preview 5 is out. To try this out you have to use the .NET client with WebSockets and enable the feature option:

var hubConnection = new HubConnectionBuilder()
    .WithUrl("<hub url>",
             options =>
             {
                options.UseAcks = true;
             })
    .Build();

Looking for documentation on where to implement this. Can this be placed in the program.cs?

We have a dashboard business app that loses connectivity and are planning to give this a go. We are hoping to keep the project in Blazor server side.

Thanks

BrennanConroy commented 1 year ago

connection issues to our Blazor application.

@m33p I assume you're using Blazor WASM and have a component using HubConnection? Glad that it's working better for you!

We are hoping to keep the project in Blazor server side.

@agrubbszenzio This isn't possible yet since Blazor server side uses the Javascript SignalR client which doesn't implement this feature yet. We're nailing down the details with the .NET client first before getting other clients updated. Javascript client will be next though.

8.0-preview6 is out today and does require the server to opt-in to this feature now to use it.

Example code: Server:

app.MapHub<AppHub>("/default", o => o.AllowAcks = true);

Client:

var hubConnection = new HubConnectionBuilder()
    .WithUrl("<hub url>",
             options =>
             {
                options.UseAcks = true;
             })
    .Build();
Webreaper commented 1 year ago

8.0-preview6 is out today and does require the server to opt-in to this feature now to use it.

This is exciting - I'd like to try it. Do we know if preview 6 will finally add VS for Mac support?

BrennanConroy commented 1 year ago

Do we know if preview 6 will finally add VS for Mac support?

No idea. I think the relationship is the other way around though: "Does VS for Mac support 8.0-preview6?"

Webreaper commented 1 year ago

Turns out the answer is Yes!

Webreaper commented 1 year ago

I'm trying this in my app, but I'm getting an error for options.UseAcks = true; - compiler is saying there's no UseAcks property. This is with .Net 8 preview 6. Did it definitely get into the release?

BrennanConroy commented 1 year ago

I'm trying this in my app, but I'm getting an error for options.UseAcks = true; - compiler is saying there's no UseAcks property. This is with .Net 8 preview 6. Did it definitely get into the release?

Yes, it's definitely been present since preview5. This likely means you aren't actually using the preview builds.

Webreaper commented 1 year ago

Yes, it's definitely been present since preview5. This likely means you aren't actually using the preview builds.

I was definitely using the preview builds, because I had other code using features from preview 6. However, I just uncommented that line, and it's not generating a compiler error (I haven't installed any updated SDKs since I last tried). Very very weird. But looks better now!

WhitWaldo commented 1 year ago

This isn't possible yet since Blazor server side uses the Javascript SignalR client which doesn't implement this feature yet. We're nailing down the details with the .NET client first before getting other clients updated. Javascript client will be next though.

I, too, am really looking forward to seeing this functionality in Blazor Server once it's been fleshed out in this context.

juanyacovino77 commented 1 year ago

Hey,

is there a guaranteed way of sharing state between SignalR client and the hub? I mean guaranteed because we know HttpContext it is not.

For example, I would like to receive data from the client at the OnConnected() Hub event... How could I make this? (out of using headers and cookies)

Let say I have the list of connectionId s mapped with user id at in-memory dictionary or using Context.Items.. at the moment the conection get disconnected I need to map that (disconnected) connectionid to the corresponding connected new one ...(in order to identify the same device) The only way of mapping the last disconnect connectionId with the new one it to define a new hub method and call it from the client with the parameters.

I am using ASP.NET Core 6.

it would be useful to have more info about the SignalR conection context (not http)

thanks

benguenter commented 1 year ago

Very excited about this feature, at what point after the .net 8 release will this be available when using the Azure SignalR Service?

Sebazzz commented 1 year ago

This isn't possible yet since Blazor server side uses the Javascript SignalR client which doesn't implement this feature yet.

Is this expected before RTM, or do we need to wait on .NET 9 for that?

BrennanConroy commented 1 year ago

This isn't possible yet since Blazor server side uses the Javascript SignalR client which doesn't implement this feature yet.

Is this expected before RTM, or do we need to wait on .NET 9 for that?

This will work in 8.0-rc2

adityamandaleeka commented 1 year ago

@BrennanConroy can we call this issue done now?

pigwing commented 1 year ago

This isn't possible yet since Blazor server side uses the Javascript SignalR client which doesn't implement this feature yet.

Is this expected before RTM, or do we need to wait on .NET 9 for that?

This will work in 8.0-rc2

https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-8-rc-2/ image

blazor haven't updated it yet?^_^

BrennanConroy commented 1 year ago

Blazor can be configured for the client side via https://learn.microsoft.com/aspnet/core/blazor/fundamentals/signalr?view=aspnetcore-7.0#configure-signalr-timeouts-and-keep-alive-on-the-client, you still need server side settings as well.

pigwing commented 1 year ago

thx

kescherCode commented 1 year ago

Would this work with Azure SignalR as-is or will it require explicit support on their end?

BrennanConroy commented 1 year ago

Azure SignalR Service requires explicit support.

hrytskivr commented 1 year ago

Can this work with Redis backplane and when web-api is scaled out behind load balancer? With sticky sessions not configured and skipNegotiation: true on the client side.

BrennanConroy commented 1 year ago

With sticky sessions not configured and skipNegotiation: true on the client side.

No, you need sticky sessions.

XorZy commented 1 year ago

How to configure the server to enable stateful reconnect with InteractiveServerRenderMode? I don't see where in the new template one could set that option.

pigwing commented 1 year ago

app.MapRazorComponents<App>() .AddInteractiveServerRenderMode().Add(convention => { var meta = convention.Metadata.FirstOrDefault(e => e is HttpConnectionDispatcherOptions); if (meta != null) { HttpConnectionDispatcherOptions options = (HttpConnectionDispatcherOptions)meta; options.AllowStatefulReconnects = true; } }); I found this method at present.

mkArtakMSFT commented 11 months ago

Removing the milestone for the team to retriage

Benedicht commented 10 months ago

Is there an up-to-date documentation for implementors about this feature?

adityamandaleeka commented 10 months ago

@Benedicht I've opened #53103 to track your question about the doc. I'm going to close this issue now since it was originally meant to track getting stateful reconnect done, which has now shipped in .NET 8. Further work/issues can be tracked separately.