mirror of https://github.com/grpc/grpc.git
parent
21940df57e
commit
951254151b
5 changed files with 0 additions and 366 deletions
@ -1,96 +0,0 @@ |
|||||||
#
|
|
||||||
# Copyright 2018 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.
|
|
||||||
#
|
|
||||||
HOST_SYSTEM = $(shell uname | cut -f 1 -d_)
|
|
||||||
SYSTEM ?= $(HOST_SYSTEM)
|
|
||||||
CXX = g++
|
|
||||||
CPPFLAGS += `pkg-config --cflags protobuf grpc`
|
|
||||||
CXXFLAGS += -std=c++11
|
|
||||||
ifeq ($(SYSTEM),Darwin) |
|
||||||
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
|
|
||||||
-lgrpc++_reflection\
|
|
||||||
-ldl
|
|
||||||
else |
|
||||||
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
|
|
||||||
-Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\
|
|
||||||
-ldl
|
|
||||||
endif |
|
||||||
PROTOC = protoc
|
|
||||||
GRPC_CPP_PLUGIN = grpc_cpp_plugin
|
|
||||||
GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`
|
|
||||||
PROTOS_PATH = ../../protos
|
|
||||||
vpath %.proto $(PROTOS_PATH)
|
|
||||||
all: system-check greeter_client greeter_server
|
|
||||||
greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o
|
|
||||||
$(CXX) $^ $(LDFLAGS) -o $@
|
|
||||||
greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o
|
|
||||||
$(CXX) $^ $(LDFLAGS) -o $@
|
|
||||||
.PRECIOUS: %.grpc.pb.cc
|
|
||||||
%.grpc.pb.cc: %.proto |
|
||||||
$(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $<
|
|
||||||
.PRECIOUS: %.pb.cc
|
|
||||||
%.pb.cc: %.proto |
|
||||||
$(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $<
|
|
||||||
clean:
|
|
||||||
rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server
|
|
||||||
# The following is to test your system and ensure a smoother experience.
|
|
||||||
# They are by no means necessary to actually compile a grpc-enabled software.
|
|
||||||
PROTOC_CMD = which $(PROTOC)
|
|
||||||
PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3
|
|
||||||
PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN)
|
|
||||||
HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false)
|
|
||||||
ifeq ($(HAS_PROTOC),true) |
|
||||||
HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false)
|
|
||||||
endif |
|
||||||
HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false)
|
|
||||||
SYSTEM_OK = false
|
|
||||||
ifeq ($(HAS_VALID_PROTOC),true) |
|
||||||
ifeq ($(HAS_PLUGIN),true) |
|
||||||
SYSTEM_OK = true
|
|
||||||
endif |
|
||||||
endif |
|
||||||
system-check:
|
|
||||||
ifneq ($(HAS_VALID_PROTOC),true) |
|
||||||
@echo " DEPENDENCY ERROR"
|
|
||||||
@echo
|
|
||||||
@echo "You don't have protoc 3.0.0 installed in your path."
|
|
||||||
@echo "Please install Google protocol buffers 3.0.0 and its compiler."
|
|
||||||
@echo "You can find it here:"
|
|
||||||
@echo
|
|
||||||
@echo " https://github.com/google/protobuf/releases/tag/v3.0.0"
|
|
||||||
@echo
|
|
||||||
@echo "Here is what I get when trying to evaluate your version of protoc:"
|
|
||||||
@echo
|
|
||||||
-$(PROTOC) --version
|
|
||||||
@echo
|
|
||||||
@echo
|
|
||||||
endif |
|
||||||
ifneq ($(HAS_PLUGIN),true) |
|
||||||
@echo " DEPENDENCY ERROR"
|
|
||||||
@echo
|
|
||||||
@echo "You don't have the grpc c++ protobuf plugin installed in your path."
|
|
||||||
@echo "Please install grpc. You can find it here:"
|
|
||||||
@echo
|
|
||||||
@echo " https://github.com/grpc/grpc"
|
|
||||||
@echo
|
|
||||||
@echo "Here is what I get when trying to detect if you have the plugin:"
|
|
||||||
@echo
|
|
||||||
-which $(GRPC_CPP_PLUGIN)
|
|
||||||
@echo
|
|
||||||
@echo
|
|
||||||
endif |
|
||||||
ifneq ($(SYSTEM_OK),true) |
|
||||||
@false
|
|
||||||
endif |
|
@ -1,66 +0,0 @@ |
|||||||
# Metadata Example |
|
||||||
|
|
||||||
## Overview |
|
||||||
|
|
||||||
This example shows you how to add custom headers on the client and server and |
|
||||||
how to access them. |
|
||||||
|
|
||||||
Custom metadata must follow the "Custom-Metadata" format listed in |
|
||||||
https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md, with the |
|
||||||
exception of binary headers, which don't have to be base64 encoded. |
|
||||||
|
|
||||||
### Get the tutorial source code |
|
||||||
The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command: |
|
||||||
```sh |
|
||||||
$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc |
|
||||||
``` |
|
||||||
Change your current directory to examples/cpp/metadata |
|
||||||
```sh |
|
||||||
$ cd examples/cpp/metadata |
|
||||||
``` |
|
||||||
|
|
||||||
### Generating gRPC code |
|
||||||
To generate the client and server side interfaces: |
|
||||||
```sh |
|
||||||
$ make helloworld.grpc.pb.cc helloworld.pb.cc |
|
||||||
``` |
|
||||||
Which internally invokes the proto-compiler as: |
|
||||||
```sh |
|
||||||
$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto |
|
||||||
$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto |
|
||||||
``` |
|
||||||
### Try it! |
|
||||||
Build client and server: |
|
||||||
|
|
||||||
```sh |
|
||||||
$ make |
|
||||||
``` |
|
||||||
|
|
||||||
Run the server, which will listen on port 50051: |
|
||||||
|
|
||||||
```sh |
|
||||||
$ ./greeter_server |
|
||||||
``` |
|
||||||
|
|
||||||
Run the client (in a different terminal): |
|
||||||
|
|
||||||
```sh |
|
||||||
$ ./greeter_client |
|
||||||
``` |
|
||||||
|
|
||||||
If things go smoothly, you will see in the client terminal: |
|
||||||
|
|
||||||
"Client received initial metadata from server: initial metadata value" |
|
||||||
"Client received trailing metadata from server: trailing metadata value" |
|
||||||
"Client received message: Hello World" |
|
||||||
|
|
||||||
|
|
||||||
And in the server terminal: |
|
||||||
|
|
||||||
"Header key: custom-bin , value: 01234567" |
|
||||||
"Header key: custom-header , value: Custom Value" |
|
||||||
"Header key: user-agent , value: grpc-c++/1.16.0-dev grpc-c/6.0.0-dev (linux; chttp2; gao)" |
|
||||||
|
|
||||||
We did not add the user-agent metadata as a custom header. This shows how |
|
||||||
the gRPC framework adds some headers under the hood that may show up in the |
|
||||||
metadata map. |
|
@ -1,95 +0,0 @@ |
|||||||
/*
|
|
||||||
* |
|
||||||
* 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> |
|
||||||
|
|
||||||
#ifdef BAZEL_BUILD |
|
||||||
#include "examples/protos/helloworld.grpc.pb.h" |
|
||||||
#else |
|
||||||
#include "helloworld.grpc.pb.h" |
|
||||||
#endif |
|
||||||
|
|
||||||
using grpc::Channel; |
|
||||||
using grpc::ClientContext; |
|
||||||
using grpc::Status; |
|
||||||
using helloworld::HelloRequest; |
|
||||||
using helloworld::HelloReply; |
|
||||||
using helloworld::Greeter; |
|
||||||
|
|
||||||
class CustomHeaderClient { |
|
||||||
public: |
|
||||||
CustomHeaderClient(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; |
|
||||||
|
|
||||||
// Setting custom metadata to be sent to the server
|
|
||||||
context.AddMetadata("custom-header", "Custom Value"); |
|
||||||
|
|
||||||
// Setting custom binary metadata
|
|
||||||
char bytes[8] = {'\0', '\1', '\2', '\3', |
|
||||||
'\4', '\5', '\6', '\7'}; |
|
||||||
context.AddMetadata("custom-bin", grpc::string(bytes, 8)); |
|
||||||
|
|
||||||
// The actual RPC.
|
|
||||||
Status status = stub_->SayHello(&context, request, &reply); |
|
||||||
|
|
||||||
// Act upon its status.
|
|
||||||
if (status.ok()) { |
|
||||||
std::cout << "Client received initial metadata from server: " << context.GetServerInitialMetadata().find("custom-server-metadata")->second << std::endl; |
|
||||||
std::cout << "Client received trailing metadata from server: " << context.GetServerTrailingMetadata().find("custom-trailing-metadata")->second << std::endl; |
|
||||||
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()).
|
|
||||||
CustomHeaderClient greeter(grpc::CreateChannel( |
|
||||||
"localhost:50051", grpc::InsecureChannelCredentials())); |
|
||||||
std::string user("world"); |
|
||||||
std::string reply = greeter.SayHello(user); |
|
||||||
std::cout << "Client received message: " << reply << std::endl; |
|
||||||
return 0; |
|
||||||
} |
|
@ -1,94 +0,0 @@ |
|||||||
/*
|
|
||||||
* |
|
||||||
* 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> |
|
||||||
|
|
||||||
#ifdef BAZEL_BUILD |
|
||||||
#include "examples/protos/helloworld.grpc.pb.h" |
|
||||||
#else |
|
||||||
#include "helloworld.grpc.pb.h" |
|
||||||
#endif |
|
||||||
|
|
||||||
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 "); |
|
||||||
|
|
||||||
// Get the client's initial metadata
|
|
||||||
std::cout << "Client metadata: " << std::endl; |
|
||||||
const std::multimap<grpc::string_ref, grpc::string_ref> metadata = context->client_metadata(); |
|
||||||
for (auto iter = metadata.begin(); iter != metadata.end(); ++iter) { |
|
||||||
std::cout << "Header key: " << iter->first << ", value: "; |
|
||||||
// Check for binary value
|
|
||||||
size_t isbin = iter->first.find("-bin"); |
|
||||||
if ((isbin != std::string::npos) && (isbin + 4 == iter->first.size())) { |
|
||||||
std::cout << std::hex; |
|
||||||
for (auto c : iter->second) { |
|
||||||
std::cout << static_cast<unsigned int>(c); |
|
||||||
} |
|
||||||
std::cout << std::dec; |
|
||||||
} else { |
|
||||||
std::cout << iter->second; |
|
||||||
} |
|
||||||
std::cout << std::endl; |
|
||||||
} |
|
||||||
|
|
||||||
context->AddInitialMetadata("custom-server-metadata", "initial metadata value"); |
|
||||||
context->AddTrailingMetadata("custom-trailing-metadata", "trailing metadata value"); |
|
||||||
reply->set_message(prefix + request->name()); |
|
||||||
return Status::OK; |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
void RunServer() { |
|
||||||
std::string server_address("0.0.0.0:50051"); |
|
||||||
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; |
|
||||||
} |
|
Loading…
Reference in new issue