打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
gRPC简介及简单使用(C++)

gRPC是一个现代的、开源的、高性能远程过程调用(RPC)框架,可以在任何平台运行。gRPC使客户端和服务器端应用程序能够透明地进行通信,并简化了连接系统的构建。gRPC支持的语言包括C++、Ruby、Python、Java、Go等。

gRPC默认使用Google的Protocol Buffers,关于Protocol Buffers的介绍可以参考:https://blog.csdn.net/fengbingchun/article/details/49977903

gRPC的源码在https://github.com/grpc/grpc,最新版本的版本为v1.23.0,它的license是Apache-2.0。

关于RPC(Remote Procedure Call, 远程过程调用)的介绍可以参考:https://blog.csdn.net/fengbingchun/article/details/92406377

关于gRPC的安装可以参考:https://blog.csdn.net/fengbingchun/article/details/100608370

下面参考gRPC官方examples/cpp/helloworld中的同步模式例子,过程如下:

1. 创建IDL(interface definition language)描述文件helloworld.proto,通过protobuf定义服务端与客户端之间的RPC调用接口,通过protoc工具生成客户端和服务端代码。gRPC是需要先定义服务接口约定,才可以进行RPC调用,使用.proto可以同时定义客户端和服务端交换的数据格式以及RPC调用的接口。helloworld.proto文件内容如下:

  1. // Copyright 2015 gRPC authors.

  2. syntax = "proto3";

  3. option java_multiple_files = true;
  4. option java_package = "io.grpc.examples.helloworld";
  5. option java_outer_classname = "HelloWorldProto";
  6. option objc_class_prefix = "HLW";

  7. package helloworld;

  8. // The greeting service definition.
  9. service Greeter {
  10. // Sends a greeting
  11. rpc SayHello (HelloRequest) returns (HelloReply) {}
  12. }

  13. // The request message containing the user's name.
  14. message HelloRequest {
  15. string name = 1;
  16. }

  17. // The response message containing the greetings
  18. message HelloReply {
  19. string message = 1;
  20. }

通过protoc工具生成服务端和客户端代码,执行命令(终端定位在demo/gRGC_Test)如下:

  1. ./../../src/grpc/linux_install/bin/protoc --cpp_out=./ helloworld.proto
  2. ./../../src/grpc/linux_install/bin/protoc --grpc_out=./ --plugin=protoc-gen-grpc=./../../src/grpc/linux_install/bin/grpc_cpp_plugin helloworld.proto

会在当前目录下生成helloworld.pb.h, hellowrold.pb.cc, helloworld.grpc.pb.h, helloworld.grpc.pb.cc四个文件。使用IDL定义服务端方法、参数、返回类型,客户端和服务端都使用从服务端定义生成的接口代码。

2. 编写客户端代码,测试代码函数为test_grpc_client;

3. 编写服务端代码,测试代码函数为test_grpc_server;

  1. #include "funset.hpp"
  2. #include <iostream>
  3. #include <memory>
  4. #include <string>
  5. #include <grpcpp/grpcpp.h>
  6. #include "helloworld.grpc.pb.h"

  7. // reference: grpc/examples/cpp/helloworld
  8. namespace {

  9. class GreeterClient {
  10. public:
  11. GreeterClient(std::shared_ptr<grpc::Channel> channel) : stub_(helloworld::Greeter::NewStub(channel)) {}

  12. // Assembles the client's payload, sends it and presents the response back from the server.
  13. std::string SayHello(const std::string& user) {
  14. // Data we are sending to the server.
  15. helloworld::HelloRequest request;
  16. request.set_name(user);

  17. // Container for the data we expect from the server.
  18. helloworld::HelloReply reply;

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

  21. // The actual RPC.
  22. grpc::Status status = stub_->SayHello(&context, request, &reply);

  23. // Act upon its status.
  24. if (status.ok()) {
  25. return reply.message();
  26. } else {
  27. fprintf(stderr, "error code: %d, error message: %s\n", status.error_code(), status.error_message().c_str());
  28. return "RPC failed";
  29. }
  30. }

  31. private:
  32. std::unique_ptr<helloworld::Greeter::Stub> stub_;
  33. };

  34. } // namespace

  35. int test_grpc_client()
  36. {
  37. fprintf(stdout, "client start\n");
  38. // Instantiate the client. It requires a channel, out of which the actual RPCs are created.
  39. // This channel models a connection to an endpoint (in this case, localhost at port 50051).
  40. // We indicate that the channel isn't authenticated(use of InsecureChannelCredentials()).
  41. GreeterClient greeter(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));
  42. std::string user("world");
  43. std::string reply = greeter.SayHello(user);
  44. fprintf(stdout, "Greeter received: %s\n", reply.c_str());

  45. return 0;
  46. }

  47. namespace {

  48. // Logic and data behind the server's behavior.
  49. class GreeterServiceImpl final : public helloworld::Greeter::Service {
  50. grpc::Status SayHello(grpc::ServerContext* context, const helloworld::HelloRequest* request, helloworld::HelloReply* reply) override {
  51. std::string prefix("Hello ");
  52. reply->set_message(prefix + request->name());
  53. return grpc::Status::OK;
  54. }
  55. };

  56. void RunServer() {
  57. std::string server_address("0.0.0.0:50051");
  58. GreeterServiceImpl service;

  59. grpc::ServerBuilder builder;
  60. // Listen on the given address without any authentication mechanism.
  61. builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
  62. // Register "service" as the instance through which we'll communicate with clients.
  63. // In this case it corresponds to an *synchronous* service.
  64. builder.RegisterService(&service);
  65. // Finally assemble the server.
  66. std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
  67. fprintf(stdout, "Server listening on: %s\n", server_address.c_str());

  68. // Wait for the server to shutdown. Note that some other thread must be
  69. // responsible for shutting down the server for this call to ever return.
  70. server->Wait();
  71. }

  72. } // namespace

  73. int test_grpc_server()
  74. {
  75. fprintf(stdout, "server start\n");
  76. RunServer();

  77. return 0;
  78. }

4. 先在一个终端启动服务端程序,再在另一个终端启动客户端程序,执行结果如下:

GitHubhttps://github.com/fengbingchun/OpenSSL_Test

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
grpc-gateway:grpc转换为http协议对外提供服务
什么是HTTP、RPC 和gRPC 框架 关系如何呢
gRPC搭建使用方式
什么样的 RPC 才是好用的 RPC
Python配置gRPC环境
Spring与Akka的集成
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服