Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
cupsos opened this issue Jan 11, 2023 · 3 comments · Fixed by #2020
Closed

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

cupsos opened this issue Jan 11, 2023 · 3 comments · Fixed by #2020

Comments

@cupsos
Copy link

cupsos commented Jan 11, 2023

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")
@cupsos
Copy link
Author

cupsos commented Jan 13, 2023

I don't know why I didn't open it as bug or request template...
Close this, I will make a new issue again.

@cupsos cupsos closed this as completed Jan 13, 2023
@cupsos
Copy link
Author

cupsos commented Jan 13, 2023

I just figure out how to avoid this.

If you cannot use SocketsHttpHandler, try GrpcChannelOptions.HttpClient not GrpcChannelOptions.HttpHandler.

GrpcChannel.ForAddress(setting.Address, new GrpcChannelOptions
{
    // HttpHandler = new GrpcWebHandler(new HttpClientHandler()), // this will throw exception
    HttpClient = new HttpClient(new GrpcWebHandler(new HttpClientHandler())),
});

@JamesNK
Copy link
Member

JamesNK commented Jan 16, 2023

Fix this in GrpcChannel: #2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants