gRPC简介及简单使用(C++)
gRPC是一個(gè)現(xiàn)代的、開源的、高性能遠(yuǎn)程過(guò)程調(diào)用(RPC)框架,可以在任何平臺(tái)運(yùn)行。gRPC使客戶端和服務(wù)器端應(yīng)用程序能夠透明地進(jìn)行通信,并簡(jiǎn)化了連接系統(tǒng)的構(gòu)建。gRPC支持的語(yǔ)言包括C++、Ruby、Python、Java、Go等。
gRPC默認(rèn)使用Google的Protocol Buffers,關(guān)于Protocol Buffers的介紹可以參考:https://blog.csdn.net/fengbingchun/article/details/49977903
gRPC的源碼在https://github.com/grpc/grpc,最新版本的版本為v1.23.0,它的license是Apache-2.0。
關(guān)于RPC(Remote Procedure Call, 遠(yuǎn)程過(guò)程調(diào)用)的介紹可以參考:https://blog.csdn.net/fengbingchun/article/details/92406377
關(guān)于gRPC的安裝可以參考:https://blog.csdn.net/fengbingchun/article/details/100608370
下面參考gRPC官方examples/cpp/helloworld中的同步模式例子,過(guò)程如下:
1. 創(chuàng)建IDL(interface definition language)描述文件helloworld.proto,通過(guò)protobuf定義服務(wù)端與客戶端之間的RPC調(diào)用接口,通過(guò)protoc工具生成客戶端和服務(wù)端代碼。gRPC是需要先定義服務(wù)接口約定,才可以進(jìn)行RPC調(diào)用,使用.proto可以同時(shí)定義客戶端和服務(wù)端交換的數(shù)據(jù)格式以及RPC調(diào)用的接口。helloworld.proto文件內(nèi)容如下:
// Copyright 2015 gRPC authors.syntax = "proto3";option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";package helloworld;// The greeting service definition.
service Greeter {// Sends a greetingrpc 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;
}
通過(guò)protoc工具生成服務(wù)端和客戶端代碼,執(zhí)行命令(終端定位在demo/gRGC_Test)如下:
./../../src/grpc/linux_install/bin/protoc --cpp_out=./ helloworld.proto
./../../src/grpc/linux_install/bin/protoc --grpc_out=./ --plugin=protoc-gen-grpc=./../../src/grpc/linux_install/bin/grpc_cpp_plugin helloworld.proto
會(huì)在當(dāng)前目錄下生成helloworld.pb.h, hellowrold.pb.cc, helloworld.grpc.pb.h, helloworld.grpc.pb.cc四個(gè)文件。使用IDL定義服務(wù)端方法、參數(shù)、返回類型,客戶端和服務(wù)端都使用從服務(wù)端定義生成的接口代碼。
2. 編寫客戶端代碼,測(cè)試代碼函數(shù)為test_grpc_client;
3. 編寫服務(wù)端代碼,測(cè)試代碼函數(shù)為test_grpc_server;
#include "funset.hpp"
#include <iostream>
#include <memory>
#include <string>
#include <grpcpp/grpcpp.h>
#include "helloworld.grpc.pb.h"// reference: grpc/examples/cpp/helloworld
namespace {class GreeterClient {
public:GreeterClient(std::shared_ptr<grpc::Channel> channel) : stub_(helloworld::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.helloworld::HelloRequest request;request.set_name(user);// Container for the data we expect from the server.helloworld::HelloReply reply;// Context for the client. It could be used to convey extra information to the server and/or tweak certain RPC behaviors.grpc::ClientContext context;// The actual RPC.grpc::Status status = stub_->SayHello(&context, request, &reply);// Act upon its status.if (status.ok()) {return reply.message();} else {fprintf(stderr, "error code: %d, error message: %s\n", status.error_code(), status.error_message().c_str());return "RPC failed";} } private:std::unique_ptr<helloworld::Greeter::Stub> stub_;
};} // namespaceint test_grpc_client()
{fprintf(stdout, "client start\n");// Instantiate the client. It requires a channel, out of which the actual RPCs are created.// This channel models a connection to an endpoint (in this case, localhost at port 50051).// We indicate that the channel isn't authenticated(use of InsecureChannelCredentials()).GreeterClient greeter(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));std::string user("world");std::string reply = greeter.SayHello(user);fprintf(stdout, "Greeter received: %s\n", reply.c_str());return 0;
}namespace {// Logic and data behind the server's behavior.
class GreeterServiceImpl final : public helloworld::Greeter::Service {grpc::Status SayHello(grpc::ServerContext* context, const helloworld::HelloRequest* request, helloworld::HelloReply* reply) override {std::string prefix("Hello ");reply->set_message(prefix + request->name());return grpc::Status::OK;}
};void RunServer() {std::string server_address("0.0.0.0:50051");GreeterServiceImpl service;grpc::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<grpc::Server> server(builder.BuildAndStart());fprintf(stdout, "Server listening on: %s\n", server_address.c_str());// 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();
}} // namespaceint test_grpc_server()
{fprintf(stdout, "server start\n");RunServer();return 0;
}
4. 先在一個(gè)終端啟動(dòng)服務(wù)端程序,再在另一個(gè)終端啟動(dòng)客戶端程序,執(zhí)行結(jié)果如下:
GitHub:https://github.com/fengbingchun/OpenSSL_Test
總結(jié)
以上是生活随笔為你收集整理的gRPC简介及简单使用(C++)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 在Windows和Linux上编译gRP
- 下一篇: 程序员的自我修养--链接、装载与库笔记: