GrpcChannelOptions: Can't configure HTTP/3 with client load balancing
johncrim opened this issue · 4 comments
What version of gRPC and what language are you using?
C#
Grpc.Net.Client 2.61.0
What operating system (Linux, Windows,...) and version?
Windows 11 + Linux Ubuntu-22.04
What runtime / compiler are you using (e.g. .NET Core SDK version dotnet --info
)
targeting .NET 7 on
dotnet --info
.NET SDK:
Version: 8.0.202
Commit: 25674bb2f4
Workload version: 8.0.200-manifests.8cf8de6d
Runtime Environment:
OS Name: Windows
OS Version: 10.0.22631
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\8.0.202\
Host:
Version: 8.0.3
Architecture: x64
Commit: 9f4b1f5d66
.NET SDKs installed:
6.0.420 [C:\Program Files\dotnet\sdk]
8.0.202 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.28 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
What did you do?
While configuring a GRPC client, trying to use HTTP/3 and a load balancer, I'm not able to configure the GrpcChannelOptions
to both use HTTP/3 and the load balancer, b/c it is rejected by GrpcChannel.ValidateHttpHandlerSupportsConnectivity()
.
Here's the code I'm using:
private static void ConfigureInternalGrpcChannel(GrpcChannelOptions options)
{
// Setup load balancing
var serviceConfig = new ServiceConfig();
serviceConfig.LoadBalancingConfigs.Add(new RoundRobinConfig());
options.ServiceConfig = serviceConfig;
var httpHandler = new SocketsHttpHandler()
{
EnableMultipleHttp2Connections = true,
SslOptions = new SslClientAuthenticationOptions()
{
// Use internal server cert validation
RemoteCertificateValidationCallback = serverCertValidator.ValidateCertificate,
CertificateRevocationCheckMode = X509RevocationMode.NoCheck,
ClientCertificates = clientCertificateLoader.ClientCertificates.Certificates,
LocalCertificateSelectionCallback = CertificateSelectionAdapter
},
};
options.Credentials = ChannelCredentials.SecureSsl;
// The only way to specify HTTP/3 is to do it on the HttpClient
var httpClient = new HttpClient(httpHandler);
httpClient.DefaultRequestVersion = HttpVersion.Version30;
httpClient.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact;
options.HttpClient = httpClient;
options.DisposeHttpClient = true;
}
What did you expect to see?
GRPC channel successfully connected
What did you see instead?
InvalidOperationException: Channel is configured with an HTTP transport doesn't support client-side load balancing or connectivity state tracking. The underlying HTTP transport must be a SocketsHttpHandler with no SocketsHttpHandler.ConnectCallback configured. The HTTP transport must be configured on the channel using GrpcChannelOptions.HttpHandler.
System.InvalidOperationException:
at Grpc.Net.Client.GrpcChannel.ValidateHttpHandlerSupportsConnectivity (Grpc.Net.Client, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad)
at Grpc.Net.Client.GrpcChannel..ctor (Grpc.Net.Client, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad)
at Grpc.Net.Client.GrpcChannel.ForAddress (Grpc.Net.Client, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad)
I can certainly skip the new HttpClient()
and set options.HttpHandler = httpHandler
, but then I don't have a way to specify HTTP/3. Thanks in advance for any suggestions.
Unfortunatly HTTP/3 and client-side load balancing can't be used together.
Thanks for the reply @JamesNK - is that a technological limitation (eg does it also affect other GRPC clients and servers), or a limitation on the .NET libs for now?
It's a limitation of SocketsHttpHandler.
Thanks - your prompt response was amazing, too.