mirror of https://github.com/grpc/grpc.git
The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#)
https://grpc.io/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
5.6 KiB
193 lines
5.6 KiB
# gRPC Server Reflection Tutorial |
|
|
|
gRPC Server Reflection provides information about publicly-accessible gRPC |
|
services on a server, and assists clients at runtime to construct RPC |
|
requests and responses without precompiled service information. It is used by |
|
gRPC CLI, which can be used to introspect server protos and send/receive test |
|
RPCs. |
|
|
|
## Enable Server Reflection |
|
|
|
### Enable server reflection in C++ servers |
|
|
|
C++ Server Reflection is an add-on library, `libgrpc++_reflection`. To enable C++ |
|
server reflection, you can link this library to your server binary. |
|
|
|
Some platforms (e.g. Ubuntu 11.10 onwards) only link in libraries that directly |
|
contain symbols used by the application. On these platforms, LD flag |
|
`--no-as-needed` is needed for dynamic linking and `--whole-archive` is |
|
needed for static linking. |
|
|
|
This [Makefile](../examples/cpp/helloworld/Makefile#L37#L45) demonstrates |
|
enabling c++ server reflection on Linux and MacOS. |
|
|
|
## Test services using Server Reflection |
|
|
|
After enabling Server Reflection in a server application, you can use gRPC CLI |
|
to test its services. |
|
|
|
Instructions on how to use gRPC CLI can be found at |
|
[command_line_tool.md](command_line_tool.md), or using `grpc_cli help` command. |
|
|
|
Here we use `examples/cpp/helloworld` as an example to show the use of gRPC |
|
Server Reflection and gRPC CLI. First, we need to build gRPC CLI and setup an |
|
example server with Server Reflection enabled. |
|
|
|
- Setup an example server |
|
|
|
Server Reflection has already been enabled in the |
|
[Makefile](../examples/cpp/helloworld/Makefile) of the helloworld example. We |
|
can simply make it and run the greeter_server. |
|
|
|
```sh |
|
$ make -C examples/cpp/helloworld |
|
$ examples/cpp/helloworld/greeter_server & |
|
``` |
|
|
|
- Build gRPC CLI |
|
|
|
```sh |
|
make grpc_cli |
|
cd bins/opt |
|
``` |
|
|
|
gRPC CLI binary `grpc_cli` can be found at `bins/opt/` folder. This tool is |
|
still new and does not have a `make install` target yet. |
|
|
|
### List services |
|
|
|
`grpc_cli ls` command lists services and methods exposed at a given port |
|
|
|
- List all the services exposed at a given port |
|
|
|
```sh |
|
$ grpc_cli ls localhost:50051 |
|
``` |
|
|
|
output: |
|
```sh |
|
helloworld.Greeter |
|
grpc.reflection.v1alpha.ServerReflection |
|
``` |
|
|
|
- List one service with details |
|
|
|
`grpc_cli ls` command inspects a service given its full name (in the format of |
|
\<package\>.\<service\>). It can print information with a long listing format |
|
when `-l` flag is set. This flag can be used to get more details about a |
|
service. |
|
|
|
```sh |
|
$ grpc_cli ls localhost:50051 helloworld.Greeter -l |
|
``` |
|
|
|
output: |
|
```sh |
|
filename: helloworld.proto |
|
package: helloworld; |
|
service Greeter { |
|
rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {} |
|
} |
|
|
|
``` |
|
|
|
### List methods |
|
|
|
- List one method with details |
|
|
|
`grpc_cli ls` command also inspects a method given its full name (in the |
|
format of \<package\>.\<service\>.\<method\>). |
|
|
|
```sh |
|
$ grpc_cli ls localhost:50051 helloworld.Greeter.SayHello -l |
|
``` |
|
|
|
output: |
|
```sh |
|
rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {} |
|
``` |
|
|
|
### Inspect message types |
|
|
|
We can use`grpc_cli type` command to inspect request/response types given the |
|
full name of the type (in the format of \<package\>.\<type\>). |
|
|
|
- Get information about the request type |
|
|
|
```sh |
|
$ grpc_cli type localhost:50051 helloworld.HelloRequest |
|
``` |
|
|
|
output: |
|
```sh |
|
message HelloRequest { |
|
optional string name = 1; |
|
} |
|
``` |
|
|
|
### Call a remote method |
|
|
|
We can send RPCs to a server and get responses using `grpc_cli call` command. |
|
|
|
- Call a unary method |
|
|
|
```sh |
|
$ grpc_cli call localhost:50051 SayHello "name: 'gRPC CLI'" |
|
``` |
|
|
|
output: |
|
```sh |
|
message: "Hello gRPC CLI" |
|
``` |
|
|
|
## Use Server Reflection in a C++ client |
|
|
|
Server Reflection can be used by clients to get information about gRPC services |
|
at runtime. We've provided a descriptor database called |
|
[grpc::ProtoReflectionDescriptorDatabase](../test/cpp/util/proto_reflection_descriptor_database.h) |
|
which implements the |
|
[google::protobuf::DescriptorDatabase](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor_database#DescriptorDatabase) |
|
interface. It manages the communication between clients and reflection services |
|
and the storage of received information. Clients can use it as using a local |
|
descriptor database. |
|
|
|
- To use Server Reflection with grpc::ProtoReflectionDescriptorDatabase, first |
|
initialize an instance with a grpc::Channel. |
|
|
|
```c++ |
|
std::shared_ptr<grpc::Channel> channel = |
|
grpc::CreateChannel(server_address, server_cred); |
|
grpc::ProtoReflectionDescriptorDatabase reflection_db(channel); |
|
``` |
|
|
|
- Then use this instance to feed a |
|
[google::protobuf::DescriptorPool](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor#DescriptorPool). |
|
|
|
```c++ |
|
google::protobuf::DescriptorPool desc_pool(&reflection_db); |
|
``` |
|
|
|
- Example usage of this descriptor pool |
|
|
|
* Get Service/method descriptors. |
|
|
|
```c++ |
|
const google::protobuf::ServiceDescriptor* service_desc = |
|
desc_pool->FindServiceByName("helloworld.Greeter"); |
|
const google::protobuf::MethodDescriptor* method_desc = |
|
desc_pool->FindMethodByName("helloworld.Greeter.SayHello"); |
|
``` |
|
|
|
* Get message type descriptors and create messages dynamically. |
|
|
|
```c++ |
|
const google::protobuf::Descriptor* request_desc = |
|
desc_pool->FindMessageTypeByName("helloworld.HelloRequest"); |
|
google::protobuf::DynamicMessageFactory dmf; |
|
google::protobuf::Message* request = dmf.GetPrototype(request_desc)->New(); |
|
``` |
|
|
|
## Use Server Reflection in a Python client |
|
|
|
See [Python Server Reflection](python/server_reflection.md). |
|
|
|
|