How to enable compressed binary messaging in SignalR with Blazor WebAssembly with MessagePack

164 Views Asked by At

Hello fabulous Blazor & SignalR gurus!

My objective is to add (hopefully compressed) binary messaging between my ASP.NET Core server with SignalR and my Blazor WebAssembly by properly configuring 'MessagePack'

Messaging is fully operational in both directions but I notice in the browser's network monitor that the websocket used by SignalR still sends its messages via JSON and Base64. Not only is my stream not compressed as configured server-side but Base64 throws away 2 bits out of 8 yielding a pipe efficiency decrease of around 28%.

It is my understanding that the 'MessagePack' protocol be used to enable full binary communication (removing the usage of JSON / Base64) and I have been following the relevant article at https://learn.microsoft.com/en-us/aspnet/core/signalr/messagepackhubprotocol

As recommended in the above instructions, here is my current code in my server-side WebApplication builder:

  .AddMessagePackProtocol(options => {
    options.SerializerOptions = MessagePackSerializerOptions.Standard
      .WithResolver(MessagePack.Resolvers.StandardResolver.Instance)
      .WithSecurity(MessagePackSecurity.UntrustedData)
      .WithCompression(MessagePackCompression.Lz4Block)
      .WithCompressionMinLength(256);
    });

However, the same instructions mention to add the following to my '.net client'...

    var hubConnection = new HubConnectionBuilder()
                        .WithUrl("/chathub")
                        .AddMessagePackProtocol()
                        .Build();

Unfortunately, the sample I've been basing my WebAssembly work on has no concept of a HubConnectionBuilder object and creates its builder as follows:

var builder = WebAssemblyHostBuilder.CreateDefault(args);

Trying everything I could think of, I cannot find a way to find a sub-object of 'WebAssemblyHostBuilder' where I could call the 'AddMessagePackProtocol()' so that MessagePack also works client-side

EDIT: I was looking at the wrong place! Client-side SignalR init is in .razor page (see answer post below)

My hunch is that the server side is properly configured for (compressed) MessagePack but the web-assembly client is not, so I still get JSON + Base64 messaging. (I can live without compression support within MessagePack but would like to lose the 28% pipe efficiency drop caused by JSON + Base64)

Key questions:

  • Q1: Is MessagePack supported in Blazor WebAssemblies?
  • Q2: What is the proper procedure to configure the SignalR pipe within Blazor WASM to use MessagePack?
  • Q3: Is MessagePack the highest-performance pipe for my client/server architecture?

Thank you very much for any hint you can offer!

Jean-Pierre

1

There are 1 best solutions below

0
On

Found it thanks to the awesome hint by Brennan!

For some reason, I was only looking at my client's top-level file thinking that SignalR needed to be configured there as it is done this way server-side. But of course, the code to init SignalR is in any given Razor page that needs it so I was able to complete the instructions as Microsoft recommended, and bingo!

Here is my code in OnInitializedAsync() of my web client Razor page (same as I have server-side):

    protected override async Task OnInitializedAsync() {
        g_oHubConn = new HubConnectionBuilder()
                .WithUrl(Navigation.ToAbsoluteUri("/datumhub"))
                .AddMessagePackProtocol(options => {
                    options.SerializerOptions = MessagePackSerializerOptions.Standard
                        .WithResolver(MessagePack.Resolvers.StandardResolver.Instance)
                        .WithSecurity(MessagePackSecurity.UntrustedData)
                        .WithCompression(MessagePackCompression.Lz4Block)
                        .WithCompressionMinLength(256);})
                .Build();
        more...

As cool as full-auto compression is however, it is NOT as efficient on bandwidth as compressing / decompressing myself with the normal .net Deflate calls. (I get a 2.99 X compression with SignalR + Messagepack but much higher 7.55 X with manual calls)

Thanks Brennan for the hint on that one... U rock dude!