@ -120,57 +120,30 @@ 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
#### Install gRPC
To build and install gRPC plugins and related tools:
- For Java, see the [Java quick start ](https://github.com/grpc/grpc-java ).
- For Go, see the [Go quick start ](https://github.com/grpc/grpc-go ).
#### Get the source code
#### Get the source code
The example code for this and our other examples lives in the `grpc-common`
The example code for our Java example lives in the `grpc-java `
GitHub repository. Clone this repository to your local machine by running the
GitHub repository. Clone this repository to your local machine by running the
following command:
following command:
```
```
git clone https://github.com/google/grpc-common .git
git clone https://github.com/google/grpc-java .git
```
```
Change your current directory to grpc-common/ java
Change your current directory to grpc-java/examples
```
```
cd grpc-common/ java
cd grpc-java/examples
```
```
#### Install Java 8
Java gRPC is designed to work with both Java 7 and Java 8 - our example uses
Java 8. See
[Install Java
8](http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html)
for instructions if you need to install Java 8.
#### Install Maven
To simplify building and managing gRPC's dependencies, the Java client
and server are structured as a standard
[Maven ](http://maven.apache.org/guides/getting-started/ )
project. See [Install Maven ](http://maven.apache.org/users/index.html )
for instructions.
#### Install Go 1.4
Go gRPC requires Go 1.4, the latest version of Go. See
[Install Go ](https://golang.org/doc/install ) for instructions.
#### (optional) Install protoc
gRPC uses the latest version of the [protocol
buffer](https://developers.google.com/protocol-buffers/docs/overview)
compiler, protoc.
Having protoc installed isn't strictly necessary to follow along with this
example, as all the
generated code is checked into the Git repository. However, if you want
to experiment
with generating the code yourself, download and install protoc from its
[Git repo ](https://github.com/google/protobuf )
< a name = "servicedef" > < / a >
< a name = "servicedef" > < / a >
### Defining a service
### Defining a service
@ -186,7 +159,7 @@ types as protocol buffer message types. Both the client and the
server use interface code generated from the service definition.
server use interface code generated from the service definition.
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 ](protos/helloworld. proto ). The `Greeting`
[helloworld.proto ](https://github.com/grpc/grpc-java/tree/master/examples/src/main/ proto ). The `Greeting`
service has one method, `hello` , that lets the server receive a single
service has one method, `hello` , that lets the server receive a single
`HelloRequest`
`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
@ -196,7 +169,7 @@ can specify in gRPC - we'll look at some other types later in this document.
```
```
syntax = "proto3";
syntax = "proto3";
option java_package = "ex.grpc ";
option java_package = "io.grpc.examples ";
package helloworld;
package helloworld;
@ -229,39 +202,23 @@ in this example). The generated code contains both stub code for clients to
use and an abstract interface for servers to implement, both with the method
use and an abstract interface for servers to implement, both with the method
defined in our `Greeting` service.
defined in our `Greeting` service.
(If you didn't install `protoc` on your system and are working along with
(If you didn't install the gRPC plugins and protoc on your system and are working along with
the example, you can skip this step and move
the example, you can skip this step and move
onto the next one where we examine the generated code.)
onto the next one where we examine the generated code.)
As this is our first time using gRPC, we need to build the protobuf plugin
For simplicity, we've provided a [Gradle build file ](https://github.com/grpc/grpc-java/blob/master/examples/build.gradle ) with our Java examples that runs `protoc` for you with the appropriate plugin, input, and output:
that generates our RPC
classes. By default `protoc` just generates code for reading and writing
protocol buffers, so you need to use plugins to add additional features
to generated code. As we're creating Java code, we use the gRPC Java plugin.
To build the plugin, follow the instructions in the relevant repo: for Java,
the instructions are in [`grpc-java` ](https://github.com/grpc/grpc-java ).
To use it to generate the code:
```shell
../gradlew build
```sh
$ 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
```
```
[need to update this once I get the plugin built]
This generates the following classes from our .proto, which contain all the generated code
This generates the following classes, which contain all the generated code
we need to create our example:
we need to create our example:
- [`Helloworld.java` ](java/src/main/java/ex/grpc/Helloworld.java ) , which
- `Helloworld.java` , which
has all the protocol buffer code to populate, serialize, and retrieve our
has all the protocol buffer code to populate, serialize, and retrieve our
`HelloRequest` and `HelloReply` message types
`HelloRequest` and `HelloReply` message types
- [`GreeterGrpc.java` ](java/src/main/java/ex/grpc/GreeterGrpc.java ),
- `GreeterGrpc.java` , which contains (along with some other useful code):
which contains (along with some other useful code):
- an interface for `Greeter` servers to implement
- an interface for `Greeter` servers to implement
```java
```java
@ -294,59 +251,67 @@ tutorial for your chosen language: check if there's one available yet in the rel
Our server application has two classes:
Our server application has two classes:
- a simple service implementation
- a main server class that hosts the service implementation and allows access over the
[GreeterImpl.java ](java/src/main/java/ex/grpc/GreeterImpl.java ).
network: [HelloWorldServer.java ](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/HelloWorldServer.java ).
- a simple service implementation class [GreeterImpl.java ](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/HelloWorldServer.java#L51 ).
- a server that hosts the service implementation and allows access over the
network: [GreeterServer.java ](java/src/main/java/ex/grpc/GreeterServer.java ).
#### Service implementation
#### Service implementation
[GreeterImpl.java ](java/src/main/java/ex/grpc/GreeterImpl.java )
[GreeterImpl.java ](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/HelloWorldServer.java#L51 )
actually implements our GreetingService's required behaviour.
actually implements our GreetingService's required behaviour.
As you can see, the class `GreeterImpl` implements the interface
As you can see, the class `GreeterImpl` implements the interface
`GreeterGrpc.Greeter` that we [generated ](#generating ) from our proto
`GreeterGrpc.Greeter` that we [generated ](#generating ) from our proto
[IDL ](java/src/main/proto/helloworld.proto ) by implementing the method `h ello` :
[IDL ](https://github.com/grpc/grpc-java/tree/master/examples/src/main/proto ) by implementing the method `sayH ello` :
```java
```java
public void hello(Helloworld.HelloRequest req,
@Override
StreamObserver< Helloworld.HelloReply > responseObserver) {
public void sayHello(HelloRequest req, StreamObserver< HelloReply > responseObserver) {
Helloworld.HelloReply reply =
HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
Helloworld.HelloReply.newBuilder().setMessage(
responseObserver.onValue(reply);
"Hello " + req.getName()).build();
responseObserver.onCompleted();
responseObserver.onValue(reply);
}
responseObserver.onCompleted();
}
```
```
- `hello` takes two parameters:
- `hello` takes two parameters:
- `Helloworld.Hello Request` : the request
- `HelloRequest` : the request
- `StreamObserver<Helloworld.Hello Reply>` : a response observer, which is
- `StreamObserver<HelloReply>` : a response observer, which is
a special interface for the server to call with its response
a special interface for the server to call with its response
To return our response to the client and complete the call:
To return our response to the client and complete the call:
1. We construct and populate a `HelloReply` response object with our exciting
1. We construct and populate a `HelloReply` response object with our exciting
message, as specified in our interface definition.
message, as specified in our interface definition.
2. We use the`responseObserver` to return the `HelloReply` to the client
2. We return the `HelloReply` to the client and then specify that we've finished dealing with the RPC.
and then specify that we've finished dealing with the RPC
#### Server implementation
#### Server implementation
[GreeterServer.java ](java/src/main/java/ex/grpc/Greeter Server.java )
[HelloWorldServer.java ](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/HelloWorld Server.java )
shows the other main feature required to provide a gRPC service; making the service
shows the other main feature required to provide a gRPC service; making the service
implementation available from the network.
implementation available from the network.
```java
```java
/* The port on which the server should run */
private int port = 50051;
private ServerImpl server;
private ServerImpl server;
...
private void start() throws Exception {
private void start() throws Exception {
server = NettyServerBuilder.forPort(port)
server = NettyServerBuilder.forPort(port)
.addService(GreeterGrpc.bindService(new GreeterImpl()))
.addService(GreeterGrpc.bindService(new GreeterImpl()))
.build();
.build().start();
server.startAsync();
logger.info("Server started, listening on " + port);
server.awaitRunning(5, TimeUnit.SECONDS);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
// Use stderr here since the logger may has been reset by its JVM shutdown hook.
System.err.println("*** shutting down gRPC server since JVM is shutting down");
HelloWorldServer.this.stop();
System.err.println("*** server shut down");
}
});
}
}
```
```
@ -356,16 +321,6 @@ implementation that we created to a port. Then we start the server running: the
requests from `Greeter` service clients on our specified port. We'll cover
requests from `Greeter` service clients on our specified port. We'll cover
how all this works in a bit more detail in our language-specific documentation.
how all this works in a bit more detail in our language-specific documentation.
#### Build it
Once we've implemented everything, we use Maven to build the server:
```
$ mvn package
```
We'll look at using a client to access the server in the next section.
< a name = "client" > < / a >
< a name = "client" > < / a >
### Writing a client
### Writing a client
@ -388,10 +343,10 @@ want to connect to. Then we use the channel to construct the stub instance.
private final ChannelImpl channel;
private final ChannelImpl channel;
private final GreeterGrpc.GreeterBlockingStub blockingStub;
private final GreeterGrpc.GreeterBlockingStub blockingStub;
public HelloClient(String host, int port) {
public HelloWorld Client(String host, int port) {
channel = NettyChannelBuilder.forAddress(host, port)
channel =
.negotiationType(NegotiationType.PLAINTEXT)
NettyChannelBuilder.forAddress(host, port) .negotiationType(NegotiationType.PLAINTEXT)
.build();
.build();
blockingStub = GreeterGrpc.newBlockingStub(channel);
blockingStub = GreeterGrpc.newBlockingStub(channel);
}
}
@ -408,49 +363,30 @@ Now we can contact the service and obtain a greeting:
1. We construct and fill in a `HelloRequest` to send to the service.
1. We construct and fill in a `HelloRequest` to send to the service.
2. We call the stub's `hello()` RPC with our request and get a `HelloReply`
2. We call the stub's `hello()` RPC with our request and get a `HelloReply`
back,
back, from which we can get our greeting.
from which we can get our greeting.
```java
```java
public void greet(String name) {
HelloRequest req = HelloRequest.newBuilder().setName(name).build();
logger.debug("Will try to greet " + name + " ...");
HelloReply reply = blockingStub.sayHello(req);
try {
Helloworld.HelloRequest request =
Helloworld.HelloRequest.newBuilder().setName(name).build();
Helloworld.HelloReply reply = blockingStub.SayHello(request);
logger.info("Greeting: " + reply.getMessage());
} catch (RuntimeException e) {
logger.log(Level.WARNING, "RPC failed", e);
return;
}
}
```
#### Build the client
This is the same as building the server: our client and server are part of
the same maven package so the same command builds both.
```
$ mvn package
```
```
< a name = "run" > < / a >
< a name = "run" > < / a >
### Try it out!
### Try it out!
We've added simple shell scripts to simplifying running the examples. Now
Our [Gradle build file ](https://github.com/grpc/grpc-java/blob/master/examples/build.gradle ) simplifies building and running the examples.
that they are built, you can run the server with:
You can build and run the server from the `grpc-java` root folder with:
```sh
```sh
$ ./run_greeter_server.sh
$ ./gradlew :grpc-examples:helloWorldServer
```
```
and in another terminal window confirm that it receives a message.
and in another terminal window confirm that it receives a message.
```sh
```sh
$ ./run_greeter_client.sh
$ ./gradlew :grpc-examples:helloWorldClient
```
```
### Adding another client
### Adding another client
@ -461,11 +397,10 @@ generated from and implementing our `Greeter` service definition. However,
as you'll see if you look at the language-specific subdirectories
as you'll see if you look at the language-specific subdirectories
in this repository, we've also generated and implemented `Greeter`
in this repository, we've also generated and implemented `Greeter`
in some of gRPC's other supported languages. Each service
in some of gRPC's other supported languages. Each service
and client uses interface code generated from [exactly the same
and client uses interface code generated from the same proto
.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto)
that we used for the Java example.
that we used for the Java example.
So, for example, if we visit the [`go`
So, for example, if we visit the [`go` example
directory](https://github.com/grpc/grpc-common/tree/master/go) and look at the
directory](https://github.com/grpc/grpc-common/tree/master/go) and look at the
[`greeter_client` ](https://github.com/grpc/grpc-common/blob/master/go/greeter_client/main.go ),
[`greeter_client` ](https://github.com/grpc/grpc-common/blob/master/go/greeter_client/main.go ),
we can see that like the Java client, it connects to a `Greeter` service
we can see that like the Java client, it connects to a `Greeter` service