.NET, C#, CSharp

gRPC in .NET Core

As WCF is going to end of life with .NET 5.0 (more here), gRPC is going to replace it (as recommended alternative). So what’s that? It is bi-directional, HTTP/2 based protocol. It can be used to communicate server-server o client-server including scenarios like load-balancing, health checks, microservices communication.

gRPC stands for Google RPC (Remote Procedure Call). The idea behind it is pretty old (1981 – Wikipedia), however gRPC was created in 2015 and supports multiple platforms (libraries for 10 languages are available).

Why should we consider gRPC? Because it’s modern technology, with contract first approach, available for multiple languages, bi-directional stream support and low network usage (thanks to binary serialization).

As a part of basic concept, gRPC is using Google’s ProtoBuffer (.proto file) which contains services’ definitions and messages.

For the demo purpose, I use Visual Studio for Mac. I created project as gRPC service and named it grpcService. I updated also immediatly nuget packages to the latest version (as usually templates are a bit outdated). There is one change which has to be done to run the solution on localhost (otherwise you will get errors on startup):

webBuilder.ConfigureKestrel(options => options.ListenLocalhost(5002, 
o => o.Protocols = HttpProtocols.Http2));

Let’s take a look into .proto file.

syntax = "proto3";

option csharp_namespace = "grpcService";

package greet;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply);

message HelloRequest {
  string name = 1;

message HelloReply {
  string message = 1;

In the first line, syntax (with version) is specified. Current one is proto3. Next item, option csharp_namespace, indicates the C# namespace (default is project’s namespace). A package value usually derives from the base namespace part however in this example, it’s independent value. Next line describe service and available actions including parameters and returned types (messages types). For more details, please follow Google’s documentation here.

Let’s consider, which types are available in message:

proto typeC# type
other message typeclass

Then I run second instance of Visual Studio and created console client with name grpcClient. First step is to import .proto file – I added it as a link to file but it requires small edit in .csproj.

    <Protobuf Include="..\grpc\grpcService\Protos\greet.proto" GrpcServices="Client">

As next step, I installed following packages:

  • Grpc.Tools
  • Google.Protobuf
  • Grpc.Net.Client

After that, you can run build and in obj folder, you will find generated service and messages. Now we can can start coding. As you will note, on gRPC client, 2 types of methods are generated – sync and async. As I used http endpoint, I had to set additional flag:

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

Support for unecrypted gRPC will be introduced in .NET 5 (github issue description).

Sample client:

static async Task Main(string[] args)
    AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
    using var channel = GrpcChannel.ForAddress("http://localhost:5002");
    var client = new Greeter.GreeterClient(channel);
    var reply = await client.SayHelloAsync(new HelloRequest { Name = "test" });


As gRPC is designed mainly to server-server communication, the need to transfer data browser-server appeared. On the browser level, the control over the requests is unsufficient. Moreover we cannot force browser to use HTTP/2 therefore gRPC-Web supports both HTTP/1.1 and HTTP/2 however a mandatory part of implementation is a proxy translating requests between gRPC-Web and gRPC. For more details, follow gRPC site.

Leave a Reply

Your email address will not be published. Required fields are marked *