Improve gRPC-Web over HTTP/1.1 with .NET Core client in .NET 5+
See original GitHub issueI 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:
- Created 3 years ago
- Comments:8 (3 by maintainers)
Top GitHub Comments
There is a
GrpcWebHandler.HttpVersion
property. Could you try setting that tonew Version(1, 1)
and see whether you still get that error.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.