question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Improve gRPC-Web over HTTP/1.1 with .NET Core client in .NET 5+

See original GitHub issue

I am working on a Grpc project built with .Net Core 3.1 (both: client and server). Server is deployed to Azure App Service (we are using grpc-web) - everything worked correctly so far.

After upgrading the whole project to .Net 5 (only projects and packages, no code changes) and after deploying server to Azure App Service (net 5. Self-contained), the client stopped working while calling service, throwing an exception (attached). The same project with no changes works correctly with local console server and with linux docker container (run from Visual Studio),

Are there any configuration changes required on server/client after upgrading to .Net 5 for Azure App Service?

Exceptio details:

Grpc.Core.RpcException: ‘Status(StatusCode=“Internal”, Detail=“Error starting gRPC call. HttpRequestException: Requesting HTTP version 2.0 with version policy RequestVersionOrHigher while server offers only version fallback.”, DebugException=“System.Net.Http.HttpRequestException: Requesting HTTP version 2.0 with version policy RequestVersionOrHigher while server offers only version fallback. at System.Net.Http.HttpConnectionPool.GetHttp2ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at Grpc.Net.Client.Web.GrpcWebHandler.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken) at Grpc.Net.Client.Internal.GrpcCall 2.RunCall(HttpRequestMessage request, Nullable 1 timeout)”)’

Server (Program.cs):

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
       WebHost.CreateDefaultBuilder(args)
           .ConfigureKestrel(options =>
           {
              options.Limits.MinRequestBodyDataRate = null;
           })
          .ConfigureAppConfiguration(SetupConfiguration)
          .UseStartup<Startup>();

Server (Startup.cs):

public void ConfigureServices(IServiceCollection services)
{
      ...
      services.AddGrpc().AddServiceOptions<MyGrpcService>(options =>
      {
         options.ResponseCompressionLevel = CompressionLevel.Fastest;
         options.ResponseCompressionAlgorithm = "gzip";               
      });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
     ...
     app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });
     app.UseEndpoints(endpoints =>
     {
         endpoints.MapGrpcService<MyGrpcService>().EnableGrpcWeb();
     });
}

Client:

  private MyGrpcService.MyGrpcServiceClient GetClient()
  {
      var handler = new GrpcWebHandler(
          GrpcWebMode.GrpcWeb, 
          new HttpClientHandler 
          { 
             ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
          });

     var channel = GrpcChannel.ForAddress(
        "https://myurlonazureappservice.com",
        new GrpcChannelOptions
        {
             HttpClient = new HttpClient(handler),
        }); 
              
    return new MyGrpcService.MyGrpcServiceClient(_channel) ;
 }

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

4reactions
JamesNKcommented, Nov 11, 2020

There is a GrpcWebHandler.HttpVersion property. Could you try setting that to new Version(1, 1) and see whether you still get that error.

var handler = new GrpcWebHandler(...);
handler.HttpVersion = new Version(1, 1);
0reactions
zbigniew-gajewskicommented, Nov 11, 2020

If I understand correctly, Version(1,1) should be a default only for grpc-web (for Azure App Service). In our case we are deploying the same project to AKS with Http/2 only (without grpc-web), so in such cases Version(2,0) as a default would be OK. Maybe handler.Version = new Version(1,1) should be somehow included into grpc-web usage documentation, not as a client default. Or fix description should be included into exception details. Grpc is designed for Http/2, so Version(2.0) as a default make sense.

Read more comments on GitHub >

github_iconTop Results From Across the Web

gRPC-Web in ASP.NET Core gRPC apps
Learn how to configure gRPC services on ASP.NET Core to be callable from browser apps using gRPC-Web.
Read more >
Is it possible to use gRPC with HTTP/1.1 in .NET Core?
No, you cannot use gRPC on HTTP 1.1; you may be able to use the Grpc.Core Google transport implementation, however, instead of the...
Read more >
Use gRPC in the Browser With gRPC-Web and .NET5
This will walk you through creating your first gRPC server and client using .NET 5). 1 — The Problem. In a previous article,...
Read more >
A Complete Guide to gRPC-Web with Angular and .NET
The “web” client in gRPC-Web receives requests over HTTP 1.1 or HTTP/2 and then sends the requests through a proxy.
Read more >
Grpc.Net.Client.Web 2.55.0
gRPC -Web .NET clients don't support calling client streaming and bidirectional streaming methods over HTTP/1.1. ASP.NET Core gRPC services hosted on Azure ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found