Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ~~~ means there is more but irrelevant code
- // api.proto
- syntax = "proto3";
- package dev.api;
- service ApiService {
- rpc Call(CallRequest) returns (CallResponse) {}
- rpc ServerStream(SStreamRequest) returns (stream SStreamResponse) {}
- rpc ClientStream(stream CStreamRequest) returns (CStreamResponse) {}
- }
- ~~~
- // service_config.json
- {
- "loadBalancingConfig": [
- {
- "round_robin": {}
- }
- ],
- "methodConfig": [
- {
- "name": [
- {
- "service": {}
- }
- ],
- "retryPolicy": {
- "maxAttempts": 2,
- "initialBackoff": "1s",
- "maxBackoff": "120s",
- "backoffMultiplier": 1.5,
- "retryableStatusCodes": [
- "UNAVAILABLE"
- ]
- }
- }
- ]
- }
- // global.h
- ~~~
- constexpr std::string_view Address = "localhost:5067";
- // https://github.com/grpc/grpc/blob/master/doc/environment_variables.md
- inline void setDebugEnvs()
- {
- setenv("GRPC_DNS_RESOLVER", "ares", 1); // native
- setenv("GRPC_ABORT_ON_LEAKS", "1", 1);
- setenv("GRPC_TRACE",
- "cares_resolver,dns_resolver,"
- "client_channel,round_robin,"
- ,1);
- setenv("GRPC_VERBOSITY", "DEBUG", 1);
- }
- inline std::optional<std::string> readFile(std::string_view path)
- {
- std::ifstream file(path.data());
- if (!file.is_open())
- return std::nullopt;
- return std::string(
- std::istreambuf_iterator<char>{file},
- std::istreambuf_iterator<char>{}
- );
- }
- // main.cpp
- int main()
- {
- setDebugEnvs();
- Server server;
- server.start(Address);
- while (!gSigShutdown) {
- std::this_thread::sleep_for(std::chrono::milliseconds(4000));
- }
- std::cout << "Shutting down server..." << std::endl;
- server.stop();
- return 0;
- }
- // server.cpp
- ~~~
- bool Server::start(std::string_view address)
- {
- std::unique_lock lock(d->mtx);
- if (d->state != ServerPrivate::CREATED)
- return false;
- const auto serviceConfig = readFile("service_config.json");
- if (!serviceConfig)
- return false;
- std::cout << "Configuring Config: \n" << *serviceConfig << '\n';
- const auto valid = grpc::experimental::ValidateServiceConfigJSON(*serviceConfig);
- std::cout << std::format(
- "Valid: {}\n", valid.empty() ? "true" : valid
- );
- {
- grpc::ServerBuilder builder;
- builder.RegisterService(&d->service);
- builder.AddListeningPort(address.data(), d->creds, &d->port);
- builder.AddChannelArgument(GRPC_ARG_SERVICE_CONFIG, *serviceConfig);
- d->cq = builder.AddCompletionQueue();
- d->server = builder.BuildAndStart();
- }
- std::cout << "Server listening on " << address << ':' << d->port << '\n';
- new CallTag(d->cq.get(), &d->service);
- new SStreamTag(d->cq.get(), &d->service);
- new CStreamTag(d->cq.get(), &d->service);
- d->cqThread = std::jthread(std::bind_front(&ServerPrivate::handleAsyncRpc, d.get()));
- d->state = ServerPrivate::STARTED;
- return true;
- }
- ~~~
- // client.cpp
- int main()
- {
- setDebugEnvs();
- const auto channel = grpc::CreateChannel(Address.data(), grpc::InsecureChannelCredentials());
- std::cout << std::format("Server config: \n{}\n", channel->GetServiceConfigJSON());
- Client client(channel);
- client.sstream(10);
- // client.cstream(3);
- // client.call();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement