gRPC는 대부분의 언어에서 동기 및 비동기를 전부 제공합니다.
제공하는 방법은 아래의 통신 패턴들과 같죠
Unary RPC (단일 요청-응답)
클라이언트가 서버에 요청을 한 번 보내고, 서버도 한 번 응답
ex ) "A야, 지금 몇 시야?" → "지금 3시야"
사용 예시 ) 로그인 요청, 사용자 정보 조회와 같은 REST API에서 다루던 동작
proto
rpc GetUser (UserRequest) returns (UserResponse);
go client
res, err := client.GetUser(context.Background(), &pb.UserRequest{Id: "123"})
if err != nil {
log.Fatalf("could not get user: %v", err)
}
fmt.Println("User:", res.Name)
go server
func (s *Server) GetUser(ctx context.Context, req *pb.UserRequest) (*pb.UserResponse, error) {
return &pb.UserResponse{Name: "Alice"}, nil
}
Server Streaming RPC (서버 스트리밍)
클라이언트가 요청을 한 번 보내고, 서버는 여러 개의 응답을 스트리밍으로 전달
ex ) "A야, 오늘 뉴스 알려줘" → "첫 번째 뉴스" → "두 번째 뉴스" → …
사용 예시 ) 뉴스 피드, 실시간 로그 조회
proto
rpc ListUsers (UserFilter) returns (stream User);
go client
// ex) 필터 조건에 따라 사용자 목록 요청
stream, err := client.ListUsers(context.Background(), &pb.UserFilter{})
if err != nil {
log.Fatalf("error: %v", err)
}
for {
// 정보 수신
user, err := stream.Recv()
if err == io.EOF {
break
}
fmt.Println("User:", user.Name)
}
go server
func (s *Server) ListUsers(req *pb.UserFilter, stream pb.YourService_ListUsersServer) error {
users := []string{"Alice", "Bob", "Charlie"}
for _, name := range users {
stream.Send(&pb.User{Name: name})
}
return nil
}
Client Streaming RPC (클라이언트 스트리밍)
클라이언트가 여러 요청을 스트리밍으로 보내고, 서버는 마지막에 한 번 응답
ex ) "A야, 이 파일들 저장해 줘" → "이미지 1" → "이미지 2" → "전부 보냈어" → "확인"
사용 예시 ) 로그 업로드, 대용량 파일 업로드, 센서 데이터 전송
proto
rpc UploadLogs (stream LogEntry) returns (UploadStatus);
go client
stream, err := client.UploadLogs(context.Background())
if err != nil {
log.Fatal(err)
}
for _, msg := range []string{"log1", "log2"} {
stream.Send(&pb.LogEntry{Message: msg})
}
// 스트림 전송 종료를 알리고, 최종 응답을 반환받음
res, _ := stream.CloseAndRecv()
fmt.Println("Status:", res.Success)
go server
func (s *Server) UploadLogs(stream pb.YourService_UploadLogsServer) error {
count := 0
for {
_, err := stream.Recv()
if err == io.EOF {
return stream.SendAndClose(&pb.UploadStatus{Success: true})
}
count++
}
}
Bidirectional Streaming RPC (양방향 스트리밍)
클라이언트와 서버가 서로 자유롭게 동시에 데이터를 주고받음.
ex ) 실시간 대화방처럼 정해진 양식 없이 대화
사용 예시 ) 채팅, 실시간 게임 상태 동기화, 화상 회의 등
proto
rpc Chat (stream ChatMessage) returns (stream ChatMessage);
go client
// 양방향 스트리밍 생성
stream, _ := client.Chat(context.Background())
// 메시지 보내기
go func() {
for _, msg := range []string{"hi", "how are you?"} {
stream.Send(&pb.ChatMessage{Text: msg})
}
stream.CloseSend()
}()
// 메시지 받기
for {
in, err := stream.Recv()
if err == io.EOF {
break
}
fmt.Println("Received:", in.Text)
}
go server
func (s *Server) Chat(stream pb.YourService_ChatServer) error {
for {
msg, err := stream.Recv()
if err == io.EOF {
return nil
}
stream.Send(&pb.ChatMessage{Text: "Echo: " + msg.Text})
}
}
'Go Lang > Study' 카테고리의 다른 글
[GoLang] 동영상 다 받지 않고 스트리밍 하는 법 with ffmpeg (0) | 2025.04.10 |
---|---|
[GoLang] gRPC를 통한 동영상 스트리밍 및 모니터링 (0) | 2025.04.04 |
[GoLang] REST API, gRPC 비교 (0) | 2025.03.15 |
[GoLang] 시간 초과 로직 Context, 채널과 비교 (0) | 2025.02.25 |
[GoLang] net/http에서 http 요청을 동시적으로 처리하는 이유 (0) | 2025.02.17 |
gRPC는 대부분의 언어에서 동기 및 비동기를 전부 제공합니다.
제공하는 방법은 아래의 통신 패턴들과 같죠
Unary RPC (단일 요청-응답)
클라이언트가 서버에 요청을 한 번 보내고, 서버도 한 번 응답
ex ) "A야, 지금 몇 시야?" → "지금 3시야"
사용 예시 ) 로그인 요청, 사용자 정보 조회와 같은 REST API에서 다루던 동작
proto
rpc GetUser (UserRequest) returns (UserResponse);
go client
res, err := client.GetUser(context.Background(), &pb.UserRequest{Id: "123"})
if err != nil {
log.Fatalf("could not get user: %v", err)
}
fmt.Println("User:", res.Name)
go server
func (s *Server) GetUser(ctx context.Context, req *pb.UserRequest) (*pb.UserResponse, error) {
return &pb.UserResponse{Name: "Alice"}, nil
}
Server Streaming RPC (서버 스트리밍)
클라이언트가 요청을 한 번 보내고, 서버는 여러 개의 응답을 스트리밍으로 전달
ex ) "A야, 오늘 뉴스 알려줘" → "첫 번째 뉴스" → "두 번째 뉴스" → …
사용 예시 ) 뉴스 피드, 실시간 로그 조회
proto
rpc ListUsers (UserFilter) returns (stream User);
go client
// ex) 필터 조건에 따라 사용자 목록 요청
stream, err := client.ListUsers(context.Background(), &pb.UserFilter{})
if err != nil {
log.Fatalf("error: %v", err)
}
for {
// 정보 수신
user, err := stream.Recv()
if err == io.EOF {
break
}
fmt.Println("User:", user.Name)
}
go server
func (s *Server) ListUsers(req *pb.UserFilter, stream pb.YourService_ListUsersServer) error {
users := []string{"Alice", "Bob", "Charlie"}
for _, name := range users {
stream.Send(&pb.User{Name: name})
}
return nil
}
Client Streaming RPC (클라이언트 스트리밍)
클라이언트가 여러 요청을 스트리밍으로 보내고, 서버는 마지막에 한 번 응답
ex ) "A야, 이 파일들 저장해 줘" → "이미지 1" → "이미지 2" → "전부 보냈어" → "확인"
사용 예시 ) 로그 업로드, 대용량 파일 업로드, 센서 데이터 전송
proto
rpc UploadLogs (stream LogEntry) returns (UploadStatus);
go client
stream, err := client.UploadLogs(context.Background())
if err != nil {
log.Fatal(err)
}
for _, msg := range []string{"log1", "log2"} {
stream.Send(&pb.LogEntry{Message: msg})
}
// 스트림 전송 종료를 알리고, 최종 응답을 반환받음
res, _ := stream.CloseAndRecv()
fmt.Println("Status:", res.Success)
go server
func (s *Server) UploadLogs(stream pb.YourService_UploadLogsServer) error {
count := 0
for {
_, err := stream.Recv()
if err == io.EOF {
return stream.SendAndClose(&pb.UploadStatus{Success: true})
}
count++
}
}
Bidirectional Streaming RPC (양방향 스트리밍)
클라이언트와 서버가 서로 자유롭게 동시에 데이터를 주고받음.
ex ) 실시간 대화방처럼 정해진 양식 없이 대화
사용 예시 ) 채팅, 실시간 게임 상태 동기화, 화상 회의 등
proto
rpc Chat (stream ChatMessage) returns (stream ChatMessage);
go client
// 양방향 스트리밍 생성
stream, _ := client.Chat(context.Background())
// 메시지 보내기
go func() {
for _, msg := range []string{"hi", "how are you?"} {
stream.Send(&pb.ChatMessage{Text: msg})
}
stream.CloseSend()
}()
// 메시지 받기
for {
in, err := stream.Recv()
if err == io.EOF {
break
}
fmt.Println("Received:", in.Text)
}
go server
func (s *Server) Chat(stream pb.YourService_ChatServer) error {
for {
msg, err := stream.Recv()
if err == io.EOF {
return nil
}
stream.Send(&pb.ChatMessage{Text: "Echo: " + msg.Text})
}
}
'Go Lang > Study' 카테고리의 다른 글
[GoLang] 동영상 다 받지 않고 스트리밍 하는 법 with ffmpeg (0) | 2025.04.10 |
---|---|
[GoLang] gRPC를 통한 동영상 스트리밍 및 모니터링 (0) | 2025.04.04 |
[GoLang] REST API, gRPC 비교 (0) | 2025.03.15 |
[GoLang] 시간 초과 로직 Context, 채널과 비교 (0) | 2025.02.25 |
[GoLang] net/http에서 http 요청을 동시적으로 처리하는 이유 (0) | 2025.02.17 |