angularsignalrmsgpack.net-5lz4

.net 5 - Signalr - Messagepack - lz4 - Error: unable to find ext type 98


Got this error un .net core 5 solution with angular client after enabling lz4BlockArray compression. Without compression everithing seems to work pretty fine. Looking around for motivation but i found nothing. Seems like some decoders aren't loaded correctly.

That's client side error, no server side error

Utils.js:208 [2020-12-01T09:01:42.527Z] Trace: (WebSockets transport) data received. Binary data of length 1086.
core.js:4352 ERROR Error: unable to find ext type 98
    at decodeExt (decoder.js:432)
    at tryDecode (decoder.js:266)
    at decodeArray (decoder.js:338)
    at tryDecode (decoder.js:288)
    at decodeArray (decoder.js:338)
    at tryDecode (decoder.js:288)
    at decodeArray (decoder.js:338)
    at tryDecode (decoder.js:288)
    at Object.decode (decoder.js:103)
    at MessagePackHubProtocol.push.jxpC.MessagePackHubProtocol.parseMessage (MessagePackHubProtocol.js:79)

To Reproduce

My configuration:

Partial project

<PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
    <TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
    <IsPackable>false</IsPackable>
    <SpaRoot>ClientApp\</SpaRoot>
    <DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>

    <BuildServerSideRenderer>false</BuildServerSideRenderer>
    <Configurations>Debug;Release;Development;DStaging;DProduction;Staging;Production</Configurations>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="HtmlSanitizer" Version="5.0.355" />
    <PackageReference Include="IdentityModel" Version="4.5.0" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="5.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="5.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="5.0.0" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.0" />
    <PackageReference Include="NLog.Targets.ElasticSearch" Version="7.5.0" />
    <PackageReference Include="NLog.Web.AspNetCore" Version="4.9.3" />
  </ItemGroup>

Startup.cs

  var resolver = CompositeResolver.Create(
               DynamicEnumAsStringResolver.Instance,
               StandardResolver.Instance
           );
           services.AddSignalR().AddMessagePackProtocol(

               option =>
               {
                   option.SerializerOptions =
                       MessagePackSerializerOptions.Standard.WithResolver(resolver)
                           .WithCompression(MessagePackCompression.Lz4BlockArray)
                           .WithSecurity(MessagePackSecurity.UntrustedData);
               });

package.json

"@microsoft/signalr": "^5.0.0",
"@microsoft/signalr-protocol-msgpack": "^5.0.0",

Connection

const builder = new HubConnectionBuilder();
      // as per setup in the startup.cs
      this._hubConnection = builder.withUrl('url', {
        accessTokenFactory:
          () => {
            const token = sessionStorage.getItem('token');
            return JSON.parse(token).access_token;
          },
      }).configureLogging(signalR.LogLevel.Trace).withAutomaticReconnect(new SignalrRetryPolicy()).withHubProtocol(new MessagePackHubProtocol()).build();

tsconfig

{
  "compileOnSave": true,
  "compilerOptions": {
    "baseUrl": "./",
    "downlevelIteration": true,
    "module": "es2020",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es2015",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2017",
      "dom"
    ]
  }
}

Thanks for your help


Solution

  • From the .NET MessagePack libraries README

    MessagePackCompression has two modes, Lz4Block and Lz4BlockArray. Neither is a simple binary LZ4 compression, but a special compression integrated into the serialization pipeline, using MessagePack ext code (Lz4BlockArray (98) or Lz4Block (99)). Therefore, it is not readily compatible with compression offered in other languages.

    The important part is the last sentence, other languages might not be compatible. And in this case the Angular client is using a MessagePack library that doesn't support these ext codes for compression.