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.
191 lines
5.6 KiB
191 lines
5.6 KiB
8 years ago
|
# gRPC Server Reflection Tutorial
|
||
|
|
||
|
gRPC Server Reflection provides information about publicly-accessible gRPC
|
||
|
services on a server, and assists clients in runtime to construct RPC
|
||
|
requests/responses without precompiled service information. It has been
|
||
|
supported by gRPC CLI, which could be used to introspect server protos and
|
||
|
send/receive test RPCs.
|
||
|
|
||
|
## Eanble Server Reflection
|
||
|
|
||
|
### Enable server reflection in C++ servers
|
||
|
|
||
|
C++ Server Reflection is offered as an add-on library, `libgrpc++_reflction`.
|
||
|
To enable C++ server reflection, you can simply 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 for dynamic linking and `--whole-archive` is
|
||
|
needed for for static linking.
|
||
|
|
||
|
Here is an [example](examples/cpp/helloworld/Makefile#L37#L45) for enabling c++
|
||
|
server reflection on Linux and MacOS.
|
||
|
|
||
|
## Test services using Server Reflection
|
||
|
|
||
|
gRPC Server Reflection has been supported by gRPC CLI. 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](doc/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
|
||
|
```
|
||
|
|
||
|
### List services
|
||
|
|
||
|
`grpc_cli ls` command can list services and methods exposed at a given port
|
||
|
|
||
|
- List all the services exposed at a given port
|
||
|
|
||
|
```sh
|
||
|
$ bins/opt/grpc_cli ls localhost:50051
|
||
|
```
|
||
|
|
||
|
output:
|
||
|
```sh
|
||
|
helloworld.Greeter
|
||
|
grpc.reflection.v1alpha.ServerReflection
|
||
|
```
|
||
|
|
||
|
- List one service with details
|
||
|
|
||
|
`grpc_cli ls` command can inspect one 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
|
||
|
$ bins/opt/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 can also inspect one method given its full name (in the
|
||
|
format of \<package\>.\<service\>.\<method\>).
|
||
|
|
||
|
```sh
|
||
|
$ bins/opt/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
|
||
|
$ bins/opt/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
|
||
|
$ bins/opt/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
|
||
|
in 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.
|
||
|
|
||
|
```c++
|
||
|
const google::protobuf::Descriptor* request_desc =
|
||
|
desc_pool->FindMessageTypeByName("helloworld.HelloRequest");
|
||
|
```
|
||
|
|
||
|
* Feed [google::protobuf::DynamicMessageFactory](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.dynamic_message#DynamicMessageFactory).
|
||
|
|
||
|
```c++
|
||
|
google::protobuf::DynamicMessageFactory(&desc_pool);
|
||
|
```
|