프로그래밍 일반/gRPC

gRPC C++ 동기 API 사용법

지노윈 2024. 7. 25. 23:00
반응형

 

gRPC 네 가지 종류의 서비스 메서드

1. 클라이언트가 Stub을 사용하여 서버에 요청을 보내고 일반 함수 호출처럼 응답이 돌아올 때까지 기다리는 RPC입니다.

// Obtains the feature at a given position.
rpc GetFeature(Point) returns (Feature) {}

 

2. 클라이언트가 서버에 요청을 보내고 스트림을 받아 일련의 메시지를 다시 읽는 서버 측 스트리밍 RPC입니다.

클라이언트는 더 이상 메시지가 없을 때까지 반환된 스트림에서 읽습니다. stream 키워드를 응답 타입 앞에 두어 서버 측 스트리밍으로 지정합니다.

// Obtains the Features available within the given Rectangle.  Results are
// streamed rather than returned at once (e.g. in a response message with a
// repeated field), as the rectangle may cover a large area and contain a
// huge number of features.
rpc ListFeatures(Rectangle) returns (stream Feature) {}

 

3. 클라이언트가 일련의 메시지를 작성하여 제공된 스트림을 사용하여 서버로 보내는 클라이언트 측 스트리밍 RPC입니다 . 클라이언트가 메시지 작성을 마치면 서버가 모든 메시지를 읽고 응답을 반환할 때까지 기다립니다. stream 키워드를 요청 타입 앞에 두어 클라이언트측 스트리밍으로 지정합니다.

// Accepts a stream of Points on a route being traversed, returning a
// RouteSummary when traversal is completed.
rpc RecordRoute(stream Point) returns (RouteSummary) {}

 

4. 양쪽이 읽기-쓰기 스트림을 사용하여 일련의 메시지를 보내는 양방향 스트리밍 RPC입니다. 두 스트림은 독립적으로 작동하므로 클라이언트와 서버는 원하는 순서대로 읽고 쓸 수 있습니다.
예를 들어, 서버는 응답을 쓰기 전에 모든 클라이언트 메시지를 수신할 때까지 기다리거나, 메시지를 번갈아가며 읽고 메시지를 쓰거나, 읽기와 쓰기를 조합할 수 있습니다. 

// Accepts a stream of RouteNotes sent while a route is being traversed,
// while receiving other RouteNotes (e.g. from other users).
rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}

 

Stub 생성

먼저 Stub에 대한 gRPC 채널을 생성하고 연결하려는 서버 주소와 포트를 지정해야 합니다. 이 경우 SSL을 사용하지 않습니다.

grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials());
grpc::CreateCustomChannel() 메서드로 추가 옵션을 줄 수 있으며 grpc::ChannelArguments를 사용합니다..

 

NewStub 함수의 인자로 channel을 사용하여 Stub을 생성합니다.

public:
 RouteGuideClient(std::shared_ptr<ChannelInterface> channel,
                  const std::string& db)
     : stub_(RouteGuide::NewStub(channel)) {
   ...
 }

 

GetFeature RPC 호출

생성한 stub으로 GetFeature를 호출 하는 것을 볼 수 있습니다.

Point point;
Feature feature;
point = MakePoint(409146138, -746188906);
GetOneFeature(point, &feature);

...

bool GetOneFeature(const Point& point, Feature* feature) {
  ClientContext context;
  Status status = stub_->GetFeature(&context, point, feature);
  ...
}

 

ListFeatures RPC 호출

서버 응답을 Steam으로 처리하는 RPC입니다.

std::unique_ptr<ClientReader<Feature>> reader(stub_->ListFeatures(&context, rect));

while (reader->Read(&feature)) {
  std::cout << "Found feature called "
            << feature.name() << " at "
            << feature.location().latitude()/kCoordFactor_ << ", "
            << feature.location().longitude()/kCoordFactor_ << std::endl;
}
Status status = reader->Finish();

 

 

RecordRoute RPC 호출

클라이언트 요청을 Stream으로 처리하는 RPC입니다.

std::unique_ptr<ClientWriter<Point>> writer(stub_->RecordRoute(&context, &stats));

for (int i = 0; i < kPoints; i++) {
  const Feature& f = feature_list_[feature_distribution(generator)];
  std::cout << "Visiting point "
            << f.location().latitude()/kCoordFactor_ << ", "
            << f.location().longitude()/kCoordFactor_ << std::endl;
  if (!writer->Write(f.location())) {
    // Broken stream.
    break;
  }
  std::this_thread::sleep_for(std::chrono::milliseconds(delay_distribution(generator)));
}
writer->WritesDone();

Status status = writer->Finish();
if (status.IsOk()) {
  std::cout << "Finished trip with " << stats.point_count() << " points\n"
            << "Passed " << stats.feature_count() << " features\n"
            << "Travelled " << stats.distance() << " meters\n"
            << "It took " << stats.elapsed_time() << " seconds"
            << std::endl;
} else {
  std::cout << "RecordRoute rpc failed." << std::endl;
}

 

RouteChat RPC 호출

양방향 스트림은 위의 코드 모두를 사용하여 구현합니다.

 

https://grpc.io/docs/languages/cpp/basics/