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 인터페이스를 이용한 서버 코드 작성
서버는 클라이언트로 부터 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
클라이언트는 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 서버 실행 결과
gRPC 클라이언트 실행 결과