这篇文章上次修改于 903 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
1 介绍
2 示例
2.1 项目结构
grpc
├── helloworld
│ ├── BUILD
│ ├── greeter_client.cc
│ ├── greeter_server.cc
│ └── proto
│ ├── BUILD
│ └── helloworld.proto
└── WORKSPACE
2.2 源码
helloworld/proto/helloworld.proto:定义要传输的消息
// 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. syntax = "proto3"; package helloworld; // The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. message HelloRequest { string name = 1; } // The response message containing the greetings message HelloReply { string message = 1; }
helloworld/proto/BUILD:生成 c++ 格式的头文件
# Copyright 2020 the 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. package(default_visibility = ["//visibility:public"]) load("@rules_proto//proto:defs.bzl", "proto_library") load("@com_github_grpc_grpc//bazel:cc_grpc_library.bzl", "cc_grpc_library") load("@com_github_grpc_grpc//bazel:grpc_build_system.bzl", "grpc_proto_library") # The following three rules demonstrate the usage of the cc_grpc_library rule in # in a mode compatible with the native proto_library and cc_proto_library rules. proto_library( name = "helloworld_proto", srcs = ["helloworld.proto"], ) cc_proto_library( name = "helloworld_cc_proto", deps = [":helloworld_proto"], ) cc_grpc_library( name = "helloworld_cc_grpc", srcs = [":helloworld_proto"], deps = [":helloworld_cc_proto"], grpc_only = True, )
helloword/greeter_server.cc
/* * * 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 <grpcpp/health_check_service_interface.h> #include "helloworld/proto/helloworld.grpc.pb.h" using grpc::Server; using grpc::ServerBuilder; using grpc::ServerContext; using grpc::Status; using helloworld::Greeter; using helloworld::HelloReply; using helloworld::HelloRequest; // 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("Hello "); reply->set_message(prefix + request->name()); return Status::OK; } }; void RunServer() { std::string server_address("0.0.0.0:50051"); GreeterServiceImpl service; grpc::EnableDefaultHealthCheckService(true); 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; }
helloword/greeter_client.cc
/* * * 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 "helloworld/proto/helloworld.grpc.pb.h" using grpc::Channel; using grpc::ClientContext; using grpc::Status; using helloworld::Greeter; using helloworld::HelloReply; using helloworld::HelloRequest; class GreeterClient { public: GreeterClient(std::shared_ptr<Channel> channel) : stub_(Greeter::NewStub(channel)) {} // Assembles the client's payload, sends it and presents the response back // from the server. std::string SayHello(const std::string& user) { // Data we are sending to the server. HelloRequest request; request.set_name(user); // Container for the data we expect from the server. HelloReply 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_->SayHello(&context, request, &reply); // Act upon its status. if (status.ok()) { return reply.message(); } else { std::cout << status.error_code() << ": " << status.error_message() << std::endl; return "RPC failed"; } } private: std::unique_ptr<Greeter::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 = "localhost:50051"; GreeterClient greeter( grpc::CreateChannel(target_str, grpc::InsecureChannelCredentials())); std::string user("world"); std::string reply = greeter.SayHello(user); std::cout << "Greeter received: " << reply << std::endl; return 0; }
helloword/BUILD
# Copyright 2020 the 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. package(default_visibility = ["//visibility:public"]) load("@rules_cc//cc:defs.bzl", "cc_proto_library") load("@rules_proto//proto:defs.bzl", "proto_library") cc_binary( name = "greeter-client", srcs = ["greeter_client.cc"], deps = [ "@com_github_grpc_grpc//:grpc++", "//helloworld/proto:helloworld_cc_grpc", ], ) cc_binary( name = "greeter-server", srcs = ["greeter_server.cc"], deps = [ "@com_github_grpc_grpc//:grpc++", "//helloworld/proto:helloworld_cc_grpc", ], )
WORKSPACE:下载相关依赖
workspace(name = "example") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "rules_proto", sha256 = "602e7161d9195e50246177e7c55b2f39950a9cf7366f74ed5f22fd45750cd208", strip_prefix = "rules_proto-97d8af4dc474595af3900dd85cb3a29ad28cc313", urls = [ "https://mirror.bazel.build/github.com/bazelbuild/rules_proto/archive/97d8af4dc474595af3900dd85cb3a29ad28cc313.tar.gz", "https://github.com/bazelbuild/rules_proto/archive/97d8af4dc474595af3900dd85cb3a29ad28cc313.tar.gz", ], ) load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains") rules_proto_dependencies() rules_proto_toolchains() http_archive( name = "com_google_protobuf", strip_prefix = "protobuf-3.10.1", sha256 = "d7cfd31620a352b2ee8c1ed883222a0d77e44346643458e062e86b1d069ace3e", urls = [ "https://release.mad.st.meituan.com/bazel/deps/protobuf-all-3.10.1.tar.gz", "https://release.mad.st.sankuai.com/bazel/deps/protobuf-all-3.10.1.tar.gz" ] ) http_archive( name = "com_github_grpc_grpc", sha256 = "393d5abc343db59b4d27b18819718bcd61f9c313f2ada35fb63992780d09d693", strip_prefix = "grpc-1.28.1", urls = [ "https://release.mad.st.meituan.com/bazel/deps/grpc_deps/grpc-1.28.1-v1.tar.gz", "https://release.mad.st.sankuai.com/bazel/deps/grpc_deps/grpc-1.28.1-v1.tar.gz", ], ) load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps") grpc_deps() load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps") grpc_extra_deps()
2.3 运行结果
服务端:
$ ./bazel-bin/helloworld/greeter-server
Server listening on 0.0.0.0:50051
客户端:
$ ./bazel-bin/helloworld/greeter-client
Greeter received: Hello world
没有评论