diff options
author | Lisa Carey <lcarey@google.com> | 2015-02-26 14:30:19 +0000 |
---|---|---|
committer | Tim Emiola <temiola@google.com> | 2015-02-26 08:05:13 -0800 |
commit | ff0591f8d5017afd8812593e2cfc6b097895c4a4 (patch) | |
tree | 6bc7ee42fc4a6b7004b49fbabaddb4c52ca62884 | |
parent | c8809b1d25abb62fba05b0c68e85ee4889785650 (diff) |
Updated to work with new Java example location/build
-rw-r--r-- | README.md | 195 |
1 files changed, 65 insertions, 130 deletions
@@ -120,57 +120,30 @@ commands that you will need to use are: - git checkout ... : check out a particular branch or a tagged version of 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 -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 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> ### 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. 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 `HelloRequest` 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"; -option java_package = "ex.grpc"; +option java_package = "io.grpc.examples"; 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 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 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 -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). +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: -To use it to generate the code: - -```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 +```shell +../gradlew build ``` -[need to update this once I get the plugin built] - -This generates the following classes, which contain all the generated code +This generates the following classes from our .proto, which contain all the generated code 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 `HelloRequest` and `HelloReply` message types -- [`GreeterGrpc.java`](java/src/main/java/ex/grpc/GreeterGrpc.java), -which contains (along with some other useful code): +- `GreeterGrpc.java`, which contains (along with some other useful code): - an interface for `Greeter` servers to implement ```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: -- a simple service implementation -[GreeterImpl.java](java/src/main/java/ex/grpc/GreeterImpl.java). +- a main server class that hosts the service implementation and allows access over the +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 -[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. As you can see, the class `GreeterImpl` implements the interface `GreeterGrpc.Greeter` that we [generated](#generating) from our proto -[IDL](java/src/main/proto/helloworld.proto) by implementing the method `hello`: +[IDL](https://github.com/grpc/grpc-java/tree/master/examples/src/main/proto) by implementing the method `sayHello`: ```java - 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(); - } + @Override + public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) { + HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build(); + responseObserver.onValue(reply); + responseObserver.onCompleted(); + } ``` - `hello` takes two parameters: - - `Helloworld.HelloRequest`: the request - - `StreamObserver<Helloworld.HelloReply>`: a response observer, which is + - `HelloRequest`: the request + - `StreamObserver<HelloReply>`: a response observer, which is a special interface for the server to call with its response To return our response to the client and complete the call: 1. We construct and populate a `HelloReply` response object with our exciting message, as specified in our interface definition. -2. We use the`responseObserver` to return the `HelloReply` to the client -and then specify that we've finished dealing with the RPC +2. We return the `HelloReply` to the client and then specify that we've finished dealing with the RPC. #### Server implementation -[GreeterServer.java](java/src/main/java/ex/grpc/GreeterServer.java) +[HelloWorldServer.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/HelloWorldServer.java) shows the other main feature required to provide a gRPC service; making the service implementation available from the network. ```java + /* The port on which the server should run */ + private int port = 50051; private ServerImpl server; - ... + private void start() throws Exception { server = NettyServerBuilder.forPort(port) - .addService(GreeterGrpc.bindService(new GreeterImpl())) - .build(); - server.startAsync(); - server.awaitRunning(5, TimeUnit.SECONDS); + .addService(GreeterGrpc.bindService(new GreeterImpl())) + .build().start(); + logger.info("Server started, listening on " + port); + 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 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> ### 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 GreeterGrpc.GreeterBlockingStub blockingStub; - public HelloClient(String host, int port) { - channel = NettyChannelBuilder.forAddress(host, port) - .negotiationType(NegotiationType.PLAINTEXT) - .build(); + public HelloWorldClient(String host, int port) { + channel = + NettyChannelBuilder.forAddress(host, port).negotiationType(NegotiationType.PLAINTEXT) + .build(); 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. 2. We call the stub's `hello()` RPC with our request and get a `HelloReply` -back, -from which we can get our greeting. +back, from which we can get our greeting. ```java - 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.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. + HelloRequest req = HelloRequest.newBuilder().setName(name).build(); + HelloReply reply = blockingStub.sayHello(req); ``` -$ mvn package -``` <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: +Our [Gradle build file](https://github.com/grpc/grpc-java/blob/master/examples/build.gradle) simplifies building and running the examples. + +You can build and run the server from the `grpc-java` root folder with: ```sh -$ ./run_greeter_server.sh +$ ./gradlew :grpc-examples:helloWorldServer ``` and in another terminal window confirm that it receives a message. ```sh -$ ./run_greeter_client.sh +$ ./gradlew :grpc-examples:helloWorldClient ``` ### 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 in this repository, we've also generated and implemented `Greeter` in some of gRPC's other supported languages. Each service -and client uses interface code generated from [exactly the same -.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto) +and client uses interface code generated from the same proto 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 [`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 |