Skip to main content

C++ gRPC Integration Tutorial

gRPC (Google Remote Procedure Call) is a high-performance RPC framework that uses HTTP/2, Protocol Buffers, and provides support for multiple languages, including C++. This tutorial covers setting up a basic gRPC server and client in C++.


Prerequisites​

  1. C++ Compiler: Ensure you have a C++ compiler installed.
  2. gRPC and Protocol Buffers: Install gRPC and Protocol Buffers.

Installing gRPC and Protobuf​

Follow these steps to install gRPC and Protocol Buffers.

Step 1: Clone the gRPC Repository​

git clone --recurse-submodules -b v1.40.0 https://github.com/grpc/grpc
cd grpc

Step 2: Install Protocol Buffers​

cd third_party/protobuf
mkdir -p cmake/build
cd cmake/build
cmake -Dprotobuf_BUILD_TESTS=OFF ..
make -j 4
sudo make install

Step 3: Build and Install gRPC​

cd ../../..  # Go back to the gRPC root directory
mkdir -p cmake/build
cd cmake/build
cmake -DgRPC_INSTALL=ON -DgRPC_BUILD_TESTS=OFF ..
make -j 4
sudo make install

Once installed, verify by running:

protoc --version

1. Defining the gRPC Service in .proto​

Create a new directory for your project, and inside it, create a protos folder with a greet.proto file:

syntax = "proto3";

option cpp_namespace = "grpc_example";

service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
string name = 1;
}

message HelloReply {
string message = 1;
}

This file defines a Greeter service with a SayHello RPC method.


2. Generating C++ Code from the .proto File​

Run the following command to generate the necessary gRPC and protobuf classes:

protoc -I=protos --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` protos/greet.proto
protoc -I=protos --cpp_out=. protos/greet.proto

This generates greet.pb.h, greet.pb.cc, greet.grpc.pb.h, and greet.grpc.pb.cc files.


3. Implementing the gRPC Server​

Create a server.cpp file to implement the server-side logic:

#include <iostream>
#include <memory>
#include <string>

#include <grpcpp/grpcpp.h>
#include "greet.grpc.pb.h"

using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using grpc_example::Greeter;
using grpc_example::HelloReply;
using grpc_example::HelloRequest;

class GreeterServiceImpl final : public Greeter::Service {
Status SayHello(ServerContext* context, const HelloRequest* request, HelloReply* reply) override {
std::string prefix("Hello, ");
reply->set_message(prefix + request->name());
return Status::OK;
}
};

void RunServer() {
std::string server_address("0.0.0.0:50051");
GreeterServiceImpl service;

ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);

std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
server->Wait();
}

int main(int argc, char** argv) {
RunServer();
return 0;
}

Compile the server:

g++ -std=c++11 server.cpp greet.pb.cc greet.grpc.pb.cc -o server `pkg-config --cflags --libs grpc++ protobuf`

4. Implementing the gRPC Client​

Create a client.cpp file to implement the client-side logic:

#include <iostream>
#include <memory>
#include <string>

#include <grpcpp/grpcpp.h>
#include "greet.grpc.pb.h"

using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using grpc_example::Greeter;
using grpc_example::HelloReply;
using grpc_example::HelloRequest;

class GreeterClient {
public:
GreeterClient(std::shared_ptr<Channel> channel)
: stub_(Greeter::NewStub(channel)) {}

std::string SayHello(const std::string& user) {
HelloRequest request;
request.set_name(user);

HelloReply reply;
ClientContext context;

Status status = stub_->SayHello(&context, request, &reply);

if (status.ok()) {
return reply.message();
} else {
std::cerr << "gRPC call failed." << std::endl;
return "RPC failed";
}
}

private:
std::unique_ptr<Greeter::Stub> stub_;
};

int main(int argc, char** argv) {
GreeterClient client(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));
std::string user("World");
std::string reply = client.SayHello(user);
std::cout << "Greeter received: " << reply << std::endl;

return 0;
}

Compile the client:

g++ -std=c++11 client.cpp greet.pb.cc greet.grpc.pb.cc -o client `pkg-config --cflags --libs grpc++ protobuf`

5. Running the Server and Client​

  1. Start the server in one terminal:

    ./server
  2. Run the client in another terminal:

    ./client

The client should print the response from the server: "Greeter received: Hello, World".


Summary​

This tutorial covered the basics of integrating gRPC with C++, including:

  1. Defining a gRPC service in a .proto file.
  2. Generating C++ code from the .proto file.
  3. Implementing a gRPC server and client.

gRPC provides a powerful, efficient way to handle communication between services. Experiment with additional gRPC methods and client configurations to enhance your setup.

Content Review​

The content in this repository has been reviewed by chevp. Chevp is dedicated to ensuring that the information provided is accurate, relevant, and up-to-date, helping users to learn and implement programming skills effectively.

About the Reviewer​

For more insights and contributions, visit chevp's GitHub profile: chevp's GitHub Profile.