#include <iostream>
#include <memory>
#include <string>
#include <grpc++/grpc++.h>
#include <grpc++/security/credentials.h>
#include <fstream>
#include "hello.grpc.pb.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using helloworld::HelloRequest;
using helloworld::HelloResponse;
using helloworld::Greeter;
static std::string get_file_contents(const char *fpath)
{
std::ifstream finstream(fpath);
std::string contents((std::istreambuf_iterator<char>(finstream)),
std::istreambuf_iterator<char>());
return contents;
}
// Logic and data behind the server's behavior.
class GreeterServiceImpl final : public Greeter::Service {
Status SayHello(ServerContext* context, const HelloRequest* request,
HelloResponse* reply) override {
std::string prefix("Hello ");
reply->set_message(prefix + request->name());
return Status::OK;
}
};
void RunServer(char** argv) {
std::string server_address("127.0.0.1:50051");
GreeterServiceImpl service;
auto client_ca_pem = get_file_contents(argv[1]); // for verifying clients
auto my_key_pem = get_file_contents(argv[2]);
auto my_cert_pem = get_file_contents(argv[3]);
grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp = {
my_key_pem.c_str(), my_cert_pem.c_str()
};
grpc::SslServerCredentialsOptions ssl_opts(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
ssl_opts.pem_root_certs = client_ca_pem;
ssl_opts.pem_key_cert_pairs.push_back(pkcp);
std::cout << "pem_root_certs length: " << ssl_opts.pem_root_certs.length() << std::endl;
std::shared_ptr<grpc::ServerCredentials> creds = grpc::SslServerCredentials(ssl_opts);
ServerBuilder builder;
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, creds);
// 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(argv);
return 0;
}
3、gRPC 客户端实现
#include <iostream>
#include <memory>
#include <string>
#include <grpc++/grpc++.h>
#include <grpc++/security/credentials.h>
#include <fstream>
#include "hello.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using helloworld::HelloRequest;
using helloworld::HelloResponse;
using helloworld::Greeter;
static std::string get_file_contents(const char *fpath)
{
std::ifstream finstream(fpath);
std::string contents((std::istreambuf_iterator<char>(finstream)),
std::istreambuf_iterator<char>());
return contents;
}
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.
HelloResponse 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 (in this case,
// localhost at port 50051). We indicate that the channel isn't authenticated
// (use of InsecureChannelCredentials()).
assert (argc == 4);
auto server_ca_pem = get_file_contents(argv[1]);
auto my_key_pem = get_file_contents(argv[2]);
auto my_cert_pem = get_file_contents(argv[3]);
grpc::SslCredentialsOptions ssl_opts;
ssl_opts.pem_root_certs = server_ca_pem;
ssl_opts.pem_private_key = my_key_pem;
ssl_opts.pem_cert_chain = my_cert_pem;
std::shared_ptr<grpc::ChannelCredentials> creds = grpc::SslCredentials(ssl_opts);
grpc::ChannelArguments channel_args;
channel_args.SetSslTargetNameOverride("foo.test.google.fr");
GreeterClient greeter(grpc::CreateCustomChannel("localhost:50051", creds, channel_args));
// GreeterClient greeter(grpc::CreateChannel(
// "localhost:50051", creds));
std::string user("world");
std::string reply = greeter.SayHello(user);
std::cout << "Greeter received: " << reply << std::endl;
return 0;
}