Skip to content

Commit

Permalink
[Dev] Add grpc cpp example
Browse files Browse the repository at this point in the history
  • Loading branch information
lshmouse committed Oct 8, 2024
1 parent a1d8ed1 commit 52fa315
Show file tree
Hide file tree
Showing 10 changed files with 244 additions and 9 deletions.
1 change: 1 addition & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
build --cxxopt=-std=c++17
build --host_cxxopt=-std=c++17

build:clang --repo_env=CC=clang
build:clang --copt=-std=c++17
Expand Down
12 changes: 11 additions & 1 deletion WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,22 @@ pip_install(
requirements = "//bazel/python:requirements.txt",
)


### GRPC Setup
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()

### Gazelle Setup
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")

### Golang Setup
load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
go_rules_dependencies()
go_register_toolchains(version = "1.18")
# duplicate with grpc_extra_deps
# go_register_toolchains(version = "1.18")
gazelle_dependencies()

load("//bazel/go:deps.bzl", "go_dependencies")
Expand Down
41 changes: 41 additions & 0 deletions experimental/grpc_example/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package(default_visibility = ["//visibility:public"])

load("@rules_proto//proto:defs.bzl", "proto_library")
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_proto_library")
load("@com_github_grpc_grpc//bazel:cc_grpc_library.bzl", "cc_grpc_library")

proto_library(
name = "hello_proto",
srcs = ["hello.proto"],
)

cc_proto_library(
name = "hello_cc_proto",
deps = [":hello_proto"],
)

cc_grpc_library(
name = "hello_cc_grpc",
srcs = [":hello_proto"],
grpc_only = True,
deps = [":hello_cc_proto"],
)

cc_binary(
name = "greeter_client",
srcs = ["greeter_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":hello_cc_grpc",
"@com_github_grpc_grpc//:grpc++",
],
)

cc_binary(
name = "greeter_server",
srcs = ["greeter_server.cc"],
deps = [
":hello_cc_grpc",
"@com_github_grpc_grpc//:grpc++",
],
)
92 changes: 92 additions & 0 deletions experimental/grpc_example/greeter_client.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#include <iostream>
#include <memory>
#include <string>

#include <grpcpp/grpcpp.h>

#include "experimental/grpc_example/hello.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";
}
}

std::string SayHelloAgain(const std::string& user) {
// Follows the same pattern as SayHello.
HelloRequest request;
request.set_name(user);
HelloReply reply;
ClientContext context;

// Here we can use the stub's newly available method we just added.
Status status = stub_->SayHelloAgain(&context, request, &reply);
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) {
std::string address = "localhost";
std::string port = "50051";
std::string server_address = address + ":" + port;
std::cout << "Client querying server address: " << server_address << std::endl;


// 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(
server_address, grpc::InsecureChannelCredentials()));
std::string user("world");

std::string reply = greeter.SayHello(user);
std::cout << "Greeter received: " << reply << std::endl;

reply = greeter.SayHelloAgain(user);
std::cout << "Greeter received: " << reply << std::endl;

return 0;
}
58 changes: 58 additions & 0 deletions experimental/grpc_example/greeter_server.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include <iostream>
#include <memory>
#include <string>

#include <grpcpp/grpcpp.h>

#include "experimental/grpc_example/hello.grpc.pb.h"

using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using helloworld::HelloRequest;
using helloworld::HelloReply;
using helloworld::Greeter;

// 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;
}

Status SayHelloAgain(ServerContext* context, const HelloRequest* request,
HelloReply* reply) override {
std::string prefix("Hello again ");
reply->set_message(prefix + request->name());
return Status::OK;
}
};

void RunServer() {
std::string address = "0.0.0.0";
std::string port = "50051";
std::string server_address = address + ":" + port;
GreeterServiceImpl service;

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;
}
27 changes: 27 additions & 0 deletions experimental/grpc_example/hello.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
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 greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}

// Sends another greeting
rpc SayHelloAgain (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;
}
6 changes: 3 additions & 3 deletions third_party/absl/workspace.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
def repo():
http_archive(
name = "com_google_absl",
sha256 = "6764f226bd6e2d8ab9fe2f3cab5f45fb1a4a15c04b58b87ba7fa87456054f98b",
strip_prefix = "abseil-cpp-273292d1cfc0a94a65082ee350509af1d113344d",
sha256 = "f4871f2982e29496f4ddd598ccd5a87fea42f23c49b5e5eb459d57eab91df9d9",
strip_prefix = "abseil-cpp-29bf8085f3bf17b84d30e34b3d7ff8248fda404e",
urls = [
"https://github.com/abseil/abseil-cpp/archive/273292d1cfc0a94a65082ee350509af1d113344d.zip"
"https://github.com/abseil/abseil-cpp/archive/29bf8085f3bf17b84d30e34b3d7ff8248fda404e.zip"
],
)
6 changes: 6 additions & 0 deletions third_party/grpc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## GRPC

### References
- [gRPC](https://grpc.io/)
- https://github.com/grpc/grpc/tree/master/examples/cpp
- https://github.com/grpc/grpc-java
4 changes: 2 additions & 2 deletions third_party/grpc/workspace.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ def clean_dep(dep):
return str(Label(dep))

def repo():
version = "1.45.2"
version = "1.59.5"
http_archive(
name = "com_github_grpc_grpc",
strip_prefix = "grpc-{}".format(version),
sha256 = "e18b16f7976aab9a36c14c38180f042bb0fd196b75c9fd6a20a2b5f934876ad6",
sha256 = "ad295f118a84d87096fe3eb416ef446d75d44c988eadccebc650656eb9383b3d",
urls = [
"https://github.com/grpc/grpc/archive/v{}.tar.gz".format(version),
],
Expand Down
6 changes: 3 additions & 3 deletions third_party/protobuf/workspace.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

def repo():
version = "3.19.4"
version = "24.4"
http_archive(
name = "com_google_protobuf",
strip_prefix = "protobuf-{}".format(version),
sha256 = "3bd7828aa5af4b13b99c191e8b1e884ebfa9ad371b0ce264605d347f135d2568",
sha256 = "616bb3536ac1fff3fb1a141450fa28b875e985712170ea7f1bfe5e5fc41e2cd8",
urls = [
"https://github.com/protocolbuffers/protobuf/archive/v{}.tar.gz".format(version),
"https://github.com/protocolbuffers/protobuf/releases/download/v{}/protobuf-{}.tar.gz".format(version, version),
],
)

0 comments on commit 52fa315

Please sign in to comment.