0

I am trying to set up a grpc-net client on a .net standard 2.0 project that is connected via an insecure channel to a grpc server running google's implementation.

The server side is running on a .NET 6.0 console app with google's grpc implementation:

var server = new Grpc.Core.Server()
{
   Ports = { new ServerPort("localhost", 0, ServerCredentials.Insecure) },
   Services = { Greeter.BindService(new GreeterServer()) }
};
server.Start();

The client side is running as a .net 4.7.2 console app (with the server port as input):

var channel = GrpcChannel.ForAddress("http://localhost:" + port, new GrpcChannelOptions
{
   HttpHandler = new GrpcWebHandler(new HttpClientHandler()),
   Credentials = ChannelCredentials.Insecure
});

var client = new Greeter.GreeterClient(channel);

The following exception is thrown on the client Channel creation:

Grpc.Core.RpcException: 'Status(StatusCode="Internal", Detail="Error starting gRPC call. HttpRequestException: An error occurred while sending the request. WebException: The server committed a protocol violation. Section=ResponseStatusLine", DebugException="System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The server committed a protocol violation. Section=ResponseStatusLine
at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context) at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar) --- End of inner exception stack trace --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Grpc.Net.Client.Web.GrpcWebHandler.d__18.MoveNext() in //src/Grpc.Net.Client.Web/GrpcWebHandler.cs:line 166 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Grpc.Net.Client.Internal.GrpcCall`2.d__73.MoveNext() in /
/src/Grpc.Net.Client/Internal/GrpcCall.cs:line 493")'

Robabeh Ghasemi
  • 422
  • 1
  • 3
  • 11
MisterT
  • 1
  • 2
  • See folloiwng : https://github.com/grpc/grpc-dotnet/issues/1552 – jdweng Aug 13 '22 at 19:13
  • @jdweng thanks for the link. According to their answer, the problem is that client is trying to use http 1.1 while the server is using http2. In my case, the server is google's implementation which AFAIK doesn't support http 1.1 at all. Does it mean that grpc-net client will not be able to connect to google's grpc server? (assuming I cannot use the latest windows version and setup WinHttpHandler) – MisterT Aug 13 '22 at 19:30
  • What port number are you using? HTTPS usually uses 443. So it is the combination of HTTP/HTTPS and port number if issue is same as the link. The server determines the minimum requirements. So it also depends on the Server. If server requires http2 than you must use http2. It server requires TLS that you must use TLS (HTTPS not HTTP). And if you are using TLS probably you need to use 1.2 or 1.3. Net 4.7.2 defaults to TLS in operating system (not Net) so if you can reach site using a browser you probably can also do same inside c#. – jdweng Aug 13 '22 at 23:55
  • It's an unsecured channel. the server is a console app – MisterT Aug 14 '22 at 06:20
  • You may need to use TLS. Try HTTPS instead of HTTP at client. Server machine may require HTTPS and you have no option to change the server. – jdweng Aug 14 '22 at 07:17
  • I am running the server, it does not require any credentials. – MisterT Aug 14 '22 at 10:11
  • TLS is not credentials. It is encryption. If server requires TLS than you must use TLS. The server has a firewall and your connection must be able to get through the firewall. You do not have any way of bypassing the firewall. – jdweng Aug 14 '22 at 10:36
  • There is no encryption, the example is running both client and server on the same machine with localhost – MisterT Aug 14 '22 at 11:32
  • You are not listening. The code is making a HTTP connection. There is a firewall that handles all HTTP connection whether the connection is virtual or remote. If the firewall requires HTTPS than you must use HTTPs. HTTPS uses TLS and establishes a encryption method to encrypt all data. The firewall recognizes the connection is HTTP. – jdweng Aug 14 '22 at 13:54
  • thanks again for your effort @jdweng. There is no firewall blocking the call, I've verified it. In addition, I was able to connect when both client and server were running google's implementation using an insecure channel so your suggestion about a firewall blocking non-HTTPS calls doesn't seem to fit. – MisterT Aug 14 '22 at 14:44
  • Hi.... have you found a solution for this? – user2896152 Nov 15 '22 at 18:47
  • Sorry to say, but I could not find a solution, perhaps its an implementation limitation. – MisterT Nov 19 '22 at 14:40

1 Answers1

1

This error happened exactly by the reason described here (use http 1.1 while the server is using http2) as for your question in comments - Yes - it means that grpc-net client will not be able to connect to google's grpc server in the way you use it. I faced with a little bit more complex case when I was needed to connect to grpc server that work through HTTP 0.9, and it was the same exception. I found the way to do it. There is an implementation that use native gRPC Core library and the C# implementation. Here you will get ability to create channel. For your case, it will look like:

    var channel = new Grpc.Core.Channel("localhost", port, ChannelCredentials.Insecure);
    var client = new Greeter.GreeterClient(channel);

Be mind because it is on maintenance mode. Here you can read about it.

Alexandr
  • 163
  • 7