Connect C# GRPC client to Go Server
Asked Answered
P

1

7

I'm attempting to connect to a Go GRPC Server from a C# Client but the client channel is failing to connect to the server.

I would expect that there should be no issues in connecting to a GRPC server that is written and hosted by Go and a client written in C#.


My Go Server connection is setup thus:

lis, err := net.Listen("tcp", ":50051")
if err != nil {
    log.Fatalf("Failed to listen: %v", err)
}

s := grpc.NewServer()

pb.Register**ServiceServer(s, &server{})
reflection.Register(s)
if err := s.Serve(lis); err != nil {
    log.Fatalf("Failed to serve: %v", err)
}

This is fairly standard and I know that my Server is working as I am able to connect with a Go client using the supplied port:

conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure(), grpc.WithBlock())

But when I attempt to connect using a C# Client using the Grpc.Net.Client package as thus:

var channel = GrpcChannel.ForAddress(@"http://localhost:50051", new GrpcChannelOptions
{
   Credentials = ChannelCredentials.Insecure
});

I get a Grpc.Core.RpcException: 'Status(StatusCode=Internal, Detail="Bad gRPC response. Response protocol downgraded to HTTP/1.1.")' exception.

Or by using the Grpc.Core package as thus:

var channel = new Channel("localhost:50051", ChannelCredentials.Insecure);

results in a Grpc.Core.RpcException: 'Status(StatusCode=Unavailable, Detail="failed to connect to all addresses")' exception.

I've tried both methods with and without Http2UnencryptedSupport set within the C# client but I've run out of ideas on why I am unable to connect.

Any suggestions on where I am going wrong would be appreciated.

Predestinate answered 4/6, 2020 at 14:34 Comment(5)
Have you already tried combining the Http2UnencryptedSupport thing with setting the Net.Client manually on ForAddress? Net.Client.DefaultRequestVersion is HTTP1.1 by default. Maybe also try setting Net.Client.DefaultVersionPolicy to HttpVersionPolicy.RequestVersionExact.Carrico
Thanks @TylerKropp pushing me to look at this again. If I try using the latest Grpc NuGet packages (v2.34.0 at the moment) and setting both AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", true); and AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); I am able to send a recieve message from the golang server. I'm not sure what has changed since v2.29 and v2.34 but one of the changes in here has resolved this for me.Predestinate
OK, yeah the documentation did mention fixing it at a certain version: "must use Grpc.Net.Client version 2.32.0 or later". I guess it really was Microsoft's fault. learn.microsoft.com/en-us/aspnet/core/grpc/…Carrico
Why are you using HTTP instead of HTTPS? gRPC uses HTTP/2 which in turn requires HTTPS.Temikatemp
@PanagiotisKanavos since I was using an unsecure channel for this test I therefore have to use a 'http' channel instead of 'https'. HTTP/2 support is still enabled via the AppContext.SetSwitch but with unencrypted support enabled for use without credentials (not recommended for a production environment).Predestinate
C
2

For .NET 3.x, set:

AppContext.SetSwitch(
    "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

and use http for the protocol in the URL.

For .NET 5.0, use version Grpc.Net.Client version 2.32.0 or later.

Source: https://learn.microsoft.com/en-us/aspnet/core/grpc/troubleshoot?view=aspnetcore-5.0#call-insecure-grpc-services-with-net-core-client

Carrico answered 12/1, 2021 at 18:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.