dev/asp.net, c#

[c# asp.net core 3.1] - gRPC 서버, 클라이언트 샘플 튜토리얼

코딩for 2020. 11. 6. 15:52
반응형

 

 

gRPC 

gRPC는 RPC(원격 프로시저 호출) 프레임워크로 구글의 프로토콜 버퍼를 이용한 RPC입니다.

(SOAP, JAVA RMI, MS-SQL 링크드서버 등)

 

MS 사이트에서 알려주는 gRPC의 장점은 다음과 같이 정의를 하고 있습니다.

gRPC의 주요 이점

  • 최신 고성능 경량 RPC 프레임워크.
  • 기본적으로 프로토콜 버퍼를 사용하는 계약 중심 API 개발로 언어에 구애받지 않는 구현이 가능합니다.
  • 여러 언어에서 강력한 형식의 서버 및 클라이언트를 생성할 수 있는 도구입니다.
  • 클라이언트, 서버 및 양방향 스트리밍 호출을 지원합니다.
  • Protobuf 이진 직렬화를 사용하여 네트워크 사용량이 감소합니다.

이러한 이점으로 인해 gRPC는 다음과 같은 분야에 이상적입니다.

  • 효율성이 중요한 경량 마이크로 서비스.
  • 개발을 위해 여러 언어가 필요한 다중 언어 시스템.
  • 스트리밍 요청 또는 응답을 처리해야 하는 지점 간 실시간 서비스.

gRPC에서는 데이터를 protobuf(프로토콜 버퍼)를 통해서 데이터를 직렬화 하여 주고받게 되는데, protobuf는 주고받을 데이터 타입과 함수들에 대해서 정의를 하게 됩니다. protobuf 파일은  *. proto 파일 확장자로 생성을 합니다.

 

 

 

이번 글에서는 asp.net core를 이용해서 gRPC 서비스  server와 client를 만드는 튜토리얼을 진행합니다.

 

준비사항

 

gRPC 서버 만들기

gRCP 서비스 프로젝트 템플릿을 만듭니다.

 

 

프로젝트 이름(GrpcServer)을 입력하고 프로젝트를 만들기로 생성하면 기본적으로 greet라는 이름의 gRPC 템플릿이 생성됩니다.

 

생성된 grpc 템플릿

//  greet.ptoto 파일 보기

syntax = "proto3";                             

option csharp_namespace = "GrpcServer";        

package greet;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply);
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings.
message HelloReply {
  string message = 1;
}

service에서 함수를 정의하고 message에 서버와 클라이언트 간에 주고받을 데이터 포맷을 정의합니다.

csharp_namespace에서 정의한 네임스페이스를 아래 서비스 구현부(GreeterService.cs)의 namespace와 매칭이 되어야 합니다.

// GreeterService.cs

namespace GrpcServer
{
    public class GreeterService : Greeter.GreeterBase
    {
        private readonly ILogger<GreeterService> _logger;
        public GreeterService(ILogger<GreeterService> logger)
        {
            _logger = logger;
        }

        public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
        {
            return Task.FromResult(new HelloReply
            {
                Message = "Hello " + request.Name
            });
        }
    }
}

 

생성된 GreeterService.cs  는 proto 파일에서 정의한 service와 message 가 생성된 것을 볼 수 있습니다.

생성이 완료된 프로젝트에 대해 빌드(F5)를 실행합니다.

 

오류가 발생을 하면, Program.cs 파일의 CreateHostBuilder에 아래 내용을 추가해 줍니다. 

오류 참고 macOS에서 ASP.NET Core gRPC 앱을 시작할 수 없음

https://docs.microsoft.com/ko-kr/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.1#unable-to-start-aspnet-core-grpc-app-on-macos

 

host관련 error 발생

// Program.cs

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    // Setup a HTTP/2 endpoint without TLS.
                    webBuilder.ConfigureKestrel(options =>
                    {
                        options.ListenLocalhost(5001, o => o.Protocols = HttpProtocols.Http2);
                    });

                    webBuilder.UseStartup<Startup>();
                });
        }

 

빌드 성공 후 localhost:5001 에서 수신 대기 중인 것을 확인할 수 있습니다.

 

 

gRPC 클라이언트 만들기

. NetCore 콘솔 앱, 웹 애플리케이션 등 필요한 프로젝트를 생성합니다.

여기서는 ASP.NET Core 웹 애플리케이션으로 생성하는 방법에 대해서 설명합니다.

 

 

프로젝트 이름(GrcpClient )을 입력 후 다음을 클릭합니다.

 

웹 응용프로그램(MVC) 프레임워크 애플리케이션으로 만들어 줍니다.

 

 

기본적인 MVC 프레임워크로 프로젝트가 생성됩니다.

 

 

gRPC에 필요한 필수 패키지를 설치해 줍니다.

  #설치방법 1   

  도구 > Nuget 패키지 관리자 > 패키지 관리자 콘솔을 이용해서 패키지를 설치합니다.

PM> Install-Package Grpc.Net.Client
PM> Install-Package Google.Protobuf
PM> Install-Package Grpc.Tools

 

패키지관리지 콘솔을 이용한 패키지추가

 

#설치방법 2   

도구 > nuget 패키지관리자 > 솔루션용 패키지 관리 를 통해 검색 후 추가하실 수 있습니다.

 

 

서버 프로젝트에서 생성한 greet.proto 파일을 클라이언트 프로젝트에 복사해서 추가해줍니다.

클라이언트 프로젝트 파일(GrpcClient.csproj)을 열고 protobuf 파일 관련 항목을 추가합니다.

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

 

 

gRpc client 통신 하기

.proto 파일의 네임스페이스를 클라이언트 프로젝트의 네임스페이스로 변경합니다.

 

 

gRPC 통신 전(grpc 액션 메서드)에 코드를 추가합니다.

 * NET Core 클라이언트를 사용하여 안전하지 않은 gRPC 서비스 호출 에러 발생 해결

   https://docs.microsoft.com/ko-kr/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.1

AppContext.SetSwitch(
    "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
// HomeController.cs 
// grpc 액션을 추가 한 후 통신 코드 작성

        public IActionResult grpc()
        {
            AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
        
            // The port number(5001) must match the port of the gRPC server.
            using var channel = GrpcChannel.ForAddress("http://localhost:5001");
            var client = new Greeter.GreeterClient(channel);
            var reply = client.SayHello(
                              new HelloRequest { Name = "client hello" });
            return View(reply);
        }
 // gRPC View 페이지
 // 모델을 전달 받아 보여준다.
 
@model GrcpClient.Controllers.HelloReply
@{
    ViewData["Title"] = "gRPC";
}

<div class="text-center">  
    <h1>
        @Model.Message
    </h1>
</div>

 

gRPC 서버, 클라이언트 테스트

 

gRPC 서버 시작합니다.

 

gRpc 클라이언트 실행( https://localhost:44395/home/grpc  ) 하여 통신 확인합니다.

*호출하는 포트는 설정에 따라 다름

 

클라이언트에서 Name에 전달을 하면 서버는 요청에 따라 응답을 줍니다.

 

 

 

이전의 WCF 라는 MS 웹 플랫폼에서 gRPC 의 공용 플랫폼으로의 진화라고 해야 할까, gRPC는 시스템 에서 중요한 proto 파일의 공용 관리 배포가 유기적으로 되어야 할 거 같다는 생각입니다.  현재는 HTTP 통신의 확장과 유연함으로 REST 서비스를 많이 사용을 하지만 앞으로는 또 어떤 플랫폼과 프레임워크가 트렌가 될지는 모르겠습니다.

 

 

github

https://github.com/Chris-You/CSharpSampleTest/tree/master/gRPC

 

 

참고

https://grpc.io/

https://docs.microsoft.com/ko-kr/aspnet/core/grpc/?view=aspnetcore-3.1

https://docs.microsoft.com/ko-kr/aspnet/core/tutorials/grpc/grpc-start?view=aspnetcore-3.1&tabs=visual-studio

https://namu.wiki/w/RPC

https://blog.naver.com/alice_k106/221617347519

 

반응형