Added server and client steps. Still a bit rough round the edges....
This commit is contained in:
parent
ad011166ba
commit
c57778bdba
139
README.md
139
README.md
|
|
@ -3,8 +3,7 @@
|
||||||
## TODO: move this to the tutorial sub-folder
|
## TODO: move this to the tutorial sub-folder
|
||||||
|
|
||||||
Welcome to the developer documentation for gRPC, a language-neutral,
|
Welcome to the developer documentation for gRPC, a language-neutral,
|
||||||
platform-neutral remote procedure call (RPC) system developed at Google that
|
platform-neutral remote procedure call (RPC) system developed at Google.
|
||||||
helps you build connected systems.
|
|
||||||
|
|
||||||
This document introduces you to gRPC with a quick overview and a simple
|
This document introduces you to gRPC with a quick overview and a simple
|
||||||
Hello World example. More documentation is coming soon!
|
Hello World example. More documentation is coming soon!
|
||||||
|
|
@ -13,6 +12,7 @@ Hello World example. More documentation is coming soon!
|
||||||
|
|
||||||
## TODO: basic conceptual intro (anything more in-depth will go in gRPC Concepts doc)
|
## TODO: basic conceptual intro (anything more in-depth will go in gRPC Concepts doc)
|
||||||
|
|
||||||
|
<a name="hello"></a>
|
||||||
## Hello gRPC!
|
## Hello gRPC!
|
||||||
|
|
||||||
Now that you know a bit more about gRPC, the easiest way to see how it
|
Now that you know a bit more about gRPC, the easiest way to see how it
|
||||||
|
|
@ -38,11 +38,12 @@ don't worry if you're not a Go or
|
||||||
Java developer - complete tutorials and reference documentation for all gRPC
|
Java developer - complete tutorials and reference documentation for all gRPC
|
||||||
languages are coming soon.
|
languages are coming soon.
|
||||||
|
|
||||||
|
<a name="setup"></a>
|
||||||
### Setup
|
### Setup
|
||||||
|
|
||||||
The rest of this page explains how to set up your local machine to work with
|
The rest of this page explains how to set up your local machine to work with
|
||||||
the example code.
|
the example code.
|
||||||
If you just want to read the example, you can go straight to the next step.
|
If you just want to read the example, you can go straight to the [next step](#servicedef).
|
||||||
|
|
||||||
#### Install Git
|
#### Install Git
|
||||||
|
|
||||||
|
|
@ -54,19 +55,19 @@ commands that you will need to use are:
|
||||||
- git checkout ... : check out a particular branch or a tagged version of
|
- git checkout ... : check out a particular branch or a tagged version of
|
||||||
the code to hack on
|
the code to hack on
|
||||||
|
|
||||||
#### Download grpc-helloworld
|
#### Get the source code
|
||||||
|
|
||||||
Clone the grpc-helloword repository located at GitHub by running the
|
The example code for this and our other examples lives in the `grpc-common` GitHub repository. Clone this repository to your local machine by running the
|
||||||
following command:
|
following command:
|
||||||
|
|
||||||
```
|
```
|
||||||
git clone https://github.com/google/grpc-helloworld.git
|
git clone https://github.com/google/grpc-common.git
|
||||||
```
|
```
|
||||||
|
|
||||||
Change your current directory to grpc-helloworld
|
Change your current directory to grpc-common/java
|
||||||
|
|
||||||
```
|
```
|
||||||
cd grpc-helloworld
|
cd grpc-common/java
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Install Java 8
|
#### Install Java 8
|
||||||
|
|
@ -104,6 +105,7 @@ to experiment
|
||||||
with generating the code yourself, download and install protoc from its
|
with generating the code yourself, download and install protoc from its
|
||||||
[Git repo](https://github.com/google/protobuf)
|
[Git repo](https://github.com/google/protobuf)
|
||||||
|
|
||||||
|
<a name="servicedef"></a>
|
||||||
### Defining a service
|
### Defining a service
|
||||||
|
|
||||||
The first step in creating our example is to define a *service*: an RPC
|
The first step in creating our example is to define a *service*: an RPC
|
||||||
|
|
@ -116,7 +118,7 @@ familiar with protocol buffers, you can find out more in the [Protocol Buffers
|
||||||
Developer Guide](https://developers.google.com/protocol-buffers/docs/overview).
|
Developer Guide](https://developers.google.com/protocol-buffers/docs/overview).
|
||||||
|
|
||||||
Here's our example service definition, defined using protocol buffers IDL in
|
Here's our example service definition, defined using protocol buffers IDL in
|
||||||
[helloworld.proto](src/main/proto/helloworld.proto). The `Greeting` service
|
[helloworld.proto](java/src/main/proto/helloworld.proto) _should we link to the version in the Java subdirectory or the one in the common protos directory?_. The `Greeting` service
|
||||||
has one method, `hello`, that lets the server receive a single `HelloRequest`
|
has one method, `hello`, that lets the server receive a single `HelloRequest`
|
||||||
message from the remote client containing the user's name, then send back
|
message from the remote client containing the user's name, then send back
|
||||||
a greeting in a `HelloReply`.
|
a greeting in a `HelloReply`.
|
||||||
|
|
@ -124,6 +126,8 @@ a greeting in a `HelloReply`.
|
||||||
```
|
```
|
||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "ex.grpc";
|
||||||
|
|
||||||
package helloworld;
|
package helloworld;
|
||||||
|
|
||||||
// The request message containing the user's name.
|
// The request message containing the user's name.
|
||||||
|
|
@ -146,6 +150,7 @@ service Greeting {
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a name="generating"></a>
|
||||||
### Generating gRPC code
|
### Generating gRPC code
|
||||||
|
|
||||||
Once we've defined our service, we use the protocol buffer compiler
|
Once we've defined our service, we use the protocol buffer compiler
|
||||||
|
|
@ -185,15 +190,103 @@ $ protoc -I . helloworld.proto
|
||||||
--java_out=src/main/java
|
--java_out=src/main/java
|
||||||
```
|
```
|
||||||
|
|
||||||
This generates the following Java classes
|
This generates the following classes, which contain all the generated code we need to create our example:
|
||||||
|
|
||||||
|
- [`Helloworld.java`](java/src/main/java/ex/grpc/Helloworld.java), which has all the protocol buffer code to populate, serialize, and retrieve our `HelloRequest` and `HelloReply` message types
|
||||||
|
- [`GreetingsGrpc.java`](java/src/main/java/ex/grpc/GreetingsGrpc.java), which contains (along with some other useful code):
|
||||||
|
- an interface for `Greetings` servers to implement
|
||||||
|
|
||||||
|
```
|
||||||
|
public static interface Greetings {
|
||||||
|
|
||||||
|
public void hello(ex.grpc.Helloworld.HelloRequest request,
|
||||||
|
com.google.net.stubby.stub.StreamObserver<ex.grpc.Helloworld.HelloReply> responseObserver);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- _stub_ classes that clients can use to talk to a `Greetings` server.
|
||||||
|
|
||||||
|
```
|
||||||
|
public static class GreetingsStub extends
|
||||||
|
com.google.net.stubby.stub.AbstractStub<GreetingsStub, GreetingsServiceDescriptor>
|
||||||
|
implements Greetings {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
_Does gRPC output multiple Java classes per proto by default?_
|
||||||
|
|
||||||
|
<a name="server"></a>
|
||||||
### Writing a server
|
### Writing a server
|
||||||
|
|
||||||
Now let's write some code! First we'll create the `Greetings` server.
|
Now let's write some code! First we'll create a server application to implement our service. Note that we're not going to go into a lot of detail about how to create a server in this section More detailed information will be in the tutorial for your chosen language (coming soon).
|
||||||
|
|
||||||
Note that we're not going to go into a lot of detail about how to create a server in this section More detailed information will be in the tutorial for your chosen language (coming soon).
|
Our server application has two classes:
|
||||||
|
|
||||||
|
- a simple service implementation [GreetingsImpl.java](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](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
|
||||||
|
```
|
||||||
|
|
||||||
|
<a name="client"></a>
|
||||||
### Writing a client
|
### Writing a client
|
||||||
|
|
||||||
Client-side gRPC is pretty simple. In this step, we'll use the generated code to write a simple client that can access the `Greetings` server we created in the previous section. You can see the complete client code in [GreetingsClient.java](src/main/java/ex/grpc/GreetingsClient.java).
|
Client-side gRPC is pretty simple. In this step, we'll use the generated code to write a simple client that can access the `Greetings` server we created in the previous section. You can see the complete client code in [GreetingsClient.java](src/main/java/ex/grpc/GreetingsClient.java).
|
||||||
|
|
@ -267,10 +360,6 @@ It can be built as follows.
|
||||||
$ mvn package
|
$ 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
|
#### Notes
|
||||||
|
|
||||||
- The client uses a blocking stub. This means that the RPC call waits for the
|
- The client uses a blocking stub. This means that the RPC call waits for the
|
||||||
|
|
@ -280,7 +369,23 @@ implement, build and run a server that supports the service description.
|
||||||
server, where the response is returned asynchronously. Usage of these stubs
|
server, where the response is returned asynchronously. Usage of these stubs
|
||||||
is a more advanced topic and will be described in later steps.
|
is a more advanced topic and will be described in later steps.
|
||||||
|
|
||||||
|
<a name="run"></a>
|
||||||
|
### Try it 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
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
We haven't looked at implementing a server yet, but
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue