gRPC для C++: библиотеки, примеры и практическое руководство
gRPC — это современная, высокопроизводительная среда удаленного вызова процедур (RPC), разработанная Google. Она позволяет клиентским и серверным приложениям на разных языках (включая C++, Python, Go, Java) общаться друг с другом так же легко, как если бы это были локальные вызовы функций. Для C++ gRPC предоставляет мощный, строго типизированный интерфейс на основе Protocol Buffers (protobuf), что делает его идеальным выбором для создания микросервисов и распределенных систем.
В этой статье мы разберем ключевые библиотеки, процесс установки и напишем полноценный пример gRPC-сервера и клиента на C++.
Ключевые библиотеки для gRPC в C++
Для работы с gRPC на C++ вам понадобятся следующие компоненты:
- grpc (libgrpc++) — основная библиотека gRPC. Содержит реализацию транспортного уровня (HTTP/2), каналы, серверы и асинхронные стеки.
- protobuf (libprotobuf) — библиотека для сериализации структурированных данных. Определяет формат сообщений (.proto файлы) и генерирует C++ код.
- grpc++ (libgrpc++_unsecure или libgrpc++_reflection) — высокоуровневая C++ обертка для gRPC. Обеспечивает синхронный и асинхронный API для сервисов.
- grpc_cpp_plugin — плагин для компилятора protobuf (
protoc), который генерирует C++ код для серверов и клиентов gRPC. - abseil-cpp — библиотека от Google, используемая gRPC для строк, потоков и синхронизации (часто подключается автоматически).
Установка и настройка
Рекомендуемый способ установки — сборка из исходников или использование менеджера пакетов vcpkg/conan. Покажем установку через vcpkg:
# Установка vcpkg (если ещё не установлен)
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
# Установка gRPC с поддержкой C++
./vcpkg install grpc[ssl]
После установки подключите библиотеки в CMakeLists.txt:
cmake_minimum_required(VERSION 3.15)
project(GrpcExample CXX)
set(CMAKE_CXX_STANDARD 17)
find_package(gRPC CONFIG REQUIRED)
find_package(Protobuf CONFIG REQUIRED)
# Генерация proto-файлов
set(PROTO_FILE proto/hello.proto)
set(GENERATED_PROTO_SRC ${CMAKE_CURRENT_BINARY_DIR}/hello.pb.cc)
set(GENERATED_PROTO_HDR ${CMAKE_CURRENT_BINARY_DIR}/hello.pb.h)
set(GENERATED_GRPC_SRC ${CMAKE_CURRENT_BINARY_DIR}/hello.grpc.pb.cc)
set(GENERATED_GRPC_HDR ${CMAKE_CURRENT_BINARY_DIR}/hello.grpc.pb.h)
add_custom_command(
OUTPUT ${GENERATED_PROTO_SRC} ${GENERATED_PROTO_HDR} ${GENERATED_GRPC_SRC} ${GENERATED_GRPC_HDR}
COMMAND protobuf::protoc
ARGS --grpc_out ${CMAKE_CURRENT_BINARY_DIR}
--cpp_out ${CMAKE_CURRENT_BINARY_DIR}
--plugin=protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>
-I ${CMAKE_CURRENT_SOURCE_DIR}/proto
${CMAKE_CURRENT_SOURCE_DIR}/${PROTO_FILE}
DEPENDS ${PROTO_FILE}
COMMENT "Generating gRPC code from proto files"
)
add_library(generated_proto ${GENERATED_PROTO_SRC} ${GENERATED_GRPC_SRC})
target_include_directories(generated_proto PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(generated_proto gRPC::grpc++ protobuf::libprotobuf)
Создание .proto файла
Сначала определим сервис и сообщения в файле hello.proto:
syntax = "proto3";
package hello;
// Запрос: отправляем имя
message HelloRequest {
string name = 1;
}
// Ответ: получаем приветствие
message HelloReply {
string message = 1;
}
// Определяем gRPC сервис
service Greeter {
// Unary RPC (один запрос — один ответ)
rpc SayHello (HelloRequest) returns (HelloReply);
}
Реализация сервера на C++
Создадим файл server.cpp:
#include <iostream>
#include <memory>
#include <string>
#include <grpcpp/