3

I am attempting to transition away from WCF to move our codebase across to .NET Core. Our services are all hosted as Windows services at present so am trying to self-host the gRPC service as well (rather than building AspNetCore applications). I have successfully built a server using Grpc.Core.Server, and the client side as well with Grpc.Net.Client.GrpcChannel, see the code snippets below for reference.

Server:

  var builder = ServerServiceDefinition.CreateBuilder();
  // Binder is a small class ripped from the CodeFirst example
  var binder = new Binder();
  binder.Bind(builder, serviceType, service: serv);
  var serverServiceDefinition = builder.Build();

  var server = new Grpc.Core.Server
  {       
    Services = { serverServiceDefinition },
    Ports = { new ServerPort(host, port, ServerCredentials.Insecure) }
  };

  server.Start();

Client:

  var channel = GrpcChannel.ForAddress(Uri, new GrpcChannelOptions()
  {
    //HttpHandler = new GrpcWebHandler(new System.Net.Http.HttpClientHandler())
  });
  var service = channel.CreateGrpcService<TService>();

However because our applications are still running in .Net Framework 4.8 I get the runtime exception when testing out this code:

System.PlatformNotSupportedException : gRPC requires extra configuration on .NET implementations that don't support gRPC over HTTP/2. An HTTP provider must be specified using GrpcChannelOptions.HttpHandler.The configured HTTP provider must either support HTTP/2 or be configured to use gRPC-Web. See https://aka.ms/aspnet/grpc/netstandard for details.

That leads me to add in the Grpc.Net.Client.Web.GrpcWebHandler on the client side to switch over to Grpc-web as per the link in the error.

However, I am now struggling to do the equivalent for the server to support Grpc-web. The guide here suggests to either (1) use Grpc.AspNetCore.Web or (2) use "Envoy proxy" to get the server supporting it. The problem with (1) is that I'm not using AspNetCore so I don't think this solution is appropriate, and I can't find any lightweight/easy way to do (2) in a simple C# solution.

Without the server-side support added, I get this exception:

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.

Which I assume is obviously related to the fact the server isn't supporting the Grpc-web requests. So I am at a bit of a dead end with regards to this now. I feel I need to work out how to self-host AspNetCore servers and move to that instead of Grpc.Core.Server, which will open up option (1), but I am finding little to no evidence that is actually possible.

So I guess my main question is: Is there any way to support Grpc-web clients in a server hosted via Grpc.Core.Server?

And if the answer is no --> How can I self-host a GRPC server that will support Grpc-web clients?

mike
  • 3,146
  • 5
  • 32
  • 46
  • May I ask, why aren't you using https://github.com/grpc/grpc-dotnet instead of https://github.com/grpc/grpc ? – Rand Random Nov 04 '21 at 12:30
  • @RandRandom I wanted a code-first solution which led me to protobuf-net.Grpc, which is what I've based my solution off. We have an existing WCF code base using [DataContract] and [ServiceContract] interfaces/classes, so we are not interested in .proto files. I also want to self-host C# server & clients. It seems I'm limited in what is available that ticks these boxes? – mike Nov 04 '21 at 22:23

1 Answers1

0

As per this getting started guide I have discovered protobuf-net.Grpc.Native which appears to solve the problem I have at the moment. I also discovered I was missing a default constructor for my [DataContract], which I think was unrelated to the errors I was receiving but may have been contributing.

mike
  • 3,146
  • 5
  • 32
  • 46