Cpp(九) gRPC protobuf for C++ 基本使用
文章目錄
Mac gRPC for C++
#0 原始碼
https://github.com/Coxhuang/FKCpp/tree/master/gRPCDemo
#1 環境
C++14
Python 3.8
macOS 10.5.15
cmake 3.18.2
proto 3
Clion
#2 安裝
略
#3 開始
#3.1 說明
- 使用前需要安裝gRPC
- C++實現gRPC服務端(CMake編譯)
- Python/C++實現gRPC客戶端
#3.2 目錄結構
.
├── CMakeLists.txt
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── Makefile
│ ├── cmake_install.cmake
│ ├── hello_bin
│ └── libhellolibrary.a
├── client.py
├── client_cpp
│ ├── CMakeLists.txt
│ ├── build
│ └── main.cpp
├── main.cpp
├── protos
│ ├── helloworld.grpc.pb.cc
│ ├── helloworld.grpc.pb.h
│ ├── helloworld.pb.cc
│ ├── helloworld.pb.h
│ ├── helloworld.proto
│ ├── helloworld_pb2.py
│ └── helloworld_pb2_grpc.py
└── server_cpp
├── CMakeLists.txt
├── build
└── main.cpp
#3.3 proto檔案
helloworld.proto
syntax = "proto3";
option java_package = "ex.grpc";
package helloworld;
message Reply {
int32 result = 1;
}
message HelloMessage {
int32 a = 1;
int32 b = 2;
}
service TestServer {
rpc hello_request (HelloMessage) returns (Reply) {}
}
生成c++和python對應的檔案
- C++
cd protos
protoc --cpp_out=. helloworld.proto
protoc --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` helloworld.proto
生成:
helloworld.grpc.pb.cc
helloworld.grpc.pb.h
helloworld.pb.cc
helloworld.pb.h
- Python
cd protos
python3 -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. helloworld.proto
生成:
helloworld_pb2_grpc.py
helloworld_pb2.py
#3.4 gRPC服務端(C++)
main.cpp
#include <string>
#include <grpcpp/grpcpp.h>
#include "protos/helloworld.grpc.pb.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using helloworld::TestServer; // MathTest
using helloworld::HelloMessage; // MathRequest
using helloworld::Reply; // MathReply
class HelloServiceImplementation final : public TestServer::Service {
Status hello_request(
ServerContext* context,
const HelloMessage* request,
Reply* reply
) override {
int a = request->a();
int b = request->b();
reply->set_result(a * b);
return Status::OK;
}
};
void Run() {
std::string address("0.0.0.0:5000");
HelloServiceImplementation service;
ServerBuilder builder;
builder.AddListeningPort(address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on port: " << address << std::endl;
server->Wait();
}
int main(int argc, char** argv) {
Run();
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.17)
project(grpcdemo)
set(CMAKE_CXX_STANDARD 14)
find_package(Protobuf REQUIRED)
set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GRPCPP REQUIRED grpc++>=1.22.0)
include_directories(
${GRPCPP_INCLUDE_DIRS}
${Protobuf_INCLUDE_DIRS}
)
link_directories(
${GRPCPP_LIBRARY_DIRS}
)
add_library(hellolibrary ../protos/helloworld.grpc.pb.cc ../protos/helloworld.pb.cc )
add_executable(server_bin main.cpp)
target_link_libraries(server_bin
${GRPCPP_LIBRARIES}
${_PROTOBUF_LIBPROTOBUF}
hellolibrary
)
#3.6 gRPC客戶端(Python/C++)
#3.6.1 Python
client.py
import grpc
from protos import helloworld_pb2
from protos import helloworld_pb2_grpc
from google.protobuf.json_format import ParseDict
import time
class HelloBusiness(object):
def __init__(self):
super(HelloBusiness, self).__init__()
self.ip = "127.0.0.1"
self.port = 5000
self.client_init()
def client_init(self):
"""
gRPC客戶端初始化
:return: None
"""
self.channel = grpc.insecure_channel('{}:{}'.format(self.ip, self.port))
self.client = helloworld_pb2_grpc.TestServerStub(self.channel)
return None
def hello_business(self, msg):
"""
:param msg: request msg
:return:
"""
proto_data = helloworld_pb2.HelloMessage() #
ParseDict(msg, proto_data) # 格式化msg
response = self.client.hello_request.future(proto_data) # 向server傳送資料
response.add_done_callback(self.hello_callback) # 回撥函式, 傳送資料使用非同步[future]時, 必須加回撥函式
return response
def hello_callback(self, future):
print(future.result().result)
print("callback")
class HelloWorld(HelloBusiness):
def hello(self, *args, **kwargs):
"""
:return: None
"""
self.hello_business({
"a": 1,
"b": 2,
})
return None
grpc_client = HelloWorld()
if __name__ == '__main__':
grpc_client.hello()
time.sleep(2)
#3.6.2 C++
#include <iostream>
#include <memory>
#include <string>
#include <grpcpp/grpcpp.h>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "../protos/helloworld.grpc.pb.h"
#endif
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using helloworld::TestServer; // Greeter
using helloworld::HelloMessage; // HelloRequest
using helloworld::Reply; // HelloReply
class GreeterClient {
public:
GreeterClient(std::shared_ptr<Channel> channel):stub_(TestServer::NewStub(channel)) {}
int say_hello(const std::string& user) {
HelloMessage request;
Reply reply;
ClientContext context;
request.set_a(21);
request.set_b(22);
Status status = stub_->hello_request(&context, request, &reply);
if (status.ok()) {
return reply.result();
} else {
std::cout << status.error_code() << ": " << status.error_message() << std::endl;
return 0;
}
}
private:
std::unique_ptr<TestServer::Stub> stub_;
};
int main(int argc, char** argv) {
GreeterClient greeter(grpc::CreateChannel("127.0.0.1:5000", grpc::InsecureChannelCredentials()));
std::string user("world");
int reply = greeter.say_hello(user);
std::cout << "Greeter received: " << reply << std::endl;
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.17)
project(grpcdemo)
set(CMAKE_CXX_STANDARD 14)
find_package(Protobuf REQUIRED)
set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GRPCPP REQUIRED grpc++>=1.22.0)
include_directories(
${GRPCPP_INCLUDE_DIRS}
${Protobuf_INCLUDE_DIRS}
)
link_directories(
${GRPCPP_LIBRARY_DIRS}
)
add_library(hellolibrary ../protos/helloworld.grpc.pb.cc ../protos/helloworld.pb.cc )
add_executable(client_bin main.cpp)
target_link_libraries(client_bin
${GRPCPP_LIBRARIES}
${_PROTOBUF_LIBPROTOBUF}
hellolibrary
)
#3.7 效果
- gRPC服務端
- gRPC客戶端
#4 遇到的問題
- google/protobuf/port_def.inc
'google/protobuf/port_def.inc' file not found
#include <google/protobuf/port_def.inc>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
原因: CMakeLists.txt中沒有新增protobuf的標頭檔案
解決 : include_directories(
${Protobuf_INCLUDE_DIRS}
)
- 無法找到gRPC
CMake Error at CMakeLists.txt:14 (find_package):
By not providing "FindgRPC.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "gRPC", but
CMake did not find one.
Could not find a package configuration file provided by "gRPC" with any of
the following names:
gRPCConfig.cmake
grpc-config.cmake
Add the installation prefix of "gRPC" to CMAKE_PREFIX_PATH or set
"gRPC_DIR" to a directory containing one of the above files. If "gRPC"
provides a separate development package or SDK, be sure it has been
installed.
原因: find_package(gRPC)
解決 : 將find_package(gRPC) 該為: find_package(PkgConfig REQUIRED)
pkg_check_modules(GRPCPP REQUIRED grpc++>=1.22.0)
相關文章
- protobuf和gRPCRPC
- GRPC之protobuf理解RPC
- grpc系列- protobuf詳解RPC
- ubuntu編譯grpc & protobufUbuntu編譯RPC
- 使用gRPC和protobuf建立高效能的APIRPCAPI
- protobuf 的交叉編譯使用(C++)編譯C++
- 思考gRPC:為什麼是protobufRPC
- gRPC(二)入門:Protobuf入門RPC
- C++使用gnuplot-cpp庫繪製影像C++
- GRPC與 ProtoBuf 的理解與總結RPC
- Spring Boot中使用gRPC與Protobuf驗證教程原始碼Spring BootRPC原始碼
- c++ 中.h 和.cppC++
- google protocol buffer——protobuf的基本使用和模型分析GoProtocol模型
- 《Grpc+Protobuf學習筆記》一、前言RPC筆記
- 《Grpc+Protobuf學習筆記》一、protobuf安裝生成程式碼外掛RPC筆記
- 《Grpc+Protobuf學習筆記》二、protobuf安裝生成程式碼外掛RPC筆記
- 《Grpc+Protobuf學習筆記》三、go使用docker編譯執行RPC筆記GoDocker編譯
- C#語言下使用gRPC、protobuf(Google Protocol Buffers)實現檔案傳輸C#RPCGoProtocol
- c++ protobuf安裝記錄C++
- gRPC入門學習之旅(九)RPC
- [cpp]C++中的解構函式C++函式
- php 中使用 protobufPHP
- java中使用protobufJava
- paho.mqtt.cpp的使用MQQT
- 【轉】C++ map的基本操作和使用C++
- 在 Golang 中使用 ProtobufGolang
- Protobuf Java使用嚮導Java
- Google Protobuf 使用 Java 版GoJava
- cpp
- gRPC(2):四種基本通訊模式RPC模式
- go使用grpcGoRPC
- GRPC的使用RPC
- 在java程式中使用protobufJava
- 使用cpp-httplib庫實現HTTP
- Vuejs基本知識(九)【路由】VueJS路由
- clion執行單個c和c++檔案(.c.cpp)C++
- 如何使用 Protobuf 做資料交換
- Protobuf的使用,結合ideaIdea