CSharp gRPC Client Tutorial with gRPC.NET

Introduction

This tutorial guides you through creating a C# gRPC client using .NET Core with gRPC.NET. The tutorial assumes you are familiar with C# and have a basic understanding of gRPC.

Prerequisites

Ensure you have dotnet core installed on your machine.

Bootstrapping the Project

  1. Open a command line and navigate to an empty folder.
  2. Create a new C# console app: dotnet new console --language C#

Downloading the .proto File

Download the AmazeingEvening.proto file from /static/AmazeingEvening.proto and place it in the project folder.

Automatic Code Generation

In order to auto-gen the client to our gRPC server, you need to install a couple of packages: Grpc.Tools, Grpc.Net.Client and Google.Protobuf.

You can install these packages either via the Visual Studio package manager, or you can run the following commands in the command line:

dotnet add package Grpc.Net.Client
dotnet add package Grpc.Tools
dotnet add package Google.Protobuf

Once you add these references to your project, you now need to indicate to your csproj that the AmazeingEvening.proto file is actually a special file, by adding a <Protobuf> entry directly in your .csproj file.

Your .csproj should contain the following snippet:

  <ItemGroup>
    <Protobuf Include="AmazeingEvening.proto" GrpcServices="Client" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Google.Protobuf" Version="3.25.1" />
    <PackageReference Include="Grpc.Net.Client" Version="2.59.0" />
    <PackageReference Include="Grpc.Tools" Version="2.60.0">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
  </ItemGroup>

If you try to build and run your application now, you should get a successful build and the Hello World! from the code that dotnet new has created.

Registering on the Amazeing server

Now that gRPC tools have done the automatic code generation for us, we can create the simplest program that communicates with our server.

You may now either replace your Program.cs with these contents, or take inspiration from them:

using AmazeingEvening;
using Grpc.Core;
using System;

namespace gRPCGuide
{
    class Program
    {
        static void Main(string[] args)
        {
            /// Create credentials with the apiKey you received.
            var credentials = CallCredentials.FromInterceptor((context, metadata) =>
            {
                metadata.Add("Authorization", "<<YOUR API KEY>>");
                return Task.CompletedTask;
            });

            /// Create a GRPC Channel and attach the credentials which should be added on each request.
            var channel = GrpcChannel.ForAddress(<<THE SERVER ADDRESS>>, new GrpcChannelOptions()
            {
                Credentials = ChannelCredentials.Create(new SslCredentials(), credentials),
            });
            
            /// Create the clients
            var mazesClient = new Mazes.MazesClient(channel);
            var mazeClient = new Maze.MazeClient(channel);
            var playerClient = new Player.PlayerClient(channel);

            /// Register ourselves
            var ourName = $"gRPC guide ({Guid.NewGuid().ToString().Substring(0, 5)})";
            var registerResult = playerClient.Register(new RegisterRequest { Name = username });
            Console.WriteLine($"Registration result: [{registerResult.Result}]");

            /// List all the available mazes
            var availableMazesResult = mazesClient.GetAllAvailableMazes(new GetAllAvailableMazesRequest());
            foreach (var maze in availableMazesResult.AvailableMazes)
                Console.WriteLine($"Maze [{maze.Name}] | Total tiles: [{maze.TotalTiles}] | Potential reward: [{maze.PotentialReward}]");
        }
    }
}

Remember to replace the two placeholders with the information provided to you during the event.

If everything goes amazingly well, you should see the following output in your console:

Registration result: [Success]
Maze [Example maze] | Total tiles: [17] | Potential reward: [160]
Maze [Hello maze] | Total tiles: [8] | Potential reward: [110]

The maze navigation is part of the challenge of this evening. The swagger API and the gRPC API are very similar, so you can study the documentation provided by swagger to know what to expect from the server for each request.

And remember: Have fun! 👍🏻


This example was written and tested on [2024-01-02], and it “worked on my machine”. Hopefully it will work on yours as well 😅.