{"id":7022,"date":"2023-01-29T11:50:52","date_gmt":"2023-01-29T03:50:52","guid":{"rendered":"https:\/\/yanjingang.com\/blog\/?p=7022"},"modified":"2023-06-26T17:52:28","modified_gmt":"2023-06-26T09:52:28","slug":"grpc%e6%a6%82%e8%bf%b0","status":"publish","type":"post","link":"https:\/\/yanjingang.com\/blog\/?p=7022","title":{"rendered":"gRPC\u6982\u8ff0"},"content":{"rendered":"<p>gRPC\u662f\u7531 google\u5f00\u53d1\u7684\u4e00\u6b3e\u9ad8\u6027\u80fd\u5f00\u6e90\u8fdc\u7a0b\u8fc7\u7a0b\u8c03\u7528(RPC)\u6846\u67b6\uff0c\u4e3b\u8981\u9762\u5411\u9ad8\u6027\u80fdC\/S\u6a21\u5f0f\u5e94\u7528\u573a\u666f\uff0c\u57fa\u4e8eHTTP\/2\u534f\u8bae\u6807\u51c6\u8bbe\u8ba1\uff0c\u652f\u6301\u5e38\u89c1\u7684\u5404\u7c7b\u7f16\u7a0b\u8bed\u8a00\u3002<\/p>\n<h1>\u4e00\u3001\u6982\u8ff0<\/h1>\n<h3>1\u3001RPC<\/h3>\n<p>RPC\uff08Remote Procedure Call\uff09\u5373\u8fdc\u7a0b\u8fc7\u7a0b\u8c03\u7528\uff0c\u91c7\u7528\u5ba2\u6237\u7aef-\u670d\u52a1\u7aef\uff08Client\/Server\uff09\u6a21\u5f0f\u3002\u5e38\u89c1\u7684RPC\u6846\u67b6\u6709Google\u7684gRPC\u3001Facebook\u7684Thrift\u3001Baidu\u7684bRPC\u7b49\u3002<\/p>\n<p><a href=\"https:\/\/yanjingang.com\/blog\/wp-content\/uploads\/2023\/01\/rpc.jpeg\"><img loading=\"lazy\" class=\"alignnone size-full wp-image-7026\" src=\"https:\/\/yanjingang.com\/blog\/wp-content\/uploads\/2023\/01\/rpc.jpeg\" alt=\"\" width=\"500\" height=\"314\" srcset=\"https:\/\/yanjingang.com\/blog\/wp-content\/uploads\/2023\/01\/rpc.jpeg 500w, https:\/\/yanjingang.com\/blog\/wp-content\/uploads\/2023\/01\/rpc-300x188.jpeg 300w\" sizes=\"(max-width: 500px) 100vw, 500px\" \/><\/a><\/p>\n<p>\u4ece\u5e7f\u4e49\u89d2\u5ea6\u6765\u8bf4\uff0c\u6240\u6709\u672c\u8eab\u5e94\u7528\u7a0b\u5e8f\u4e4b\u5916\u7684\u8c03\u7528\u90fd\u53ef\u4ee5\u5f52\u7c7b\u4e3aRPC\u8c03\u7528\uff0c\u65e0\u8bba\u662f\u5fae\u670d\u52a1\u3001\u7b2c\u4e09\u65b9HTTP\u63a5\u53e3\uff0c\u8fd8\u662f\u8bfb\u5199\u6570\u636e\u5e93\u4e2d\u95f4\u4ef6Mysql\u3001Redis\u7b49\u3002<\/p>\n<h3>2\u3001gRPC<\/h3>\n<p>gRPC\u4e0e\u5e38\u89c1\u7684rpc\u6846\u67b6\u7c7b\u4f3c\uff0c\u4e3b\u8981\u57fa\u4e8e\u5b9a\u4e49\u670d\u52a1\u7684\u8bbe\u8ba1\u601d\u8def\uff0c\u901a\u8fc7IDL\u9884\u5148\u5b9a\u4e49\u670d\u52a1\u540d\u79f0\u3001\u65b9\u6cd5\u540d\u79f0\/\u53c2\u6570\/\u8fd4\u56de\u503c\uff0c\u5e76\u751f\u6210\u5bf9\u5e94\u7684\u670d\u52a1\u7aef\u548c\u5ba2\u6237\u7aef\u4ee3\u7801\uff0c\u518d\u5bf9\u670d\u52a1\u7aef\u65b9\u6cd5\u8fdb\u884c\u5b9e\u73b0\u540e\u5373\u53ef\u65b9\u4fbf\u7684\u8fdb\u884c\u8fdc\u7a0b\u8c03\u7528\u3002<\/p>\n<p><a href=\"https:\/\/yanjingang.com\/blog\/wp-content\/uploads\/2023\/01\/grpc.png\"><img loading=\"lazy\" class=\"alignnone size-full wp-image-7025\" src=\"https:\/\/yanjingang.com\/blog\/wp-content\/uploads\/2023\/01\/grpc.png\" alt=\"\" width=\"514\" height=\"330\" srcset=\"https:\/\/yanjingang.com\/blog\/wp-content\/uploads\/2023\/01\/grpc.png 514w, https:\/\/yanjingang.com\/blog\/wp-content\/uploads\/2023\/01\/grpc-300x193.png 300w\" sizes=\"(max-width: 514px) 100vw, 514px\" \/><\/a><\/p>\n<p>grpc\u9ed8\u8ba4\u4f7f\u7528protocol buffers\u4f5c\u4e3a\u63cf\u8ff0\u670d\u52a1\u63a5\u53e3\u63cf\u8ff0\u548c\u6d88\u606f\u683c\u5f0f\u5b9a\u4e49\u7684\u8bed\u8a00\uff08IDL\uff09\uff0c\u5982\u9700\u8981\u4e5f\u53ef\u4ee5\u4f7f\u7528\u5176\u4ed6IDL\u4ee3\u66ff\u3002<\/p>\n<p>\u6e90\u4ee3\u7801\uff1ahttps:\/\/github.com\/grpc\/grpc.git<\/p>\n<h3>3\u3001\u4f18\u7f3a\u70b9<\/h3>\n<h6>gRPC\u4f18\u52bf\uff1a<\/h6>\n<ul>\n<li>\u652f\u6301\u591a\u79cd\u8bed\u8a00\uff1aC++\u3001Java\u3001Go\u3001Python\u3001Ruby\u3001C#\u3001Node.js\u3001Android Java\u3001Objective-C\u3001PHP\u7b49\uff1b<\/li>\n<li>\u57fa\u4e8e IDL \uff08Interface Define Language)\u63a5\u53e3\u5b9a\u4e49\u8bed\u8a00\u5b9a\u4e49\u670d\u52a1\uff0c\u901a\u8fc7 proto3 \u5de5\u5177\u751f\u6210\u6307\u5b9a\u8bed\u8a00\u7684\u6570\u636e\u7ed3\u6784\u3001\u670d\u52a1\u7aef\u63a5\u53e3\u4ee5\u53ca\u5ba2\u6237\u7aef Stub\uff0c\u4f20\u8f93\u6570\u636e\u66f4\u5c0f\u3001\u66f4\u5feb\uff0c\u4f7f\u7528\u66f4\u7b80\u5355\uff1b<\/li>\n<li>\u901a\u4fe1\u534f\u8bae\u57fa\u4e8e\u6807\u51c6 HTTP\/2 \u8bbe\u8ba1\uff0c\u652f\u6301\u6d88\u606f\u5934\u538b\u7f29\u3001\u5355 TCP \u7684\u591a\u8def\u590d\u7528\u3001\u670d\u52a1\u7aef\u63a8\u9001\u3001\u53cc\u5411\u6d41\u7b49\u7279\u6027\uff0c\u4f7f\u5f97 gRPC \u5728\u79fb\u52a8\u7aef\u8bbe\u5907\u4e0a\u66f4\u52a0\u7701\u7535\u548c\u8282\u7701\u7f51\u7edc\u6d41\u91cf\uff1b<\/li>\n<li>\u5e8f\u5217\u5316\u652f\u6301 PB\uff08Protocol Buffer\uff09\u548c JSON\uff0cPB \u662f\u4e00\u79cd\u8bed\u8a00\u65e0\u5173\u7684\u9ad8\u6027\u80fd\u5e8f\u5217\u5316\u6846\u67b6\uff0c\u57fa\u4e8e HTTP\/2 + PB, \u4fdd\u969c\u4e86 RPC \u8c03\u7528\u7684\u9ad8\u6027\u80fd\uff1b<\/li>\n<li>\u5b89\u88c5\u7b80\u5355\uff0c\u6269\u5c55\u65b9\u4fbf\uff08\u7528\u8be5\u6846\u67b6\u6bcf\u79d2\u53ef\u8fbe\u5230\u767e\u4e07\u4e2aRPC\uff09<\/li>\n<\/ul>\n<p><a href=\"https:\/\/yanjingang.com\/blog\/wp-content\/uploads\/2023\/01\/http2.jpeg\"><img loading=\"lazy\" class=\"alignnone size-full wp-image-7027\" src=\"https:\/\/yanjingang.com\/blog\/wp-content\/uploads\/2023\/01\/http2.jpeg\" alt=\"\" width=\"625\" height=\"324\" srcset=\"https:\/\/yanjingang.com\/blog\/wp-content\/uploads\/2023\/01\/http2.jpeg 625w, https:\/\/yanjingang.com\/blog\/wp-content\/uploads\/2023\/01\/http2-300x156.jpeg 300w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><\/a><\/p>\n<h6>gRPC\u4e0d\u8db3\uff1a<\/h6>\n<ul>\n<li>\u957f\u8fde\u63a5\u6d41\u91cf\u4e0d\u6613\u8c03\u5ea6\uff0c\u4e0d\u80fd\u5f88\u597d\u7684\u652f\u6301\u8d1f\u8f7d\u5747\u8861<\/li>\n<li data-pid=\"PxcJUnG_\">\u4e0d\u652f\u6301\u6d4f\u89c8\u5668\u8bf7\u6c42<\/li>\n<li data-pid=\"PxcJUnG_\">\u4e0d\u652f\u6301\uff11\u5bf9\u591a\u5e7f\u64ad<\/li>\n<\/ul>\n<h6>gRPC\u4e0eREST API\u7684\u4e3b\u8981\u533a\u522b\uff1a<\/h6>\n<ul>\n<li>\u6570\u636e\/\u8d1f\u8f7d\uff1ajson\u6587\u672c,\u5927,\u53ef\u8bfb\u00a0 -&gt; pb\u538b\u7f29\u4e8c\u8fdb\u5236,\u5c0f,\u4e0d\u53ef\u8bfb<\/li>\n<li>\u4f20\u8f93\u534f\u8bae\uff1aHTTP -&gt; HTTP\/2<\/li>\n<li>\u4ee3\u7801\u751f\u6210\uff1a\u4e0d\u652f\u6301 -&gt; \u652f\u6301<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h1 style=\"margin-top: 1.71429rem; margin-bottom: 1.71429rem;\">\u4e8c\u3001\u7f16\u8bd1\u5b89\u88c5<\/h1>\n<pre class=\"pure-highlightjs\"><code class=\"\"># \u5b89\u88c5\u4f9d\u8d56\r\nsudo apt install -y cmake build-essential autoconf libtool pkg-config\r\n# \u4e0b\u8f7d\u6e90\u7801 (v1.46\u662f\u6700\u540e\u4e00\u4e2a\u652f\u6301c++11\u7f16\u8bd1\u7684\u7248\u672c)\r\ngit clone --recurse-submodules -b v1.46.7 --depth 1 --shallow-submodules https:\/\/github.com\/grpc\/grpc\r\n# \u7f16\u8bd1\u5b89\u88c5\r\nmkdir -p grpc\/cmake\/build &amp;&amp; cd grpc\/cmake\/build\r\ncmake -DgRPC_INSTALL=ON -DgRPC_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR ..\/..\r\nmake\r\nsudo make install\r\nldconfig\r\n\r\n# \u793a\u4f8b\u7f16\u8bd1\r\ncd examples\/cpp\/helloworld\r\nmkdir -p cmake\/build &amp;&amp; cd cmake\/build\r\ncmake ..\/..\r\nmake\r\n\r\n# \u793a\u4f8b\u6d4b\u8bd5\r\n.\/greeter_server\r\n.\/greeter_client\r\n    Greeter received: Hello world<\/code><\/pre>\n<p>&nbsp;<\/p>\n<h1 style=\"margin-top: 1.71429rem; margin-bottom: 1.71429rem;\">\u4e09\u3001\u5b9e\u4f8b<\/h1>\n<h3>1\u3001\u670d\u52a1\u5b9a\u4e49<\/h3>\n<p>\u5b9a\u4e49\u4e00\u4e2arobot\u670d\u52a1\uff0c\u5305\u542bHello\u65b9\u6cd5\uff0c\u5e76\u5b9a\u4e49\u53c2\u6570\u548c\u8fd4\u56de\u503c\u683c\u5f0f\uff1a<\/p>\n<pre class=\"pure-highlightjs\"><code class=\"\">$ vim  protos\/robot_service.proto\r\n\r\nsyntax = \"proto3\";\r\n\r\npackage robot_service;\r\n\r\n\/\/ \u670d\u52a1\u548c\u65b9\u6cd5\u5b9a\u4e49\r\nservice Robot {\r\n  rpc Hello (HelloRequest) returns (HelloReply) {}\r\n\r\n  rpc HelloStreamReply (HelloRequest) returns (stream HelloReply) {}\r\n}\r\n\r\n\/\/ \u53c2\u6570\u5b9a\u4e49\r\nmessage HelloRequest {\r\n  string name = 1;\r\n}\r\n\r\n\/\/ \u8fd4\u56de\u503c\u5b9a\u4e49\r\nmessage HelloReply {\r\n  string message = 1;\r\n}\r\n<\/code><\/pre>\n<h3>2\u3001\u751f\u6210\u670d\u52a1\u7aef\/\u5ba2\u6237\u7aef\u4ee3\u7801<\/h3>\n<p>\u4f7f\u7528cmake\u7f16\u8bd1.proto\u6587\u4ef6\uff1a<\/p>\n<pre class=\"pure-highlightjs\"><code class=\"\">$ vim CMakeLists.txt\r\n\r\ncmake_minimum_required(VERSION 3.8)\r\n\r\nproject(TestGrpc C CXX)\r\n\r\n# Common set\r\nfind_package(Threads REQUIRED)\r\nfind_package(Protobuf CONFIG REQUIRED)\r\nmessage(STATUS \"Using protobuf ${Protobuf_VERSION}\")\r\nfind_package(gRPC CONFIG REQUIRED)\r\nmessage(STATUS \"Using gRPC ${gRPC_VERSION}\")\r\nset(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)\r\nset(_REFLECTION gRPC::grpc++_reflection)\r\nset(_PROTOBUF_PROTOC $&lt;TARGET_FILE:protobuf::protoc&gt;)\r\nset(_GRPC_GRPCPP gRPC::grpc++)\r\nset(_GRPC_CPP_PLUGIN_EXECUTABLE $&lt;TARGET_FILE:gRPC::grpc_cpp_plugin&gt;)\r\n\r\n\r\n# Proto file\r\nget_filename_component(serv_proto \"protos\/robot_service.proto\" ABSOLUTE)\r\nget_filename_component(serv_proto_path \"${serv_proto}\" PATH)\r\n# Generated sources\r\nset(serv_proto_srcs \"${CMAKE_CURRENT_BINARY_DIR}\/robot_service.pb.cc\")\r\nset(serv_proto_hdrs \"${CMAKE_CURRENT_BINARY_DIR}\/robot_service.pb.h\")\r\nset(serv_grpc_srcs \"${CMAKE_CURRENT_BINARY_DIR}\/robot_service.grpc.pb.cc\")\r\nset(serv_grpc_hdrs \"${CMAKE_CURRENT_BINARY_DIR}\/robot_service.grpc.pb.h\")\r\nadd_custom_command(\r\n      OUTPUT \"${serv_proto_srcs}\" \"${serv_proto_hdrs}\" \"${serv_grpc_srcs}\" \"${serv_grpc_hdrs}\"\r\n      COMMAND ${_PROTOBUF_PROTOC}\r\n      ARGS --grpc_out \"${CMAKE_CURRENT_BINARY_DIR}\"\r\n        --cpp_out \"${CMAKE_CURRENT_BINARY_DIR}\"\r\n        -I \"${serv_proto_path}\"\r\n        --plugin=protoc-gen-grpc=\"${_GRPC_CPP_PLUGIN_EXECUTABLE}\"\r\n        \"${serv_proto}\"\r\n      DEPENDS \"${serv_proto}\")\r\n\r\n$ mkdir build &amp;&amp; cd build\r\n$ cmake .. &amp;&amp; make<\/code><\/pre>\n<p>\u751f\u6210\u7684\u4ee3\u7801\uff1a<\/p>\n<pre class=\"pure-highlightjs\"><code class=\"\">$ tree\r\n\u251c\u2500\u2500 CMakeCache.txt\r\n\u251c\u2500\u2500 libserv_grpc_proto.a\r\n\u251c\u2500\u2500 Makefile\r\n\u251c\u2500\u2500 robot_client\r\n\u251c\u2500\u2500 robot_server\r\n\u251c\u2500\u2500 robot_service.grpc.pb.cc\r\n\u251c\u2500\u2500 robot_service.grpc.pb.h\r\n\u251c\u2500\u2500 robot_service.pb.cc\r\n\u2514\u2500\u2500 robot_service.pb.h<\/code><\/pre>\n<p>\u901a\u8fc7robot_service.grpc.pb.h\u5934\u6587\u4ef6\u53ef\u4ee5\u770b\u5230\u670d\u52a1\u7aef\u7c7b\u4e3aRobot::Service\uff0c\u5ba2\u6237\u7aef\u7c7b\u4e3aRobot::Stub\u3002<\/p>\n<h3>3\u3001\u65b9\u6cd5\u5b9e\u73b0<\/h3>\n<p>\u670d\u52a1\u7aef\u4ee3\u7801\uff1a<\/p>\n<pre class=\"pure-highlightjs\"><code class=\"\">$ vim robot_server.cc\r\n\r\n#include &lt;iostream&gt;\r\n#include &lt;memory&gt;\r\n#include &lt;string&gt;\r\n\r\n#include &lt;grpcpp\/ext\/proto_server_reflection_plugin.h&gt;\r\n#include &lt;grpcpp\/grpcpp.h&gt;\r\n#include &lt;grpcpp\/health_check_service_interface.h&gt;\r\n\r\n#include \"robot_service.grpc.pb.h\"\r\n\r\nusing grpc::Server;\r\nusing grpc::ServerBuilder;\r\nusing grpc::ServerContext;\r\nusing grpc::Status;\r\nusing robot_service::Robot;\r\nusing robot_service::HelloReply;\r\nusing robot_service::HelloRequest;\r\n\r\n\/\/ \u670d\u52a1\u7aef\u65b9\u6cd5\u5b9e\u73b0\r\nclass RobotServiceImpl final : public Robot::Service {\r\n  Status Hello(ServerContext* context, const HelloRequest* request,\r\n                  HelloReply* reply) override {\r\n    std::string prefix(\"hello \");\r\n    reply-&gt;set_message(prefix + request-&gt;name());\r\n    return Status::OK;\r\n  }\r\n};\r\n\r\nvoid StartServer() {\r\n  \/\/ \u542f\u7528\u9ed8\u8ba4\u7684\u5065\u5eb7\u68c0\u67e5\u670d\u52a1\r\n  grpc::EnableDefaultHealthCheckService(true);\r\n  \/\/ \u521d\u59cb\u5316\u670d\u52a1\u5668\u53cd\u5c04\uff0c\u65b9\u4fbf\u5728\u8fd0\u884c\u65f6\u83b7\u53d6\u6709\u5173gRPC\u670d\u52a1\u7684\u4fe1\u606f\r\n  grpc::reflection::InitProtoReflectionServerBuilderPlugin();\r\n\r\n  \/\/ \u6ce8\u518c\u5e76\u542f\u52a8\u670d\u52a1\r\n  std::string server_address(\"0.0.0.0:60061\");\r\n  RobotServiceImpl service;\r\n  ServerBuilder builder;  \/\/ \u7528\u4e8e\u521b\u5efa\u548c\u542f\u52a8grpc::Server\u5b9e\u4f8b\u7684\u6784\u5efa\u5668\u7c7b\r\n  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());  \/\/ \u767b\u8bb0\u670d\u52a1\u76d1\u542c\u5730\u5740\u4ee5\u7ed1\u5b9a\u8981\u521b\u5efa\u7684grpc::Server\u5bf9\u8c61\uff08\u5728\u6ca1\u6709\u4efb\u4f55\u8eab\u4efd\u9a8c\u8bc1\u673a\u5236\u7684\u60c5\u51b5\u4e0b\uff09\r\n  builder.RegisterService(&amp;service);  \/\/ \u6ce8\u518c\u670d\u52a1\u5b9e\u4f8b\r\n  std::unique_ptr&lt;Server&gt; server(builder.BuildAndStart());  \/\/\u8fd4\u56de\u51c6\u5907\u597d\u5904\u7406\u8c03\u7528\u7684\u6b63\u5728\u8fd0\u884c\u7684\u670d\u52a1\u5668\r\n  std::cout &lt;&lt; \"Server listening on \" &lt;&lt; server_address &lt;&lt; std::endl;\r\n\r\n  \/\/ \u7b49\u5f85\u670d\u52a1\u5668\u5173\u95ed\uff08\u5fc5\u987b\u6709\u5176\u4ed6\u7ebf\u7a0b\u8d1f\u8d23\u5173\u95ed\u670d\u52a1\u5668\uff0c\u624d\u80fd\u4f7f\u6b64\u8c03\u7528\u8fd4\u56de\uff09\r\n  server-&gt;Wait();\r\n}\r\n\r\nint main(int argc, char** argv) {\r\n  StartServer();\r\n\r\n  return 0;\r\n}\r\n<\/code><\/pre>\n<p>\u5ba2\u6237\u7aef\u4ee3\u7801\u5b9e\u73b0\uff1a<\/p>\n<pre class=\"pure-highlightjs\"><code class=\"\">$ vim robot_client.cc\r\n\r\n#include &lt;iostream&gt;\r\n#include &lt;memory&gt;\r\n#include &lt;string&gt;\r\n\r\n#include &lt;grpcpp\/grpcpp.h&gt;\r\n\r\n#include \"robot_service.grpc.pb.h\"\r\n\r\nusing grpc::Channel;\r\nusing grpc::ClientContext;\r\nusing grpc::Status;\r\nusing robot_service::Robot;\r\nusing robot_service::HelloReply;\r\nusing robot_service::HelloRequest;\r\n\r\nclass RobotClient {\r\n public:\r\n  \/\/ \u4f7f\u7528proto\u751f\u6210\u7684\u7c7bNewStub\u65b9\u6cd5\u521b\u5efa\u5ba2\u6237\u7aef\r\n  RobotClient(std::shared_ptr&lt;Channel&gt; channel)\r\n      : stub_(Robot::NewStub(channel)) {}\r\n\r\n  \/\/ \u53d1\u9001\u5ba2\u6237\u7aef\u8bf7\u6c42\r\n  std::string Hello(const std::string&amp; user) {\r\n    \/\/ \u7ec4\u7ec7\u53c2\u6570\u548c\u8fd4\u56de\u503c\r\n    HelloRequest request;\r\n    request.set_name(user);\r\n    HelloReply reply; \/\/ \u8fd4\u56de\u503c\r\n    ClientContext context;  \/\/ \u5ba2\u6237\u7aef\u4e0a\u4e0b\u6587\r\n\r\n    \/\/ \u53d1\u9001\u8bf7\u6c42\r\n    Status status = stub_-&gt;Hello(&amp;context, request, &amp;reply);\r\n\r\n    \/\/ \u8fd4\u56de\u503c\u5904\u7406\r\n    if (status.ok()) {\r\n      return reply.message();\r\n    } else {\r\n      std::cout &lt;&lt; status.error_code() &lt;&lt; \": \" &lt;&lt; status.error_message() &lt;&lt; std::endl;\r\n      return \"RPC failed\";\r\n    }\r\n  }\r\n\r\n private:\r\n  std::unique_ptr&lt;Robot::Stub&gt; stub_;\r\n};\r\n\r\n\r\nint main(int argc, char** argv) {\r\n  \/\/ \u5b9e\u4f8b\u5316\u5ba2\u6237\u7aef\r\n  std::string target_str(\"localhost:60061\");\r\n  RobotClient robot(grpc::CreateChannel(target_str, grpc::InsecureChannelCredentials())); \/\/ \u6682\u4e0d\u4f7f\u7528\u8eab\u4efd\u9a8c\u8bc1\r\n  \/\/ \u53d1\u9001\u8bf7\u6c42\r\n  std::string user(\"mars\");\r\n  std::string reply = robot.Hello(user);\r\n  std::cout &lt;&lt; \"Client received: \" &lt;&lt; reply &lt;&lt; std::endl;\r\n\r\n  return 0;\r\n}\r\n<\/code><\/pre>\n<h3>4\u3001\u6d4b\u8bd5<\/h3>\n<p>\u4e3a\u5ba2\u6237\u7aef\u6dfb\u52a0CMake\u7f16\u8bd1\u8bbe\u7f6e\uff1a<\/p>\n<pre class=\"pure-highlightjs\"><code class=\"\">vim CMakeLists.txt\r\n\r\n...\r\n\r\n# serv_grpc_proto\r\nadd_library(serv_grpc_proto\r\n  ${serv_grpc_srcs}\r\n  ${serv_grpc_hdrs}\r\n  ${serv_proto_srcs}\r\n  ${serv_proto_hdrs})\r\ntarget_link_libraries(serv_grpc_proto\r\n  ${_REFLECTION}\r\n  ${_GRPC_GRPCPP}\r\n  ${_PROTOBUF_LIBPROTOBUF})\r\n\r\n# Targets robot_[async_](client|server)\r\nforeach(_target\r\n  robot_client robot_server \r\n  )\r\n  add_executable(${_target} \"${_target}.cc\")\r\n  target_link_libraries(${_target}\r\n    serv_grpc_proto\r\n    ${_REFLECTION}\r\n    ${_GRPC_GRPCPP}\r\n    ${_PROTOBUF_LIBPROTOBUF})\r\nendforeach()\r\n<\/code><\/pre>\n<p>\u7f16\u8bd1\u6d4b\u8bd5\uff1a<\/p>\n<pre class=\"pure-highlightjs\"><code class=\"\"># build\r\n$  mkdir build &amp;&amp; cd build\r\n$  cmake ..\r\n$  make\r\n\r\n# run\r\n$  .\/robot_server\r\nServer listening on 0.0.0.0:60061\r\n $  .\/robot_client\r\nClient received: hello mars<\/code><\/pre>\n<h3>5\u3001\u5f02\u6b65\u6539\u9020<\/h3>\n<p>\u4e0a\u8fb9\u7684\u5b9e\u4f8b\uff0c\u5ba2\u6237\u7aef\u548c\u670d\u52a1\u7aef\u5728\u8c03\u7528\u65f6\u90fd\u662f\u540c\u6b65\u963b\u585e\u7684\uff0c\u63a5\u4e0b\u6765\u6211\u4eec\u628a\u5b83\u6539\u9020\u6210\u5f02\u6b65\u7684\u65b9\u5f0f\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>yan 23.1.29<\/p>\n<p>\u53c2\u8003\uff1a<\/p>\n<p><a href=\"https:\/\/grpc.io\" target=\"_blank\" rel=\"noopener\">grpc.io<\/a><\/p>\n<p><a href=\"https:\/\/gitlab.com\/SiLA2\/sila_cpp\/-\/merge_requests\/20\" target=\"_blank\" rel=\"noopener\">Added explicit dependency to abseil by adding find_package(absl)<\/a><\/p>\n<p><a href=\"https:\/\/www.finclip.com\/blog\/grpc-load-balance\/\" target=\"_blank\" rel=\"noopener\">gRPC \u4e4b\u8d1f\u8f7d\u5747\u8861<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>gRPC\u662f\u7531 google\u5f00\u53d1\u7684\u4e00\u6b3e\u9ad8\u6027\u80fd\u5f00\u6e90\u8fdc\u7a0b\u8fc7\u7a0b\u8c03\u7528(RPC)\u6846\u67b6\uff0c\u4e3b\u8981\u9762\u5411\u9ad8\u6027\u80fdC\/S\u6a21\u5f0f\u5e94\u7528\u573a\u666f\uff0c\u57fa [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1027,1251],"tags":[1253],"_links":{"self":[{"href":"https:\/\/yanjingang.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7022"}],"collection":[{"href":"https:\/\/yanjingang.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/yanjingang.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/yanjingang.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/yanjingang.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7022"}],"version-history":[{"count":3,"href":"https:\/\/yanjingang.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7022\/revisions"}],"predecessor-version":[{"id":7786,"href":"https:\/\/yanjingang.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7022\/revisions\/7786"}],"wp:attachment":[{"href":"https:\/\/yanjingang.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7022"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yanjingang.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7022"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yanjingang.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7022"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}