Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第二节样列补充,cpp使用grpc #50

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions ch02/productinfo/cpp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

# Install Environment
```shell
export MY_INSTALL_DIR=$HOME/.local
mkdir -p $MY_INSTALL_DIR
export PATH="$MY_INSTALL_DIR/bin:$PATH"
sudo apt install -y cmake
sudo apt install -y build-essential autoconf libtool pkg-config
git clone --recurse-submodules -b v1.50.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc
cd grpc
mkdir -p cmake/build
pushd cmake/build
cmake -DgRPC_INSTALL=ON \
-DgRPC_BUILD_TESTS=OFF \
-DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR \
../..
make -j 8
sudo make install
popd
```

如果你github的下载速度不够,可以参考一下方法给命令行设置代理
```shell
export http_proxy=http://ip:port
export https_proxy=http://ip:port
```

# Build And Run Server
```shell
cd server
mkdir build
cd build
cmake ..
make -j4
./product_info_server
```

# Build And Run Client
```shell
cd client
mkdir build
cd build
cmake ..
make -j4
./product_info_client
```

# proto
```shell
cd server
protoc -I ../../proto --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ../../proto/product_info.proto
protoc -I ../../proto --cpp_out=. ../../proto/product_info.proto
```
68 changes: 68 additions & 0 deletions ch02/productinfo/cpp/client/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Copyright 2018 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# cmake build file for C++ product_info example.
# Assumes protobuf and gRPC have been installed using cmake.
# See cmake_externalproject/CMakeLists.txt for all-in-one cmake build
# that automatically builds all the dependencies before building product_info.

cmake_minimum_required(VERSION 3.5.1)

project(product_info_client C CXX)

include(../cmake/common.cmake)

# Proto file
get_filename_component(pd_proto "../../proto/product_info.proto" ABSOLUTE)
get_filename_component(pd_proto_path "${pd_proto}" DIRECTORY)

message(STATUS "pd_proto : ${pd_proto}" )
message(STATUS "pd_proto_path : ${pd_proto_path}" )

# Generated sources
set(pd_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/product_info.pb.cc")
set(pd_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/product_info.pb.h")
set(pd_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/product_info.grpc.pb.cc")
set(pd_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/product_info.grpc.pb.h")
message(STATUS ${pd_proto_srcs})
message(STATUS ${CMAKE_CURRENT_BINARY_DIR})
message(STATUS ${pd_proto_path})

# 添加自定义命令
add_custom_command(
OUTPUT "${pd_proto_srcs}" "${pd_proto_hdrs}" "${pd_grpc_srcs}" "${pd_grpc_hdrs}"
COMMAND ${_PROTOBUF_PROTOC}
ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}"
--cpp_out "${CMAKE_CURRENT_BINARY_DIR}"
-I "${pd_proto_path}"
--plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}"
"${pd_proto}"
DEPENDS "${pd_proto}")

# Include generated *.pb.h files
include_directories("${CMAKE_CURRENT_BINARY_DIR}")

# pd_grpc_proto
add_library(pd_grpc_proto
${pd_grpc_srcs}
${pd_grpc_hdrs}
${pd_proto_srcs}
${pd_proto_hdrs})
target_link_libraries(pd_grpc_proto
${_REFLECTION}
${_GRPC_GRPCPP}
${_PROTOBUF_LIBPROTOBUF})

add_executable(${PROJECT_NAME} ProductInfoClient.cc )
target_link_libraries(${PROJECT_NAME} pd_grpc_proto ${_REFLECTION} ${_GRPC_GRPCPP} ${_PROTOBUF_LIBPROTOBUF})
140 changes: 140 additions & 0 deletions ch02/productinfo/cpp/client/ProductInfoClient.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

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

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


using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
//using ecommerce::Product;
//using ecommerce::ProductInfo;
//using ecommerce::HelloRequest;

class ProductInfoClient {
public:
ProductInfoClient(std::shared_ptr<Channel> channel)
: stub_(ecommerce::ProductInfo::NewStub(channel)) {}

// Assembles the client's payload, sends it and presents the response back
// from the server.
std::string addProduct(const std::string & name ,const std::string & desc , const float price) {
// Data we are sending to the server.
ecommerce::Product request;
request.set_name(name);
request.set_description(desc);
request.set_price(price);

// Container for the data we expect from the server.
ecommerce::ProductID reply;

// Context for the client. It could be used to convey extra information to
// the server and/or tweak certain RPC behaviors.
ClientContext context;

// The actual RPC.
Status status = stub_->addProduct(&context, request, &reply);

// Act upon its status.
if (status.ok()) {
return reply.value();
} else {
std::cout << status.error_code() << ": " << status.error_message()
<< std::endl;
return "RPC failed";
}
}

std::string getProduct(const std::string & id ){
ecommerce::ProductID request;
request.set_value(id);
ecommerce::Product reply;
ClientContext context;
Status status = stub_->getProduct(&context,request,&reply);

if (status.ok()){
return reply.DebugString();
}
else{
std::cout << status.error_code() << ": " << status.error_message()
<< std::endl;
return "RPC failed";
}
}

private:
std::unique_ptr<ecommerce::ProductInfo::Stub> stub_;
};

int main(int argc, char** argv) {
// Instantiate the client. It requires a channel, out of which the actual RPCs
// are created. This channel models a connection to an endpoint specified by
// the argument "--target=" which is the only expected argument.
// We indicate that the channel isn't authenticated (use of
// InsecureChannelCredentials()).
std::string target_str;
std::string arg_str("--target");
if (argc > 1) {
std::string arg_val = argv[1];
size_t start_pos = arg_val.find(arg_str);
if (start_pos != std::string::npos) {
start_pos += arg_str.size();
if (arg_val[start_pos] == '=') {
target_str = arg_val.substr(start_pos + 1);
} else {
std::cout << "The only correct argument syntax is --target="
<< std::endl;
return 0;
}
} else {
std::cout << "The only acceptable argument is --target=" << std::endl;
return 0;
}
} else {
target_str = "localhost:50051";
}
ProductInfoClient product_info_server(
grpc::CreateChannel(target_str, grpc::InsecureChannelCredentials()));
std::string reply = product_info_server.addProduct(
"Apple iPhone 11",
"Meet Apple iPhone 11. All-new dual-camera system with Ultra Wide and Nigh mode.",
1000.0);
std::cout << "ProductInfo received: " << reply << std::endl;

reply = product_info_server.addProduct(
"Apple iPhone 11 Mini",
"Meet Apple iPhone 11 Mini.",
899.0);
std::cout << "ProductInfo received: " << reply << std::endl;

reply = product_info_server.addProduct(
"Apple iPhone 11 SE",
"Meet Apple iPhone 11 SE.",
1000.0);
std::cout << "ProductInfo received: " << reply << std::endl;

std::string product_info = product_info_server.getProduct("2");
std::cout << "ProductInfo received: " << product_info << std::endl;

return 0;
}
125 changes: 125 additions & 0 deletions ch02/productinfo/cpp/cmake/common.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Copyright 2018 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# cmake build file for C++ route_guide example.
# Assumes protobuf and gRPC have been installed using cmake.
# See cmake_externalproject/CMakeLists.txt for all-in-one cmake build
# that automatically builds all the dependencies before building route_guide.

cmake_minimum_required(VERSION 3.5.1)

if (NOT DEFINED CMAKE_CXX_STANDARD)
set (CMAKE_CXX_STANDARD 14)
endif()

if(MSVC)
add_definitions(-D_WIN32_WINNT=0x600)
endif()

find_package(Threads REQUIRED)

if(GRPC_AS_SUBMODULE)
# One way to build a projects that uses gRPC is to just include the
# entire gRPC project tree via "add_subdirectory".
# This approach is very simple to use, but the are some potential
# disadvantages:
# * it includes gRPC's CMakeLists.txt directly into your build script
# without and that can make gRPC's internal setting interfere with your
# own build.
# * depending on what's installed on your system, the contents of submodules
# in gRPC's third_party/* might need to be available (and there might be
# additional prerequisites required to build them). Consider using
# the gRPC_*_PROVIDER options to fine-tune the expected behavior.
#
# A more robust approach to add dependency on gRPC is using
# cmake's ExternalProject_Add (see cmake_externalproject/CMakeLists.txt).

# Include the gRPC's cmake build (normally grpc source code would live
# in a git submodule called "third_party/grpc", but this example lives in
# the same repository as gRPC sources, so we just look a few directories up)
add_subdirectory(../../.. ${CMAKE_CURRENT_BINARY_DIR}/grpc EXCLUDE_FROM_ALL)
message(STATUS "Using gRPC via add_subdirectory.")

# After using add_subdirectory, we can now use the grpc targets directly from
# this build.
set(_PROTOBUF_LIBPROTOBUF libprotobuf)
set(_REFLECTION grpc++_reflection)
if(CMAKE_CROSSCOMPILING)
find_program(_PROTOBUF_PROTOC protoc)
else()
set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)
endif()
set(_GRPC_GRPCPP grpc++)
if(CMAKE_CROSSCOMPILING)
find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
else()
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:grpc_cpp_plugin>)
endif()
elseif(GRPC_FETCHCONTENT)
# Another way is to use CMake's FetchContent module to clone gRPC at
# configure time. This makes gRPC's source code available to your project,
# similar to a git submodule.
message(STATUS "Using gRPC via add_subdirectory (FetchContent).")
include(FetchContent)
FetchContent_Declare(
grpc
GIT_REPOSITORY https://github.com/grpc/grpc.git
# when using gRPC, you will actually set this to an existing tag, such as
# v1.25.0, v1.26.0 etc..
# For the purpose of testing, we override the tag used to the commit
# that's currently under test.
GIT_TAG vGRPC_TAG_VERSION_OF_YOUR_CHOICE)
FetchContent_MakeAvailable(grpc)

# Since FetchContent uses add_subdirectory under the hood, we can use
# the grpc targets directly from this build.
set(_PROTOBUF_LIBPROTOBUF libprotobuf)
set(_REFLECTION grpc++_reflection)
set(_PROTOBUF_PROTOC $<TARGET_FILE:protoc>)
set(_GRPC_GRPCPP grpc++)
if(CMAKE_CROSSCOMPILING)
find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
else()
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:grpc_cpp_plugin>)
endif()
else()
# This branch assumes that gRPC and all its dependencies are already installed
# on this system, so they can be located by find_package().

# Find Protobuf installation
# Looks for protobuf-config.cmake file installed by Protobuf's cmake installation.
set(protobuf_MODULE_COMPATIBLE TRUE)
find_package(Protobuf CONFIG REQUIRED)
message(STATUS "Using protobuf ${Protobuf_VERSION}")

set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
set(_REFLECTION gRPC::grpc++_reflection)
if(CMAKE_CROSSCOMPILING)
find_program(_PROTOBUF_PROTOC protoc)
else()
set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)
endif()

# Find gRPC installation
# Looks for gRPCConfig.cmake file installed by gRPC's cmake installation.
find_package(gRPC CONFIG REQUIRED)
message(STATUS "Using gRPC ${gRPC_VERSION}")

set(_GRPC_GRPCPP gRPC::grpc++)
if(CMAKE_CROSSCOMPILING)
find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
else()
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:gRPC::grpc_cpp_plugin>)
endif()
endif()
Loading