mirror of https://github.com/grpc/grpc.git
Merge branch 'master' of https://github.com/LisaFC/grpc-common
commit
6443f8f855
4 changed files with 0 additions and 241 deletions
@ -1,41 +0,0 @@ |
||||
# Step-0: define a service |
||||
|
||||
This section presents an example of a simple service definition that receives |
||||
a message from a remote client. The message contains the user's name and |
||||
sends back a greeting to that person. |
||||
|
||||
It's shown below in full; it's actually contained in separate file. |
||||
[helloworld.proto](src/main/proto/helloworld.proto). |
||||
|
||||
``` |
||||
syntax = "proto3"; |
||||
|
||||
package helloworld; |
||||
|
||||
// The request message containing the user's name. |
||||
message HelloRequest { |
||||
optional string name = 1; |
||||
} |
||||
|
||||
// The response message containing the greetings |
||||
message HelloReply { |
||||
optional string message = 1; |
||||
} |
||||
|
||||
// The greeting service definition. |
||||
service Greeting { |
||||
|
||||
// Sends a greeting |
||||
rpc hello (HelloRequest) returns (HelloReply) { |
||||
} |
||||
} |
||||
|
||||
``` |
||||
|
||||
The service stanza of the message is an example of protobuf service IDL |
||||
(Interface Definition Language). Here, it defines a simple service that |
||||
receives a request containing a name and returns a response containing a |
||||
message. |
||||
|
||||
Next, in [Step - 1](Step_1.md), we'll use protoc to generate client code from |
||||
this IDL. |
@ -1,33 +0,0 @@ |
||||
# Step-1: Generate a service client. |
||||
|
||||
In this step, we use protoc to generate the Java Stub classes. A Stub is the |
||||
name gRPC uses for the code that initiates contact with a gRPC service running |
||||
remotely via the internet. |
||||
|
||||
If you did not install protoc on your system, you can skip this step and move |
||||
onto the next one where we examine the generated code. |
||||
|
||||
First, you'll need to build the protobuf plugin that generates the rpc |
||||
classes. `protoc` uses other tools called plugins to add additional features |
||||
to generated code. |
||||
|
||||
The gRPC Java Stub classes are created using a gRPC Java plugin, but first the |
||||
plugin must be built and installed. |
||||
|
||||
To build the plugin: |
||||
``` |
||||
$ pushd external/grpc_java |
||||
$ make java_plugin |
||||
$ popd |
||||
``` |
||||
|
||||
To use it to generate the code: |
||||
``` |
||||
$ mkdir -p src/main/java |
||||
$ protoc -I . helloworld.proto --plugin=protoc-gen-grpc=external/grpc_java/bins/opt/java_plugin \ |
||||
--grpc_out=src/main/java \ |
||||
--java_out=src/main/java |
||||
``` |
||||
|
||||
Next, in [Step - 2](Step_2.md), we'll use the generated Stub implementation to |
||||
write a client that uses the generated code to make a call to a service. |
@ -1,85 +0,0 @@ |
||||
# Step-2: Write a service client. |
||||
|
||||
This step uses the generated code to write a simple client to access the hello |
||||
service. The full client is in [GreetingsClient.java](src/main/java/ex/grpc/GreetingsClient.java). |
||||
|
||||
|
||||
## Configuring the service to connect to. |
||||
|
||||
The client contains uses a Stub to contact the service. The internet address |
||||
is configured in the client constructor. gRPC Channel is the abstraction over |
||||
transport handling; its constructor accepts the host name and port of the |
||||
service. The channel in turn is used to construct the Stub. |
||||
|
||||
|
||||
``` |
||||
private final ChannelImpl channel; |
||||
private final GreetingGrpc.GreetingBlockingStub blockingStub; |
||||
|
||||
public HelloClient(String host, int port) { |
||||
channel = NettyChannelBuilder.forAddress(host, port) |
||||
.negotiationType(NegotiationType.PLAINTEXT) |
||||
.build(); |
||||
blockingStub = GreetingGrpc.newBlockingStub(channel); |
||||
} |
||||
|
||||
``` |
||||
|
||||
## Obtaining a greeting |
||||
|
||||
The greet method uses the stub to contact the service and obtain a greeting. |
||||
It: |
||||
- constructs a request |
||||
- obtains a reply from the stub |
||||
- prints out the greeting |
||||
|
||||
|
||||
``` |
||||
public void greet(String name) { |
||||
logger.debug("Will try to greet " + name + " ..."); |
||||
try { |
||||
Helloworld.HelloRequest request = Helloworld.HelloRequest.newBuilder().setName(name).build(); |
||||
Helloworld.HelloReply reply = blockingStub.hello(request); |
||||
logger.info("Greeting: " + reply.getMessage()); |
||||
} catch (RuntimeException e) { |
||||
logger.log(Level.WARNING, "RPC failed", e); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
``` |
||||
|
||||
## Running from the command line |
||||
|
||||
The main method puts together the example so that it can be run from a command |
||||
line. |
||||
|
||||
``` |
||||
/* Access a service running on the local machine on port 50051 */ |
||||
HelloClient client = new HelloClient("localhost", 50051); |
||||
String user = "world"; |
||||
if (args.length > 1) { |
||||
user = args[1]; |
||||
} |
||||
client.greet(user); |
||||
|
||||
``` |
||||
|
||||
It can be built as follows. |
||||
|
||||
``` |
||||
$ mvn package |
||||
``` |
||||
|
||||
It can also be run, but doing so now would end up a with a failure as there is |
||||
no server available yet. The [next step](Step_3.md), describes how to |
||||
implement, build and run a server that supports the service description. |
||||
|
||||
## Notes |
||||
|
||||
- The client uses a blocking stub. This means that the RPC call waits for the |
||||
server to respond, and will either return a response or raise an exception. |
||||
|
||||
- gRPC Java has other kinds of stubs that make non-blocking calls to the |
||||
server, where the response is returned asynchronously. Usage of these stubs |
||||
is a more advanced topic and will be described in later steps. |
@ -1,82 +0,0 @@ |
||||
# Step-3: Implement a server. |
||||
|
||||
This step extends the generated server skeleton code to write a simple server |
||||
that provides the hello service. This introduces two new classes: |
||||
|
||||
- a service implementation [GreetingsImpl.java](src/main/java/ex/grpc/GreetingsImpl.java). |
||||
|
||||
- a server that hosts the service implementation and allows access over the network: [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java). |
||||
|
||||
## Service implementation |
||||
|
||||
[GreetingsImpl.java](src/main/java/ex/grpc/GreetingsImpl.java) |
||||
implements the behaviour we require of our GreetingService. There are a |
||||
number of important features of gRPC being used here: |
||||
|
||||
``` |
||||
public void hello(Helloworld.HelloRequest req, |
||||
StreamObserver<Helloworld.HelloReply> responseObserver) { |
||||
Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( |
||||
"Hello " + req.getName()).build(); |
||||
responseObserver.onValue(reply); |
||||
responseObserver.onCompleted(); |
||||
} |
||||
``` |
||||
|
||||
- it provides a class `GreetingsImpl` that implements a generated interface `GreetingsGrpc.Greetings` |
||||
- `GreetingsGrpc.Greetings` declares the method `hello` that was declared in the proto [IDL](src/main/proto/helloworld.proto) |
||||
- `hello's` signature is typesafe: |
||||
hello(Helloworld.HelloRequest req, StreamObserver<Helloworld.HelloReply> responseObserver) |
||||
- `hello` takes two parameters: |
||||
`Helloworld.HelloRequest`: the request |
||||
`StreamObserver<Helloworld.HelloReply>`: a response observer, an interface to be called with the response value |
||||
- to complete the call |
||||
- the return value is constructed |
||||
- the responseObserver.onValue() is called with the response |
||||
- responseObserver.onCompleted() is called to indicate that no more work will done on the RPC. |
||||
|
||||
|
||||
## Server implementation |
||||
|
||||
[GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java) shows the |
||||
other main feature required to provde the gRPC service; how to allow a service |
||||
implementation to be accessed from the network. |
||||
|
||||
``` |
||||
private void start() throws Exception { |
||||
server = NettyServerBuilder.forPort(port) |
||||
.addService(GreetingsGrpc.bindService(new GreetingsImpl())) |
||||
.build(); |
||||
server.startAsync(); |
||||
server.awaitRunning(5, TimeUnit.SECONDS); |
||||
} |
||||
|
||||
``` |
||||
|
||||
- it provides a class `GreetingsServer` that holds a `ServerImpl` that will run the server |
||||
- in the `start` method, `GreetingServer` binds the `GreetingsService` implementation to a port and begins running it |
||||
- there is also a `stop` method that takes care of shutting down the service and cleaning up when the program exits |
||||
|
||||
## Build it |
||||
|
||||
This is the same as before: our client and server are part of the same maven |
||||
package so the same command builds both. |
||||
|
||||
``` |
||||
$ mvn package |
||||
``` |
||||
|
||||
## Try them out |
||||
|
||||
We've added simple shell scripts to simplifying running the examples. Now |
||||
that they are built, you can run the server with: |
||||
|
||||
``` |
||||
$ ./run_greetings_server.sh |
||||
``` |
||||
|
||||
and in another terminal window confirm that it receives a message. |
||||
|
||||
``` |
||||
$ ./run_greetings_client.sh |
||||
``` |
Loading…
Reference in new issue