[gRPC] C# gRPC Server/Client 생성하기

목적

  • C# 으로 gRPC 통신을 구현합니다.
  • Server/Client 두 서비스 모두 C# 으로 작성합니다.
  • 그럼 C# 으로 간단한 gRPC 서비스를 만들어 보도록 하겠습니다.

개발 환경

  • 개발 환경은 다음과 같습니다.
    • OS : Windows 11
    • .NET Version : .NET 6
    • IDE : Visual Studio 2022

gRPC Server 구현

  • 그럼 먼저 gRPC C# Server 를 구현하는 방법에 대해서 알려 드리도록 하겠습니다.
  • Visual Studio 2022 를 실행한 후, ASP.NET Core gRPC 서비스 프로젝트를 생성합니다.
  • gRPC 서비스를 생성하게 되면, 기본으로 Protos 폴더가 생깁니다.
  • Default 로 greet.proto 라고 해서 프로토콜 버퍼가 생깁니다.
  • 저는 greet.proto 파일을 사용하지 않고, 직접 간단한 Customer 프로토콜 버퍼를 생성해 해당 파일로 gRPC 통신을 해보려고 합니다.


customers.proto 파일 생성

  • gRPC 서버/클라이언트 프로그램을 작성하기에 앞서, 예제로 사용하기 위한 customers.proto 파일을 작성합니다.
  • 서비스의 이름은 Customer 이고, 현재 원격 메서드로 GetCustomerInfo 메서드가 정의되어 있습니다.
  • 그럼 이제 해당 프로토콜 버퍼를 통해 통신하는 서버/클라이언트 프로그램을 만들어 보도록 하겠습니다.
syntax = "proto3";

option csharp_namespace = "gRPCTest.Protos";

service Customer{
   rpc GetCustomerInfo(CustomerLookupModel) returns (CustomerModel);
}

message CustomerLookupModel{
   int32 userId = 1;
}

message CustomerModel{
   string firstName = 1;
   string lastName = 2;
   string emailAddress = 3;
   bool isAlive = 4;
   int32 age = 5;
}

프로토콜 버퍼 제너레이터 하기

  • 서버/클라이언트 프로그램을 작성하기에 앞서, 앞에서 만들었던 customers.proto 파일을 컴파일 하여, C# 소스코드로 제너레이터 해야합니다.
  • 제너레이터 하는 방법은 customers.proto -> 마우스 우 클릭 하여 속성 페이지에 접근합니다.
  • 그리고 Build Action 은 Protobuf Compiler, gRPC Stub Classes 는 Server Only 로 설정하여 다시 재 빌드를 해주면 제너레이터가 된 것입니다.


CustomerService 작성

  • 다음으로 CustomerService 클래스를 생성한 후, 코드를 작성합니다.
  • 해당 코드에서는 Client 로부터 받은 메시지를 Server 에서 처리하는 로직이 들어있습니다.
  • 아래 예제에서는, Client 로부터 받은 UserID 값에 따라 다른 사람의 이름을 Server 가 반환해 주고 있습니다.
using Ecommerce;
using Grpc.Core;
using gRPCTest.Protos;

namespace gRPCTest.Services
{
    public class CustomerService : Customer.CustomerBase
    {
        private readonly ILogger<CustomerService> _logger;
        private List<Product> products = new();

        public CustomerService(ILogger<CustomerService> logger)
        {
            _logger = logger;
        }

        public override Task<CustomerModel> GetCustomerInfo(CustomerLookupModel request, ServerCallContext context)
        {
            CustomerModel output = new();

            if(request.UserId == 1)
            {
                output.FirstName = "Jamie";
                output.LastName = "Smith";
            }
            else if(request.UserId == 2)
            {
                output.FirstName = "Jane";
                output.LastName = "Doe";
            }
            else
            {
                output.FirstName = "Greg";
                output.LastName = "Thomas";
            }

            return Task.FromResult(output);
        }
    }
}

파이프라인 추가

  • 이제 마지막으로 Program.cs 에서 app.MapGrpcService<CustomerServices>(); 코드를 추가하여 CustomerServices 의 파이프라인을 추가합니다.
  • 이제 Server 쪽 준비는 모두 완료 되었습니다.
using gRPCTest.Services;

var builder = WebApplication.CreateBuilder(args);

// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682

// Add services to the container.
builder.Services.AddGrpc();

var app = builder.Build();

// Configure the HTTP request pipeline.
app.MapGrpcService<CustomerService>();
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");

app.Run();

gRPC client 콘솔 프로젝트 생성 및 proto 파일 추가

  • 앞서, gRPC Server 프로그램 로직을 모두 작성 완료 하였습니다.
  • 다음은 Client 프로그램을 만들 차례입니다.
  • 콘솔 프로젝트 하나를 생성한 후, 앞서 Server 에서 사용하였던 customer.proto 파일을 그대로 복사 붙여넣기 해 줍니다.
syntax = "proto3";

option csharp_namespace = "gRPCTest.Protos";

service Customer{
   rpc GetCustomerInfo(CustomerLookupModel) returns (CustomerModel);
}

message CustomerLookupModel{
   int32 userId = 1;
}

message CustomerModel{
   string firstName = 1;
   string lastName = 2;
   string emailAddress = 3;
   bool isAlive = 4;
   int32 age = 5;
}

NuGet Package 설치

  • Client 프로그램에서 gRPC 서비스를 사용하려면 총 3개의 gRPC 관련 NuGet Package를 설치해야 합니다.
    • Google.Protobuf
    • Grpc.Net.Client
    • Grpc.Tools
  • 위 3개의 NuGet Package를 미리 설치해 주시기 바랍니다.

client C# 프로젝트에서 GrpcService 속성 변경

  • 다음으로 생성했던 gRPCClient.csproj 파일에 가서 <Protobuf..> 로 시작하는 속성에서 GrpcService 속성을 Server -> Client 로 변경해 줍니다.


프로토콜 버퍼 제너레이터 하기

  • 서버와 마찬가지로, Client 에서 추가했던 customers.proto 파일을 C# 코드로 작성되게 끔 제너레이터 작업을 진행해야 합니다.
    • 제너레이터 하는 방법은 customers.proto -> 마우스 우 클릭 하여 속성 페이지에 접근합니다.
  • 그리고 Build Action 은 Protobuf Compiler, gRPC Stub Classes 는 Client Only 로 설정하여 다시 재 빌드를 해주면 제너레이터가 된 것입니다.


Client 통신 코드 작성

  • Program.cs 에 Server 에게 request 를 보내고, 다시 Server 가 반환한 객체를 출력하는 것까지 소스코드를 작성해 보도록 하겠습니다.
using Grpc.Net.Client;
using gRPCTest.Protos;

var channel = GrpcChannel.ForAddress("https://localhost:7223");
var customerClient = new Customer.CustomerClient(channel);

var clientRequested = new CustomerLookupModel { UserId = 3 };

var customer = await customerClient.GetCustomerInfoAsync(clientRequested);

Console.WriteLine($"{customer.FirstName} {customer.LastName}");

Console.ReadLine();

실행 방법

  • 실행 방법은 Server 가 우선 실행되어 있어야 합니다.
  • 그리고 나서, Client 프로그램을 실행하면 됩니다.


실행 결과

  • 실행 결과, Client 가 Server 로 전송하는 UserId 값에 따라 그에 맞는 User 이름이 반환되어 출력되는 것을 확인할 수 있습니다.
Greg Thomas
728x90

이 글을 공유하기

댓글

Designed by JB FACTORY