dotnet / systemweb-adapters

MIT License
332 stars 58 forks source link

Added sample demonstrating how to connect session with Blazor and WebForms #466

Open pockets3407 opened 6 months ago

pockets3407 commented 6 months ago

PR Title Added sample demonstrating how to connect session with Blazor and WebForms

PR Description Added sample demonstrating how to connect session with Blazor and WebForms

The only issue I have found is that I get an exception that breaks navigation. This occurs when I navigate from an InteractveServer page (Counter) to a static page (Home, Weather). I'm not sure if this is a different issue.

Addresses #382

pockets3407 commented 6 months ago

@dotnet-policy-service agree

twsouthwick commented 6 months ago

How is this different from this sample: https://github.com/dotnet/systemweb-adapters/tree/main/samples/WebFormsToBlazor

pockets3407 commented 6 months ago

My sample demonstrates sharing session data between Blazor and WebForms with HttpContext added in NET 8. The other sample demonstrates forwarding and displaying Blazor components in WebForms in NET 7. If it would make more sense to combine the two samples, I can do that. I just didn't want to jam everything into one sample.

twsouthwick commented 6 months ago

Yeah, let's have a one stop-shop for the the blazor/webforms sample. Both are helpful things to show, but it would be greato show how they may complement each other two (and verify that they do!)

pockets3407 commented 6 months ago

Ok, I will combine them and update the PR on Monday.

pockets3407 commented 6 months ago

@twsouthwick It looks like Blazor components in WebForms needs Blazor Interactive Server. I don't think I can combine the two unless System.Web.Adapters supports Blazor Interactive Server. As soon as blaozr.server.js loads, I can no longer navigate.

twsouthwick commented 6 months ago

I think we want to figure out why that's happening then. We should be playing nicely with blazor, and if there are issues those should be addressed. If there are limitations that we can't work around, those should be addressed.

pockets3407 commented 6 months ago

It hangs in RemoteAppSessionStateManager when requesting from Counter (page with Interactive Server) to another page (using static rendering). The request gets to GetSessionDataAsync and hangs at the backchannel request. I set a breakpoint inside PostMapRequestHandler on the framework side and the request exits this event, so I am not sure where this could be holding up.

If it doesn't succeed, it is because the request hits the 100 second timeout.

If it works and finishes before the timeout (rare, but I have reproduced it a few times), I get a status code 400 from SetOrReleaseSessionState, but everything seems to be working fine until you repeat it by going from interactive server to another page.

The current sample that I added can easily reproduce it.

pockets3407 commented 6 months ago

After further investigation (and gaining a better understanding of what his happening on both the blazor side and systemweb.adapters side), it looks like SessionLoadMiddleware is deadlocking on the blazor server request. When page is requested using InteractiveServer the following 3 requests come through the middelware

  1. GET: /counter
  2. POST: /_blazor/negotiate
  3. CONNECT: /_blazor

I am assuming 2 and 3 are from establishing the SignalR connection with Blazor interactive SSR. When request 3 (Connect) comes through, it will stay open until Blazor sends a disconnect request. Since it stays open, the session is not properly committed and will stay in the heartbeat loop on the framework side.

There is probably a better way to do this, but to temporarily fix it while I edit my sample, I am adding the following: In UseSystemWebAdapters:

        app.UseWhen(
            (context) => context.Request.Method != HttpMethods.Connect,
            (builder) => builder.UseMiddleware<SessionLoadMiddleware>());

@twsouthwick

erpardeepkaushik commented 5 months ago

Hi @pockets3407 @twsouthwick is the Issue #382 is resolved? and your new sample is ready to try?

pockets3407 commented 4 months ago

@twsouthwick Do you have any preference on my suggested fix to get this working with blazor server? Do you want me to open another pull request for it that is separate from the sample?

pockets3407 commented 4 months ago

I manually added a workaround to the sample, so System.WebAdapters can be used with SignalR. System.WebAdapters middleware can be ignored when there is a Connect request or the request is coming from Blazor SignalR. I decided to use the former, because I thought HttpMethods.IsConnect() would be more optimized than checking if the path contains "_blazor", but both are shown in the sample. This will be the workaround I will use when 1.4 is released.

@twsouthwick The sample is ready waiting to be approved.

@erpardeepkaushik Feel free to use the sample on my branch. I am not sure when it will be committed to the repo.

erpardeepkaushik commented 3 months ago

@pockets3407 I tried the samples but due to preview versions unable to run the solution. I will wait for your release version.

zachrybaker commented 3 months ago

This is a peculiar PR. Neither app has any authentication. Given the technology gaps here, a solid example of shared session also would do well to demonstrate it in a real context, i.e. with authenticated views involved.