gRPC

Language: CPP

Networking

gRPC was introduced by Google in 2015 to standardize communication in microservices and distributed systems. It builds upon Protocol Buffers for schema definition and leverages HTTP/2 for efficient transport. Today, gRPC is widely adopted in cloud-native applications, Kubernetes, and service mesh environments as a modern alternative to REST.

gRPC is a high-performance, open-source universal RPC framework developed by Google. It uses HTTP/2 for transport, Protocol Buffers for serialization, and supports features like authentication, load balancing, and bidirectional streaming.

Installation

linux: sudo apt install protobuf-compiler libgrpc++-dev
mac: brew install grpc
windows: vcpkg install grpc protobuf

Usage

gRPC uses `.proto` files to define service contracts and message schemas. The `protoc` compiler generates C++ stubs, which can be used to implement servers and clients. gRPC supports unary calls, server streaming, client streaming, and bidirectional streaming.

Defining a service

syntax = "proto3";

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

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

Defines a simple gRPC service in Protocol Buffers format.

Implementing a server

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

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

Implements the `SayHello` RPC method on the server side.

Starting the server

int main() {
  GreeterServiceImpl service;
  grpc::ServerBuilder builder;
  builder.AddListeningPort("0.0.0.0:50051", grpc::InsecureServerCredentials());
  builder.RegisterService(&service);
  std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
  server->Wait();
}

Starts a gRPC server on port 50051.

Calling from a client

auto channel = grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials());
std::unique_ptr<Greeter::Stub> stub = Greeter::NewStub(channel);
HelloRequest request;
request.set_name("World");
HelloReply reply;
gr::ClientContext context;

grpc::Status status = stub->SayHello(&context, request, &reply);
if (status.ok()) {
  std::cout << reply.message() << std::endl;
}

Implements a client that calls the `SayHello` RPC method.

Server-side streaming

rpc ListFeatures(Rectangle) returns (stream Feature);

gRPC supports returning streams of messages from server to client.

Bidirectional streaming

rpc Chat(stream ChatMessage) returns (stream ChatMessage);

Both client and server can send messages independently over a stream.

Using TLS encryption

grpc::SslServerCredentialsOptions ssl_opts;
builder.AddListeningPort("0.0.0.0:50051", grpc::SslServerCredentials(ssl_opts));

Enables secure gRPC communication over TLS.

Deadlines and timeouts

context.set_deadline(std::chrono::system_clock::now() + std::chrono::seconds(5));

Specifies a timeout for an RPC call.

Error Handling

UNAVAILABLE: failed to connect to all addresses: Ensure the server is running and reachable at the specified address/port.
DEADLINE_EXCEEDED: The client timeout expired. Increase the deadline or optimize server response time.
PERMISSION_DENIED: Occurs when credentials are missing or invalid. Ensure proper authentication is configured.

Best Practices

Always define clear and stable `.proto` contracts for services.

Use TLS for secure communication in production environments.

Leverage streaming for large datasets or long-lived connections.

Set deadlines to avoid hanging RPCs.

Use interceptors or middleware for logging and monitoring.