windows配置和使用grpc

简介

本文主要讲述如何在Windows环境下使用visual studio配置grpc,并且实现grpc通信的例子。前文windows配置和编译grpc已经介绍了如何在windows环境配置grpc,接下来我们利用之前编译好的库配置到项目中,并实现grpc通信。

项目配置

我们为了方便配置,将之前下载和编译好的项目放在D盘cppsoft文件夹下,路径为D:\cppsoft\grpc

https://cdn.llfc.club/1685531030735.jpg

接下来我们创建一个项目,名字叫Grpc-Server,在项目的根目录下创建一个proto名字为demo.proto

  1. syntax = "proto3";
  2. package hello;
  3. service Greeter {
  4. rpc SayHello (HelloRequest) returns (HelloReply) {}
  5. }
  6. message HelloRequest {
  7. string message = 1;
  8. }
  9. message HelloReply {
  10. string message = 1;
  11. }

接下来我们利用grpc编译后生成的proc.exe生成proto的头文件和源文件

  1. 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文件,因为要序列化数据。

  1. D:\cppsoft\grpc\visualpro\third_party\protobuf\Debug\protoc.exe --cpp_out=. "demo.proto"

上述命令会生成demo.pb.h和demo.pb.cc文件。

接下来我们在项目中配置grpc库的包含目录和库目录。
为了方便调试,我们配置debug版本

https://cdn.llfc.club/1685532359790.jpg

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

https://cdn.llfc.club/1685532525027.jpg

这里列举下要包含的目录

  1. D:\workspace\github\grpc\third_party\re2
  2. D:\workspace\github\grpc\third_party\address_sorting\include
  3. D:\workspace\github\grpc\third_party\abseil-cpp
  4. D:\workspace\github\grpc\third_party\protobuf\src
  5. D:\workspace\github\grpc\include

接下来配置库路径, 在链接器常规选项下,点击附加库目录,添加我们需要的库目录。

https://cdn.llfc.club/1685532681403.jpg

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

https://cdn.llfc.club/1685532839282.jpg

要配置的库目录很多,这里详细列举一下

  1. D:\cppsoft\grpc\visualpro\third_party\re2\Debug
  2. D:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\types\Debug
  3. D:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\synchronization\Debug
  4. D:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\status\Debug
  5. D:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\random\Debug
  6. D:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\flags\Debug
  7. D:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\debugging\Debug
  8. D:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\container\Debug
  9. D:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\hash\Debug
  10. D:\cppsoft\grpc\visualpro\third_party\boringssl-with-bazel\Debug
  11. D:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\numeric\Debug
  12. D:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\time\Debug
  13. D:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\base\Debug
  14. D:\cppsoft\grpc\visualpro\third_party\abseil-cpp\absl\strings\Debug
  15. D:\cppsoft\grpc\visualpro\third_party\protobuf\Debug
  16. D:\cppsoft\grpc\visualpro\third_party\zlib\Debug
  17. D:\cppsoft\grpc\visualpro\Debug
  18. D:\cppsoft\grpc\visualpro\third_party\cares\cares\lib\Debug

另外,我们虽然配置了库目录,但还要将要使用的库链接到项目
在链接器输入选项下,点击附加依赖项添加依赖的库名字

https://cdn.llfc.club/1685532997690.jpg

库配置

https://cdn.llfc.club/1685533182327.jpg

库名字列举如下

  1. libprotobufd.lib
  2. gpr.lib
  3. grpc.lib
  4. grpc++.lib
  5. grpc++_reflection.lib
  6. address_sorting.lib
  7. ws2_32.lib
  8. cares.lib
  9. zlibstaticd.lib
  10. upb.lib
  11. ssl.lib
  12. crypto.lib
  13. absl_bad_any_cast_impl.lib
  14. absl_bad_optional_access.lib
  15. absl_bad_variant_access.lib
  16. absl_base.lib
  17. absl_city.lib
  18. absl_civil_time.lib
  19. absl_cord.lib
  20. absl_debugging_internal.lib
  21. absl_demangle_internal.lib
  22. absl_examine_stack.lib
  23. absl_exponential_biased.lib
  24. absl_failure_signal_handler.lib
  25. absl_flags.lib
  26. absl_flags_config.lib
  27. absl_flags_internal.lib
  28. absl_flags_marshalling.lib
  29. absl_flags_parse.lib
  30. absl_flags_program_name.lib
  31. absl_flags_usage.lib
  32. absl_flags_usage_internal.lib
  33. absl_graphcycles_internal.lib
  34. absl_hash.lib
  35. absl_hashtablez_sampler.lib
  36. absl_int128.lib
  37. absl_leak_check.lib
  38. absl_leak_check_disable.lib
  39. absl_log_severity.lib
  40. absl_malloc_internal.lib
  41. absl_periodic_sampler.lib
  42. absl_random_distributions.lib
  43. absl_random_internal_distribution_test_util.lib
  44. absl_random_internal_pool_urbg.lib
  45. absl_random_internal_randen.lib
  46. absl_random_internal_randen_hwaes.lib
  47. absl_random_internal_randen_hwaes_impl.lib
  48. absl_random_internal_randen_slow.lib
  49. absl_random_internal_seed_material.lib
  50. absl_random_seed_gen_exception.lib
  51. absl_random_seed_sequences.lib
  52. absl_raw_hash_set.lib
  53. absl_raw_logging_internal.lib
  54. absl_scoped_set_env.lib
  55. absl_spinlock_wait.lib
  56. absl_stacktrace.lib
  57. absl_status.lib
  58. absl_strings.lib
  59. absl_strings_internal.lib
  60. absl_str_format_internal.lib
  61. absl_symbolize.lib
  62. absl_synchronization.lib
  63. absl_throw_delegate.lib
  64. absl_time.lib
  65. absl_time_zone.lib
  66. absl_statusor.lib
  67. re2.lib

grpc服务器

接下来我们写代码,实现grpc服务器

  1. #include <iostream>
  2. #include <memory>
  3. #include <string>
  4. #include <grpcpp/grpcpp.h>
  5. #include "demo.grpc.pb.h"
  6. using grpc::Server;
  7. using grpc::ServerBuilder;
  8. using grpc::ServerContext;
  9. using grpc::Status;
  10. using hello::HelloRequest;
  11. using hello::HelloReply;
  12. using hello::Greeter;
  13. // Logic and data behind the server's behavior.
  14. class GreeterServiceImpl final : public Greeter::Service {
  15. Status SayHello(ServerContext* context, const HelloRequest* request,
  16. HelloReply* reply) override {
  17. std::string prefix("llfc grpc server has received : ");
  18. reply->set_message(prefix + request->message());
  19. return Status::OK;
  20. }
  21. };
  22. void RunServer() {
  23. std::string server_address("127.0.0.1:50051");
  24. GreeterServiceImpl service;
  25. ServerBuilder builder;
  26. // Listen on the given address without any authentication mechanism.
  27. // 监听给定的地址
  28. builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
  29. // Register "service" as the instance through which we'll communicate with
  30. // clients. In this case it corresponds to an *synchronous* service.
  31. builder.RegisterService(&service);
  32. // Finally assemble the server.
  33. std::unique_ptr<Server> server(builder.BuildAndStart());
  34. std::cout << "Server listening on " << server_address << std::endl;
  35. // Wait for the server to shutdown. Note that some other thread must be
  36. // responsible for shutting down the server for this call to ever return.
  37. server->Wait();
  38. }
  39. int main(int argc, char** argv) {
  40. RunServer();
  41. return 0;
  42. }

GreeterServiceImpl 继承自 Greeter::Service,重写了SayHello函数,当收到客户端发送的SayHello请求后执行重写函数功能的逻辑。

grpc客户端

grpc客户端比较简单,直接调用发送接口发送数据即可

  1. #include <string>
  2. #include <iostream>
  3. #include <memory>
  4. #include <grpcpp/grpcpp.h>
  5. #include "demo.grpc.pb.h"
  6. using grpc::ClientContext;
  7. using grpc::Channel;
  8. using grpc::Status;
  9. using hello::HelloReply;
  10. using hello::HelloRequest;
  11. using hello::Greeter;
  12. // static method : Greeter::NewStub
  13. class FCClient {
  14. public:
  15. FCClient(std::shared_ptr<Channel> channel)
  16. :stub_(Greeter::NewStub(channel)) {
  17. }
  18. std::string SayHello(std::string name) {
  19. ClientContext context;
  20. HelloReply reply;
  21. HelloRequest request;
  22. request.set_message(name);
  23. Status status = stub_->SayHello(&context, request, &reply);
  24. if (status.ok()) {
  25. return reply.message();
  26. }
  27. else {
  28. return "failure " + status.error_message();
  29. }
  30. }
  31. private:
  32. std::unique_ptr<Greeter::Stub> stub_;
  33. };
  34. int main(int argc, char* argv[]) {
  35. auto channel = grpc::CreateChannel("127.0.0.1:50051", grpc::InsecureChannelCredentials());
  36. FCClient client(channel);
  37. // block until get result from RPC server
  38. std::string result = client.SayHello("hello , llfc.club !");
  39. printf("get result [%s]\n", result.c_str());
  40. return 0;
  41. }

客户端创建了一个channel,然后调用NewStub生成stub,接下来就可以发送数据了,下面是运行的效果

https://cdn.llfc.club/1685534091844.jpg

总结

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

源码链接https://gitee.com/secondtonone1/boostasio-learn

热门评论

热门文章

  1. slice介绍和使用

    喜欢(521) 浏览(1717)
  2. Linux环境搭建和编码

    喜欢(594) 浏览(5498)
  3. windows环境搭建和vscode配置

    喜欢(587) 浏览(1711)
  4. 解密定时器的实现细节

    喜欢(566) 浏览(1849)
  5. C++ 类的继承封装和多态

    喜欢(588) 浏览(2574)

最新评论

  1. C++ 类的拷贝构造、赋值运算、单例模式 secondtonone1:好的,已修复。
  2. 双链表实现LRU算法 secondtonone1:双链表插入和删除节点是本篇的难点,多多练习即可。
  3. 线程安全的无锁栈 secondtonone1:谢谢支持,如果pop的次数大于push的次数是会让线程处于重试的,这个是测试用例,必须满足push和pop的次数相同,实际情况不会这么使用。栈的设计没有问题。
  4. 再谈单例模式 secondtonone1:是的,C++11以后返回局部static变量对象能保证线程安全了。
  5. Linux环境搭建和编码 恋恋风辰:Linux环境下go的安装比较简单,可以不用设置GOPATH环境变量,后期我们学习go mod 之后就拜托了go文件目录的限制了。

个人公众号

个人微信