BlazorSignalR icon indicating copy to clipboard operation
BlazorSignalR copied to clipboard

[WIP] Server-side blazor support

Open CatoLeanTruetschel opened this issue 5 years ago • 14 comments

This is a prototype to make available the library server-side, running with Razor Components. The biggest issues are solved but it is not running server-side yet.

To support this, the IUriHelper needs to be injected as server, as it was needed with the js runtime on the blazor 0.9.0 update. This will incur breaking changes.

There are some code parts, that need to know whether it is running on blazor, this is currently done by checking for loaded assemblies (in particual if the Microsoft.AspNetCore.Mvc assembly is loaded). This is a temporary workaround only and need to be replaced. Maybe there is a way of checking whether we are running on Mono WASM or we let the user configure this in the options.

Fixes #23

CatoLeanTruetschel avatar Mar 15 '19 18:03 CatoLeanTruetschel

@AndreasTruetschel Any progress?

csnewman avatar May 12 '19 14:05 csnewman

I'm currently working on this. Work that I want to complete before merge:

  • Replace the usage of the WebAssemblyHttpMessageHandler to send everything to the client
  • Merge the test projects
  • Review the breaking changes (and allow the usage with the old api, disabling the server-side support in this case)

CatoLeanTruetschel avatar May 18 '19 12:05 CatoLeanTruetschel

Thanks.

I assume you're just creating a "BrowserHttpMessageHandler"/"BlazorHttpMessageHandler" or something of the sorts that will be used regardless of whether it's server side of client side blazor?

csnewman avatar May 18 '19 12:05 csnewman

Would it also be possible for the RazorComponents naming to be replaced with ServerSideBlazor as they have switched back to the old naming?

csnewman avatar May 18 '19 13:05 csnewman

Would it also be possible for the RazorComponents naming to be replaced with ServerSideBlazor as they have switched back to the old naming?

Sure. I wanted to do this anyway.

CatoLeanTruetschel avatar May 18 '19 13:05 CatoLeanTruetschel

I assume you're just creating a "BrowserHttpMessageHandler"/"BlazorHttpMessageHandler" or something of the sorts that will be used regardless of whether it's server side of client side blazor?

This would be a solution but needs the complete replacement and therefore reimplementation (or fork) of the WebAssemblyHttpMessageHandler. I have the hope that we can make the WebAssemblyHttpMessageHandler work with server-side blazor but I need to have a look into the repo whether this is possible.

@csnewman Do you have a better idea for this?

CatoLeanTruetschel avatar May 18 '19 14:05 CatoLeanTruetschel

I assume you're just creating a "BrowserHttpMessageHandler"/"BlazorHttpMessageHandler" or something of the sorts that will be used regardless of whether it's server side of client side blazor?

This would be a solution but needs the complete replacement and therefore reimplementation (or fork) of the WebAssemblyHttpMessageHandler. I have the hope that we can make the WebAssemblyHttpMessageHandler work with server-side blazor but I need to have a look into the repo whether this is possible.

@csnewman Do you have a better idea for this?

Afaik the webassembly one uses WebAssemblyJsRuntime explicitly. I also assume the JS probably isn't included as the server side blazor uses a different js file in the browser.

I therefore get the impression that a custom message handler will have to be made (well copied).

csnewman avatar May 18 '19 14:05 csnewman

I looked into this. The typescript code of the original implementation has to be changed massively, as they do not use ordinary interop but rely on the fact that this thing runs on web assembly. If this is forked and adapted in order to be used both, client and server-side it will incure a massive hit in performance IMO as this will need to work with json serialization then.
For example the result is directly written into a .net array that is pre-allocated without marshaling the array. See also: https://github.com/aspnet/AspNetCore/issues/5619#issuecomment-451943486

I don't think this will be possible in general, when we do not know that we are running client-side within wasm.

CatoLeanTruetschel avatar May 18 '19 18:05 CatoLeanTruetschel

Maybe a slight change of course is a better option.

Currently HttpClient etc is only needed for the inbuilt c# transports, i.e. ServerSentEventsTransport, whereas the JS proxied versions like BlazorServerSentEventsTransport have no need for it.

Maybe instead we can detect if running on server side blazor and disable any non-js transports in CreateTransport. This should require a lot less effort, and then the performance overhead will be lowered as much as possible (only the actual data being sent will be serialised as json instead of all HTTP overhead).

csnewman avatar May 19 '19 13:05 csnewman

Thats seems to be a reasonable approach. However we need a HttpClient instance anyway (for the negotiation). I will continue with forking WebAssemblyHttpMessageHandler and make it work server-side. When creating a transport I will then create a HttpClient via WebAssemblyHttpMessageHandler when running client-side and via the fork when running server-side.

CatoLeanTruetschel avatar May 19 '19 13:05 CatoLeanTruetschel

This is working now for both server and client-side projects. I tried to re-use and/or link most of the stuff in the server projects as it is not possible for now to combine these without copying a lot of source code from the blazor repo. It seems they are currently working on this so maybe we can do this soon.

Still open issues:

  • Server-side blazor cannot import static content as of the current version. I copied the js-files for this project and the BlazorExtensions.Logging project to the wwwroot folder. I also tried to use this but couldn't make it work yet.
  • The browser console is playing tango in the client-side and server-side case. I have to take a deeper look on this.

@csnewman Can you please review the latest changes?

CatoLeanTruetschel avatar May 19 '19 16:05 CatoLeanTruetschel

It feels like a lot of baggage having a custom HttpMessageHandler if it is only used for the negotiation. Instead having just a JS implemented negotiater might simply things.

csnewman avatar May 19 '19 20:05 csnewman

The browser console is playing tango in the client-side and server-side case. I have to take a deeper look on this.

I don't think this is a problem in our code but a bug in the BrowserConsoleLogger. I will file a bug there eventually.

Edit: This is the issue: https://github.com/BlazorExtensions/Logging/issues/28

CatoLeanTruetschel avatar May 23 '19 08:05 CatoLeanTruetschel

The browser console is playing tango in the client-side and server-side case. I have to take a deeper look on this.

I don't think this is a problem in our code but a bug in the BrowserConsoleLogger. I will file a bug there eventually.

Edit: This is the issue: BlazorExtensions/Logging#28

Ah. I see the people over BlazorExtensions/Logging#28 have been rather unhelpful.

csnewman avatar May 24 '19 22:05 csnewman