ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • F# 에서 Grpc 사용하기
    F# 2020. 2. 10. 22:34

     

    F#에서 GRPC를 사용하는 방법에 대해서 알아보자.

    (IDE에서 다음 작업을 진행하는 경우 더 편리하게 진행가능하다.)

    1. 테스트용 솔루션 생성

    // dotnet grpc tool 을 전역으로 설치
    $dotnet tool install -g dotnet-grpc
    
    // 솔루션 생성  
    $ dotnet new sln -o GrpcTest 
    
    // 솔루션 디렉토리 진입  
    $ cd ./GrpcTest

     

    2. F# Server 프로젝트 생성

    // 서버 콘솔 프로젝트 생성 
    $ dotnet new console -lang f# -o Server  
    
    // 솔루션에 추가  
    $ dotnet sln add ./Server/Server.fsproj

     

    3. F# Client 프로젝트 생성

    // F# 클라이언트 프로젝트 생성 
    $ dotnet new console -lang f# -o Client 
    
    // 솔루션에 추가 
    $ dotnet sln add ./Client/Client.fsproj

     

    4. C# GRPC 라이브러리 프로젝트 생성

    // GRPC 라이브러리 프로젝트 생성(C#) 
    $ dotnet new classlib -lang c# -o Protocol 
    
    // 솔루션에 GRPC 프로젝트 추가 
    $ dotnet sln add ./Protocol/Protocol.csproj

     

    여기까지 정상적으로 진행했다면, 디렉토리 구조는 다음과 같아야 한다.

    /GrpcTest 
        / Server 
        / Client 
        / Protocol

     

    [GrpcTest/] Server, Client, Protocol 프로젝트에 기본 패키지/레퍼런스 추가

    // 솔루션 GrpcTest project root directory로 이동한다. 
    
    // 프로토콜 프로젝트에 패키지 설치 및 참조 추가 
    $ cd ./Protocol 
    $ dotnet add package Google.Protobuf 
    $ dotnet add package Grpc 
    $ dotnet add package Grpc.Tools
    
    
    // 서버 프로젝트에 프로토콜 패키지 설치 및 참조 추가 
    $ cd ./Server 
    $ dotnet add package Google.Protobuf
    $ dotnet add package Grpc.Core 
    $ dotnet add reference ../Protocol/Protocol.csproj 
    $ cd .. 
    
    // 클라이언트 프로젝트에 패키지 설치 및 참조 추가 
    $ cd ./Client 
    $ dotnet add package Google.Protobuf
    $ dotnet add package Grpc.Core 
    $ dotnet add reference ../Protocol/Protocol.csproj 
    $ cd ..

     - 프로젝트마다 각각 설정이 조금씩 다르다.

    - Grpc.Tools를 패키지를 설치하지 않으면 Service 코드가 생성되지 않으므로 주의.

     

    [Protocol] 프로토콜 정의 및 IDL 컴파일

    // 프로토콜 프로젝트 디렉토리로 진입 
    [GrpcTest]$ cd Protocol 
    
    // 여기에 프로토콜이 정의된 IDL 파일인 *.proto 파일들을 넣는다. 
    [GrpcTest/Protocol]$ mkdir Proto 
    
    // 하단 HelloWorld.proto 작성 및 저장
    [GrpcTest/Protocol]$ vi HelloWorld.proto  
    
    // protoc를 사용하지 않고 프로젝트에 바로 등록하여 컴파일 할 수 있다. 
    [GrpcTest/Protocol] $ vi ./Protocol.csproj 
                    : (중략) 
    // 다음 내용 추가 및 저장
    
    <ItemGroup>
    
        <Protobuf Include="./Proto/HelloWorld.proto" />
    
    </ItemGroup>  
      
    // 클래스라이브러리 빌드 
    [GrpcTest/Protocol] $ dotnet build

    [Grpc/Protocol/Proto/HelloWorld.proto] 작성

    syntax = "proto3";
    package google.protobuf;
    
    service HelloService {
    	rpc SayHello(HelloReq) returns (HelloRes);
    }
    
    message HelloReq {
    	string greeting = 1;
    }
    
    message HelloRes {
    	string reply = 1;
    }

     

     

    [GrpcTest/Server] Grpc 요청 처리기 제작 

    [GrpcTest/Server/Program.fs 작성]

    open System
    open System.Threading.Tasks
    open Grpc.Core
    open HelloWorld
    
    
    type HelloServiceImpl() =
        inherit HelloService.HelloServiceBase()
        
        override this.SayHello(request : HelloReq, context :ServerCallContext) : Task<HelloRes> =
            HelloRes(Reply = request.Greeting+" 안녕?") |> Task.FromResult
    
    
    
    [<EntryPoint>]
    let main argv =
        let port = 5000
        let server = Server()
        server.Services.Add(HelloService.BindService(new HelloServiceImpl()))
        server.Ports.Add(ServerPort("127.0.0.1", port, ServerCredentials.Insecure)) |> ignore
        server.Start()
        
        Console.WriteLine("Press any key to stop the server ...")
        Console.ReadKey() |> ignore
        
        server.ShutdownAsync().Wait()
        0 // return an integer exit code
    

     

    [GrpcTest/Client] Grpc 요청 제작

    [GrpcTest/Client/Program.fs] 작성

    open System
    open HelloWorld
    open Grpc.Core
    
    
    type HelloServiceImpl(client : HelloService.HelloServiceClient) =
            member this.SayHello(greeting : string) =
                let request = new HelloReq(Greeting = greeting)
                client.SayHello(request)
    
    
    [<EntryPoint>]
    let main argv =
        let channel = new Channel("127.0.0.1:5000", ChannelCredentials.Insecure)
        let client = new HelloServiceImpl(new HelloService.HelloServiceClient(channel))
        
        let result = client.SayHello("Hi~")
        Console.WriteLine(result.Reply)
        0 // return an integer exit code
    

     

    실행

    // 서버를 가동한다 (키를 대기하게 된다.) 
    [GrpcTest]$ cd Server 
    [GrpcTest/Server]$ dotnet run 
    Press any key to stop the server ... 
    
    // 새 Console에서 실행 
    [GrpcTest]$ cd Client 
    [GrpcTest/Client]$ dotnet run  
    Hi~ 안녕? 
    
    //위와 같이 메시지가 뜨면 통신 성공

     

    GitHub Code

    전체 프로젝트와 코드는 다음 저장소에서 확인 할 수 있다.

    https://github.com/freebsdk/fsharp_grpc

     

     

Designed by Tistory.