All Articles

gRPC

gRPC는 모든 환경에서 실행할 수 있는 고성능 RPC 프레임워크이다.

HTTP/2를 이용해 데이터를 주고 받으며, protocol buffer를 이용해 인터페이스를 정의한다.

인터페이스 정의

먼저 protobuf를 이용해 주고 받을 메시지의 인터페이스를 정의한다.

// chat.proto
syntax = "proto3"; // protobuf 버전
option go_package = "/chat"; // 패키지

// 주고 받을 메시지 형태
message Message {
  string name = 1;
  string body = 2;
}

// 서비스 인터페이스 정의
service ChatService {
  rpc SayHello(Message) returns (Message) {}
}

서버/클라이언트는 메시지 전송자의 이름과 전송 내용을 포함하는 메시지를 주고 받도록 인터페이스를 정의한다

# .proto 파일 빌드
protoc -I=. --go_out=. --go-grpc_out=. ./chat.proto

빌드를 완료하면 ./chat/chat.pb.go에 인터페이스가 빌드되어 생성 된 것을 확인할 수 있다.

gRPC 서버 개발

gRPC 인터페이스를 이용한 서버 코드 작성

서버는 클라이언트로 부터 Message를 전달 받고 Message를 응답한다.

// server.go
package main

import (
 "fmt"
 "golang.org/x/net/context"
 "log"
 "net"

 "github.com/violetstair/go-grpc/chat"
 "google.golang.org/grpc"
)

type server struct {
 chat.UnimplementedChatServiceServer
}

func (s *server) SayHello(context context.Context, msg *chat.Message) (*chat.Message, error) {
 log.Printf("%s로 부터 수신된 메시지: %s", msg.GetName(), msg.GetBody())

 return &chat.Message{Name: "Server", Body: "Hello"}, nil
}

func main() {
 fmt.Println("서버 시작 ... ")

 // 포트 오픈
 listen, err := net.Listen("tcp", ":9080")
 if err != nil {
  log.Fatalf("포트 오픈 실패 : %v", err)
 }

 // grpc 서버 생성
 grpcServer := grpc.NewServer()

 chat.RegisterChatServiceServer(grpcServer, &server{})

 if err = grpcServer.Serve(listen); err != nil {
  log.Fatalf("서버 실행 실패 : %v", err)
 }
}

서버 실행

go run server.go

gRPC 클라이언트 개발

클라이언트는 Message를 작성해 서버로 전달하고

서버로부터 수신된 Message를 출력한다.

// client.go
package main

import (
 "context"
 "github.com/violetstair/go-grpc/chat"
 "google.golang.org/grpc"
 "log"
)

func main() {
 var conn *grpc.ClientConn
 // gRPC 서버 연결
 conn, err := grpc.Dial(":9080", grpc.WithInsecure());
 if err != nil {
  log.Fatalf("서버 연결 실패 : %s", err)
 }
 defer conn.Close()

 // 서비스 클라이언트 생성
 c := chat.NewChatServiceClient(conn)

 // 서버 호출
 response, err := c.SayHello(context.Background(), &chat.Message{Name: "홍길동", Body: "안녕하세요"})
 if err != nil {
  log.Fatalf("서버 호출 실패 : %s", err)
 }

 log.Printf("%s의 응답 메시지 : %s", response.GetName(), response.GetBody())
}

클라이언트 코드 실행

go run client.go

gRPC 서버 실행 결과

server

gRPC 클라이언트 실행 결과

client

Published May 30, 2021

Right Thoughts, Right Words, Right Action