Skip to content

Grpc.Net.Client >= 2.50.0 does not work on Android with grpc-web #2013

@cupsos

Description

@cupsos

Related: #1927
Might be related: dotnet/runtime#45741

Grpc.Net.Client v2.49.0 + GrpcWebHandler(new HttpClientHandler()) works but Grpc.Net.Client v2.50.0 doesn't.

I think my android device cannot use SocketsHttpHandler because await new HttpClient(new SocketsHttpHandler()).GetAsync("https://aka.ms") throws an exception.

What are options for android device that cannot use SocketsHttpHandler?

What I tried

Grpc.Net.Client GrpcChannelOptions.HttpHandler UseNativeHttpHandler Result
v2.49.0 GrpcWebHandler(new HttpClientHandler()) not set ✅ work
v2.49.0 GrpcWebHandler(new HttpClientHandler()) false SslException from gRPC call
v2.49.0 GrpcWebHandler(new SocketsHttpHandler()) not set SslException from gRPC call
v2.51.0 GrpcWebHandler(new HttpClientHandler()) not set InvalidOperationException from channel create
v2.51.0 GrpcWebHandler(new HttpClientHandler()) false SslException from gRPC call
v2.51.0 GrpcWebHandler(new SocketsHttpHandler()) not set SslException from gRPC call

Environment

  • SDK: 7.0.102
  • TFM: net7.0-android
  • UI: MAUI Blazor
  • OS: Android 7.1.2

Exception from GrpcChannel.ForAddress on Grpc.Net.Client >= 2.50.0

System.InvalidOperationException: The channel configuration isn't valid on Android devices. The channel is configured to use HttpClientHandler and Android's native HTTP/2 library. gRPC isn't fully supported by Android's native HTTP/2 library and it can cause runtime errors. To fix this problem, either configure the channel to use SocketsHttpHandler, or add <UseNativeHttpHandler>false</UseNativeHttpHandler> to the app's project file. For more information, see https://aka.ms/aspnet/grpc/android.
   at Grpc.Net.Client.GrpcChannel.CreateInternalHttpInvoker(HttpMessageHandler handler) in /_/src/Grpc.Net.Client/GrpcChannel.cs:line 402
   at Grpc.Net.Client.GrpcChannel..ctor(Uri address, GrpcChannelOptions channelOptions) in /_/src/Grpc.Net.Client/GrpcChannel.cs:line 155
   at Grpc.Net.Client.GrpcChannel.ForAddress(Uri address, GrpcChannelOptions channelOptions) in /_/src/Grpc.Net.Client/GrpcChannel.cs:line 607
   at Grpc.Net.Client.GrpcChannel.ForAddress(String address, GrpcChannelOptions channelOptions) in /_/src/Grpc.Net.Client/GrpcChannel.cs:line 570

Exception from gRPC call when using SocketsHttpHandler

Grpc.Core.RpcException: Status(StatusCode="Internal", Detail="Error starting gRPC call. HttpRequestException: The SSL connection could not be established, see inner exception. AuthenticationException: Authentication failed, see inner exception. SslException: Exception of type 'Interop+AndroidCrypto+SslException' was thrown.", DebugException="System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
 ---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
 ---> Interop+AndroidCrypto+SslException: Exception of type 'Interop+AndroidCrypto+SslException' was thrown.
   --- End of inner exception stack trace ---
   at System.Net.Security.SslStream.<ForceAuthenticationAsync>d__146`1[[System.Net.Security.AsyncReadWriteAdapter, System.Net.Security, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.AddHttp2ConnectionAsync(QueueItem queueItem)
   at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.<WaitWithCancellationAsync>d__1[[System.Net.Http.Http2Connection, System.Net.Http, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at System.Net.Http.HttpConnectionPool.HttpConnectionWaiter`1.<WaitForConnectionAsync>d__5[[System.Net.Http.Http2Connection, System.Net.Http, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(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) in /_/src/Grpc.Net.Client.Web/GrpcWebHandler.cs:line 166
   at Grpc.Net.Client.Balancer.Internal.BalancerHttpHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in /_/src/Grpc.Net.Client/Balancer/Internal/BalancerHttpHandler.cs:line 156
   at Grpc.Net.Client.Internal.GrpcCall`2.<RunCall>d__73.MoveNext() in /_/src/Grpc.Net.Client/Internal/GrpcCall.cs:line 493")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions