简介
本文主要讲述如何在Windows环境下使用visual studio配置grpc,并且实现grpc通信的例子。前文windows配置和编译grpc已经介绍了如何在windows环境配置grpc,接下来我们利用之前编译好的库配置到项目中,并实现grpc通信。
项目配置
我们为了方便配置,将之前下载和编译好的项目放在D盘cppsoft文件夹下,路径为D:\cppsoft\grpc。

接下来我们创建一个项目,名字叫Grpc-Server,在项目的根目录下创建一个proto名字为demo.proto
syntax = "proto3";package hello;service Greeter {rpc SayHello (HelloRequest) returns (HelloReply) {}}message HelloRequest {string message = 1;}message HelloReply {string message = 1;}
接下来我们利用grpc编译后生成的proc.exe生成proto的头文件和源文件
D:\cppsoft\grpc\visualpro\third_party\protobuf\Debug\protoc.exe -I="." --grpc_out="." --plugin=protoc-gen-grpc="D:\cppsoft\grpc\visualpro\Debug\grpc_cpp_plugin.exe" "demo.proto"
上述命令会生成demo.grpc.pb.h和demo.grpc.pb.cc文件。
D:\cppsoft\grpc\visualpro\third_party\protobuf\Debug\protoc.exe表示protoc.exe所在的路径,你可以将其放在指定目录并配置环境变量,直接使用protoc.exe就行了。
-I="." 指定 demo.proto所在的路径为当前路径。
--grpc_out="." 表示生成的pb.h和pb.cc文件的输出目录。
--plugin=protoc-gen-grpc="D:\cppsoft\grpc\visualpro\Debug\grpc_cpp_plugin.exe"表示要使用的插件为cpp插件,也就是生成cpp类的头文件和源文件。
接下来我们生成grpc类需要的pb文件,因为要序列化数据。
D:\cppsoft\grpc\visualpro\third_party\protobuf\Debug\protoc.exe --cpp_out=. "demo.proto"
上述命令会生成demo.pb.h和demo.pb.cc文件。
接下来我们在项目中配置grpc库的包含目录和库目录。
为了方便调试,我们配置debug版本

项目属性中选择C++下的常规选项,在附加包含目录中添加我们grpc生成debug库

这里列举下要包含的目录
D:\workspace\github\grpc\third_party\re2D:\workspace\github\grpc\third_party\address_sorting\includeD:\workspace\github\grpc\third_party\abseil-cppD:\workspace\github\grpc\third_party\protobuf\srcD:\workspace\github\grpc\include
接下来配置库路径, 在链接器常规选项下,点击附加库目录,添加我们需要的库目录。

同样,我们配置的是debug版本

要配置的库目录很多,这里详细列举一下
D:\cppsoft\grpc\visualpro\third_party\re2\DebugD:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\types\DebugD:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\synchronization\DebugD:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\status\DebugD:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\random\DebugD:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\flags\DebugD:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\debugging\DebugD:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\container\DebugD:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\hash\DebugD:\cppsoft\grpc\visualpro\third_party\boringssl-with-bazel\DebugD:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\numeric\DebugD:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\time\DebugD:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\base\DebugD:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\strings\DebugD:\cppsoft\grpc\visualpro\third_party\protobuf\DebugD:\cppsoft\grpc\visualpro\third_party\zlib\DebugD:\cppsoft\grpc\visualpro\DebugD:\cppsoft\grpc\visualpro\third_party\cares\cares\lib\Debug
另外,我们虽然配置了库目录,但还要将要使用的库链接到项目
在链接器输入选项下,点击附加依赖项添加依赖的库名字

库配置

库名字列举如下
libprotobufd.libgpr.libgrpc.libgrpc++.libgrpc++_reflection.libaddress_sorting.libws2_32.libcares.libzlibstaticd.libupb.libssl.libcrypto.libabsl_bad_any_cast_impl.libabsl_bad_optional_access.libabsl_bad_variant_access.libabsl_base.libabsl_city.libabsl_civil_time.libabsl_cord.libabsl_debugging_internal.libabsl_demangle_internal.libabsl_examine_stack.libabsl_exponential_biased.libabsl_failure_signal_handler.libabsl_flags.libabsl_flags_config.libabsl_flags_internal.libabsl_flags_marshalling.libabsl_flags_parse.libabsl_flags_program_name.libabsl_flags_usage.libabsl_flags_usage_internal.libabsl_graphcycles_internal.libabsl_hash.libabsl_hashtablez_sampler.libabsl_int128.libabsl_leak_check.libabsl_leak_check_disable.libabsl_log_severity.libabsl_malloc_internal.libabsl_periodic_sampler.libabsl_random_distributions.libabsl_random_internal_distribution_test_util.libabsl_random_internal_pool_urbg.libabsl_random_internal_randen.libabsl_random_internal_randen_hwaes.libabsl_random_internal_randen_hwaes_impl.libabsl_random_internal_randen_slow.libabsl_random_internal_seed_material.libabsl_random_seed_gen_exception.libabsl_random_seed_sequences.libabsl_raw_hash_set.libabsl_raw_logging_internal.libabsl_scoped_set_env.libabsl_spinlock_wait.libabsl_stacktrace.libabsl_status.libabsl_strings.libabsl_strings_internal.libabsl_str_format_internal.libabsl_symbolize.libabsl_synchronization.libabsl_throw_delegate.libabsl_time.libabsl_time_zone.libabsl_statusor.libre2.lib
grpc服务器
接下来我们写代码,实现grpc服务器
#include <iostream>#include <memory>#include <string>#include <grpcpp/grpcpp.h>#include "demo.grpc.pb.h"using grpc::Server;using grpc::ServerBuilder;using grpc::ServerContext;using grpc::Status;using hello::HelloRequest;using hello::HelloReply;using hello::Greeter;// Logic and data behind the server's behavior.class GreeterServiceImpl final : public Greeter::Service {Status SayHello(ServerContext* context, const HelloRequest* request,HelloReply* reply) override {std::string prefix("llfc grpc server has received : ");reply->set_message(prefix + request->message());return Status::OK;}};void RunServer() {std::string server_address("127.0.0.1:50051");GreeterServiceImpl service;ServerBuilder builder;// Listen on the given address without any authentication mechanism.// 监听给定的地址builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());// Register "service" as the instance through which we'll communicate with// clients. In this case it corresponds to an *synchronous* service.builder.RegisterService(&service);// Finally assemble the server.std::unique_ptr<Server> server(builder.BuildAndStart());std::cout << "Server listening on " << server_address << std::endl;// Wait for the server to shutdown. Note that some other thread must be// responsible for shutting down the server for this call to ever return.server->Wait();}int main(int argc, char** argv) {RunServer();return 0;}
GreeterServiceImpl 继承自 Greeter::Service,重写了SayHello函数,当收到客户端发送的SayHello请求后执行重写函数功能的逻辑。
grpc客户端
grpc客户端比较简单,直接调用发送接口发送数据即可
#include <string>#include <iostream>#include <memory>#include <grpcpp/grpcpp.h>#include "demo.grpc.pb.h"using grpc::ClientContext;using grpc::Channel;using grpc::Status;using hello::HelloReply;using hello::HelloRequest;using hello::Greeter;// static method : Greeter::NewStubclass FCClient {public:FCClient(std::shared_ptr<Channel> channel):stub_(Greeter::NewStub(channel)) {}std::string SayHello(std::string name) {ClientContext context;HelloReply reply;HelloRequest request;request.set_message(name);Status status = stub_->SayHello(&context, request, &reply);if (status.ok()) {return reply.message();}else {return "failure " + status.error_message();}}private:std::unique_ptr<Greeter::Stub> stub_;};int main(int argc, char* argv[]) {auto channel = grpc::CreateChannel("127.0.0.1:50051", grpc::InsecureChannelCredentials());FCClient client(channel);// block until get result from RPC serverstd::string result = client.SayHello("hello , llfc.club !");printf("get result [%s]\n", result.c_str());return 0;}
客户端创建了一个channel,然后调用NewStub生成stub,接下来就可以发送数据了,下面是运行的效果

总结
本文介绍了grpc在windows环境下的配置和使用