gRPC with .NET : Boilerplate server and client

Satyam Pushkar
6 min readJun 10, 2021

--

gRPC is a modern, lightweight communication protocol from Google. It is an open source remote procedure call (RPC) framework that can run anywhere. It enables client and server applications to communicate transparently, and makes it easier to build connected systems. In gRPC, a client application can directly call a method on a server application on a different machine as if it were a local object, making it easier for you to create distributed applications and services.

In this article we will talk about how to create a gRPC based server and client in .NET. To know in detail about what is gRPC, why and when to use gRPC, Please check this article. In this article focus will be more on how to create and run a basic gRPC server and client code and what happens behind the hood. So let’s start. Open your visual studio and create a new project. Select ‘ASP.NET Core gRPC Service’ template to create a new project.

Select ‘ASP.NET Core gRPC Service’ template

Upon creation your project structure will look something like this.

By default template adds a reference to ‘Grpc.AspNetCore’ package. It’s a gRPC meta-package for ASP.NET Core. It has three main packages included in it.

  • Google.Protobuf: C# runtime library for Protocol Buffers -Google’s data interchange format. This adds google’s protocol buffer feature in .net environment.
  • Grpc.AspNetCore.Server.ClientFactory: HttpClientFactory integration for the gRPC .NET client when running in ASP.NET Core. This enables the .net based gRPC service/server to be called by gRPC client.
  • Grpc.Tools: gRPC and Protocol Buffer compiler for managed C# and native C++ projects. It contains precompiled version of protoc.exe and a copy of well known .proto files under the package’s tools directory. It generates the boilerplate code from ‘.proto’ file defined in the project.

You will also see a folder called ‘Protos’. By default it will have a sample ‘greet.proto’ file. This file is added in your ‘.csproj’ file(see below image). Here GrpcServices can have 3 values: Server, Client or Both and based on that it will generate respective stub.

<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>

Let’s understand this ‘greet.proto’ protobuf file :

  • syntax: proto3 is the syntax version of proto file. If you don’t specify this then by default it will consider proto2 as syntax version.
  • csharp_namespace: It is an optional line. When code will be generated by proto3 compiler, then all classes will be created under this namespace.
  • package: If csharp_namespace is not specified, generated classes will be placed in a namespace matching the package name
  • message: defines the structure for the data for Remote Procedure Call.
  • service: are nothing but Remote Procedure Call method definitions which consists of method’s name, parameter and return type.

Now if you check your ‘obj\Debug\net5.0\Protos’ under your project folder, you will find two automatically generated files: ‘Greet.cs’ and ‘GreetGrpc.cs’. Here you can see the auto-generated code which has implementation for all the service and RPC method defined in our ‘.proto’ file. You can go through it to get the gist of what is happening under the hood.

Now check the actual implement the service. In the demo project created from template, be default one ‘Services’ folder will be created. Here you can add the actual service implementation. By default ‘GreeterService.cswill be there. You can observe the following under ‘GreeterService’ class:

  • gRPC.Service.Demo namespace: This is the csharp_namespace which was defined in ‘greet.proto’ file. You can create your own namespace but in that case remember to add it’s reference as it will have all C# implementation for our messages and services defined in ‘greet.proto’.
  • Greeter.GreeterBase: This is a partial abstract class in auto generated ‘GreetGrpc.cs’ which has C# implementation of our Greeter service written in ‘greet.proto’. It has a virtual method ‘SayHello’ which takes ‘HelloRequest’ as input parameter and returns ‘HelloReply’ as response. In our service this is the method which is overridden to provide the actual implementation.

Now have a look at StartUp.cs. Two things to notice here:

  • services.AddGrpc() in ConfigureServices method is to enable gRPC.
  • endpoints.MapGrpcService<GreeterService>() in Configure method is to add each gRPC service to routing pipeline. In this case for our GreeterService service.

Now you are all set to run your first gRPC server app in dotnet.

Create a gRPC client

Now your gRPC server is up and running. To test this you will need a client and to create a client you will need to create a console application and add three packages to it:

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

First two are same which is added in server application earlier. The last one is .NET client for gRPC. So create a console application and add these 3 packages to it.

Now add a new folder under project and name it as ‘Protos’. Copy the ‘greet.proto’ file from the earlier service and add it to ‘Protos’ folder.

Your project structure should look something like this.

Add this piece in your ‘.csproj’ file.

<ItemGroup><Protobuf Include=”Protos\greet.proto” GrpcServices=”Client” /></ItemGroup>

This will generate the ‘Greet.cs’ and ‘GreetGrpc.cs’ similar to our earlier project (gRPC server). But this time it will have auto generated implementation for client side. You can check this in your project folder under ‘obj\Debug\net5.0\Protos’.

Now copy the below code and paste in Program.cs :

using System;
using System.Threading.Tasks;
using Grpc.Net.Client;
using gRPC.Service.Demo;
namespace gRPC.Client.Demo
{
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Calling gRPC server....");
var channel = GrpcChannel.ForAddress("<your_gRPC_Server_end_point>");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(new HelloRequest { Name = "DemoClient" });
Console.WriteLine($"Response from server: {reply.Message}");
Console.ReadLine();
}
}
}

Please have a look at this closely and you will find that

  • Grpc.Net.Client and gRPC.Service.Demo reference is used. The first one adds client related functionalities and the second one is for calling the service which you have created earlier
  • First you are creating a channel to talk to the server(which we have created earlier) by using GrpcChannel.ForAddress(“<your_gRPC_Server_end_point>”).
  • Then using this channel, Greeter.GreeterClient’s instance is created which has client stub for calling your remote procedures(s). This created client will have all RPC method’s name, input and output information.
  • Finally you have the client and using this you are calling SayHelloAsync method by passing HelloRequest input. The response will be of HelloReply type which has the value Message.

Now your client is also ready. Press ctrl+F5 to run the server application first. It will open a console similar to shown in left side of below image. Copy the server endpoint and paste it in ‘Program.cs’ to replace <your_gRPC_Server_end_point>. Now run the client by pressing ctrl+F5. It will also open a console. You will get an output similar to right side of below image. You can see that client has send ‘DemoClient’ as input and server processed it by prepending ‘Hello to it. You can check the logs in server’s console. It is processing requests over HTTP/2.

Server and Client demo

This is a very basic dotnet based gRPC server and client code-first demo.

For more in-depth knowledge, Please check these other articles about gRPC by me:

--

--

Satyam Pushkar
Satyam Pushkar

Written by Satyam Pushkar

Software Engineer | Backend Specialist | System Architect | Cloud Native Apps | DOTNET, PYTHON | https://www.linkedin.com/in/satyampushkar/

No responses yet