From cf6360377c9d42f66b8940f6006c503f276907da Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 9 Feb 2015 17:14:14 +0000 Subject: [PATCH 1/9] First commit of consolidated overview/README --- README.md | 275 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 237 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 41b79ba883d..fbd35ebad97 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,64 @@ -# gRPC Hello World Tutorial +# Getting started ## TODO: move this to the tutorial sub-folder -A great way to get introduced to gRPC is to work through this tutorial, which -walks you through the construction of a simple client and server and introduces -various features of gRPC. +Welcome to the developer documentation for gRPC, a language-neutral, +platform-neutral remote procedure call (RPC) system developed at Google that +helps you build connected systems. -When you finish the tutorial, you will be able to +This document introduces you to gRPC with a quick overview and a simple +Hello World example. More documentation is coming soon! -- Create a protobuf schema that defines a simple RPC service. -- Create a Java server that implements the schema interface. -- Create a Java client that accesses the server. -- Create a Go client that accesses the Java server. -- Update the service with advanced features like RPC streaming. +## What is gRPC? + +## TODO: basic conceptual intro (anything more in-depth will go in gRPC Concepts doc) + +## Hello gRPC! -# Get Started +Now that you know a bit more about gRPC, the easiest way to see how it +works is to look at a simple example. Our Hello World walks you through the +construction of a simple gRPC client-server application, showing you how to: + +- Create a protobuf schema that defines a simple RPC service with a single +Hello World method. +- Create a Java server that implements the schema interface. +- Create a Java client that accesses the Java server. +- Create a Go client that accesses the same Java server. +- Update the service with more advanced features like RPC streaming. -The rest of this page explains how you can set up your local machine for development. -If you just want to read the tutorial, you can go straight to the next step: [Step - 0](Step_0.md) +The complete code for the example is available in [wherever we put it]. You can +work along with the example and hack on the code in the comfort of your own +computer, giving you hands-on practice of really writing +gRPC code. We use the Git versioning system for source code management: +however, you don't need to know anything about Git to follow along other +than how to install and run a few git commands. -# Working with the code +This is an introductory example rather than a comprehensive tutorial, so +don't worry if you're not a Go or +Java developer - complete tutorials and reference documentation for all gRPC +languages are coming soon. -You can follow along with this tutorial and hack on the code in the comfort of -your own computer. This way you can get hands-on practice of really writing -gRPC code. +### Setup -The tutorial relies on the use of the Git versioning system for source code -management. You don't need to know anything about Git to follow the tutorial -other than how to install and run a few git commands. +The rest of this page explains how to set up your local machine to work with +the example code. +If you just want to read the example, you can go straight to the next step: +[Step - 0](Step_0.md) -# Install Git +#### Install Git You can download and install Git from http://git-scm.com/download. Once installed you should have access to the git command line tool. The main commands that you will need to use are: - git clone ... : clone a remote repository onto your local machine -- git checkout ... : check out a particular branch or a tagged version of the code to hack on +- git checkout ... : check out a particular branch or a tagged version of +the code to hack on -# Download grpc-helloworld +#### Download grpc-helloworld -Clone the grpc-helloword repository located at GitHub by running the following command: +Clone the grpc-helloword repository located at GitHub by running the +following command: ``` git clone https://github.com/google/grpc-helloworld.git @@ -52,30 +70,211 @@ Change your current directory to grpc-helloworld cd grpc-helloworld ``` -# Install Java 8 +#### Install Java 8 -Java gRPC is designed to work with both Java 7 and Java 8. For simplicity, -the example assumes that Java 8 is installed. See -[Install Java 8](http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html) -for instructions. +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 +#### Install Maven -To simplify building and the managing of gRPC's dependencies, the Java client -are 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. +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 +#### 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 +#### (optional) Install protoc -gRPC uses the latest version of the protocol buffer compiler, protoc. +gRPC uses the latest version of the [protocol +buffer](https://developers.google.com/protocol-buffers/docs/overview) +compiler, protoc. -For following this tutorial, the protoc is not strictly necessary, as all the -generated code is checked into the Git repository. If you want to experiment +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) + +### Defining a service + +The first step in creating our example is to define a *service*: an RPC +service specifies the methods that can be called remotely with their parameters +and return types. In gRPC, we use the protocol buffers interface definition +language (IDL) to define our service methods, and the parameters and return +types are defined as protocol buffer message types. Both the client and the +server use interface code generated from the service definition. If you're not +familiar with protocol buffers, you can find out more in the [Protocol Buffers +Developer Guide](https://developers.google.com/protocol-buffers/docs/overview). + +Here's our example service definition, defined using protocol buffers IDL in +[helloworld.proto](src/main/proto/helloworld.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 +a greeting in a `HelloReply`. + +``` +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) { + } +} + +``` + +### Generating gRPC code + +Once we've defined our service, we use the protocol buffer compiler +`protoc` to generate the special client and server code we need to create +our application - right now we're going to generate Java code, though you +can generate gRPC code in any gRPC-supported language (as you'll see later +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. A stub is code that initiates contact +with a gRPC service running remotely via the internet. [can probably define +this up in "what is gRPC"?] + +(If you didn't install `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: + +``` +$ 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 +``` + +This generates the following Java classes + +### Writing a client + +Now let's write some code! Client-side gRPC is pretty simple, so we'll start there - we'll look at how to implement a gRPC server later. In this step, we'll use the generated code to write a simple client that can access the `Greetings` service. You can see the complete client code in [GreetingsClient.java](src/main/java/ex/grpc/GreetingsClient.java). + +Note that we're not going to go into much detail about how to implement a client - we'll leave that for the tutorial. + +#### Connecting to 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. + + +We haven't looked at implementing a server yet, but + + From ad011166baf7eb1359a5db25d3933e2ec940b1db Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 9 Feb 2015 17:30:37 +0000 Subject: [PATCH 2/9] Minor restructure --- README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fbd35ebad97..d7ecba75669 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,7 @@ languages are coming soon. The rest of this page explains how to set up your local machine to work with the example code. -If you just want to read the example, you can go straight to the next step: -[Step - 0](Step_0.md) +If you just want to read the example, you can go straight to the next step. #### Install Git @@ -188,11 +187,18 @@ $ protoc -I . helloworld.proto This generates the following Java classes +### Writing a server + +Now let's write some code! First we'll create the `Greetings` server. + +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). + + ### Writing a client -Now let's write some code! Client-side gRPC is pretty simple, so we'll start there - we'll look at how to implement a gRPC server later. In this step, we'll use the generated code to write a simple client that can access the `Greetings` service. 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). -Note that we're not going to go into much detail about how to implement a client - we'll leave that for the tutorial. +Again, we're not going to go into much detail about how to implement a client - we'll leave that for the tutorial. #### Connecting to the service From c57778bdba28d6db3bf08f30cc0350f3d0b36812 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Tue, 10 Feb 2015 16:38:10 +0000 Subject: [PATCH 3/9] Added server and client steps. Still a bit rough round the edges.... --- README.md | 139 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 122 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index d7ecba75669..3a2f3c85551 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,7 @@ ## TODO: move this to the tutorial sub-folder Welcome to the developer documentation for gRPC, a language-neutral, -platform-neutral remote procedure call (RPC) system developed at Google that -helps you build connected systems. +platform-neutral remote procedure call (RPC) system developed at Google. This document introduces you to gRPC with a quick overview and a simple 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) + ## Hello gRPC! 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 languages are coming soon. + ### Setup The rest of this page explains how to set up your local machine to work with 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 @@ -54,19 +55,19 @@ 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 -#### 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: ``` -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 @@ -104,6 +105,7 @@ to experiment with generating the code yourself, download and install protoc from its [Git repo](https://github.com/google/protobuf) + ### Defining a service 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). 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` message from the remote client containing the user's name, then send back a greeting in a `HelloReply`. @@ -124,6 +126,8 @@ a greeting in a `HelloReply`. ``` syntax = "proto3"; +option java_package = "ex.grpc"; + package helloworld; // The request message containing the user's name. @@ -146,6 +150,7 @@ service Greeting { ``` + ### Generating gRPC code 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 ``` -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 responseObserver); + } +``` + + - _stub_ classes that clients can use to talk to a `Greetings` server. + +``` +public static class GreetingsStub extends + com.google.net.stubby.stub.AbstractStub + implements Greetings { + ... + } +``` + +_Does gRPC output multiple Java classes per proto by default?_ + ### 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). + +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 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 responseObserver) +- `hello` takes two parameters: + `Helloworld.HelloRequest`: the request + `StreamObserver`: 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. + -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). +## 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 +``` + + ### 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). @@ -267,10 +360,6 @@ 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 @@ -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 is a more advanced topic and will be described in later steps. + +### 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 From 4a8df2ae35d5864c30d09bd72376dece749c3ff1 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Tue, 10 Feb 2015 16:46:20 +0000 Subject: [PATCH 4/9] Delete Step_0.md Remove separate step now everything's been moved into the main doc --- Step_0.md | 41 ----------------------------------------- 1 file changed, 41 deletions(-) delete mode 100644 Step_0.md diff --git a/Step_0.md b/Step_0.md deleted file mode 100644 index d0745b0dd1f..00000000000 --- a/Step_0.md +++ /dev/null @@ -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. From baa905deefac19dcd32b2ccedcc53e41b077825a Mon Sep 17 00:00:00 2001 From: LisaFC Date: Tue, 10 Feb 2015 16:46:45 +0000 Subject: [PATCH 5/9] Delete Step_1.md Remove separate step now that all the content has been moved into the main doc --- Step_1.md | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 Step_1.md diff --git a/Step_1.md b/Step_1.md deleted file mode 100644 index c7aed326c38..00000000000 --- a/Step_1.md +++ /dev/null @@ -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. From b8d33683de3fa51b45c285b35030e0568420f299 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Tue, 10 Feb 2015 16:47:00 +0000 Subject: [PATCH 6/9] Delete Step_2.md Remove separate step now that all the content has been moved into the main doc --- Step_2.md | 85 ------------------------------------------------------- 1 file changed, 85 deletions(-) delete mode 100644 Step_2.md diff --git a/Step_2.md b/Step_2.md deleted file mode 100644 index eafe70b6923..00000000000 --- a/Step_2.md +++ /dev/null @@ -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. From a60ad9e4221046b3444789d67873186cd1dd2103 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Tue, 10 Feb 2015 16:47:10 +0000 Subject: [PATCH 7/9] Delete Step_3.md Remove separate step now that all the content has been moved into the main doc --- Step_3.md | 82 ------------------------------------------------------- 1 file changed, 82 deletions(-) delete mode 100644 Step_3.md diff --git a/Step_3.md b/Step_3.md deleted file mode 100644 index 7b03cdf585f..00000000000 --- a/Step_3.md +++ /dev/null @@ -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 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 responseObserver) -- `hello` takes two parameters: - `Helloworld.HelloRequest`: the request - `StreamObserver`: 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 -``` From 874bff090a0231940e0c60e6520f80d3834b91f3 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Tue, 10 Feb 2015 16:47:41 +0000 Subject: [PATCH 8/9] Minor formatting tweaks --- README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3a2f3c85551..61ff9a5e97d 100644 --- a/README.md +++ b/README.md @@ -227,7 +227,7 @@ Our server application has two classes: - a server that hosts the service implementation and allows access over the network: [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java). -## Service implementation +#### Service implementation [GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java) implements the behaviour we require of our GreetingService. There are a @@ -256,7 +256,7 @@ number of important features of gRPC being used here: - responseObserver.onCompleted() is called to indicate that no more work will done on the RPC. -## Server implementation +#### 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 @@ -277,15 +277,16 @@ implementation to be accessed from the network. - 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 +#### 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. +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. + ### Writing a client @@ -354,7 +355,10 @@ line. ``` -It can be built as follows. +#### Build the client + +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 From d7e29f4b313faa71acd2cee5f46ca9fc380e9c3d Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Wed, 11 Feb 2015 13:14:16 +0000 Subject: [PATCH 9/9] Implementing Tim's edits --- README.md | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 61ff9a5e97d..c7c896db61d 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Hello World method. - Create a Go client that accesses the same Java server. - Update the service with more advanced features like RPC streaming. -The complete code for the example is available in [wherever we put it]. You can +The complete code for the example is available in the `grpc-common` GitHub repository. You can work along with the example and hack on the code in the comfort of your own computer, giving you hands-on practice of really writing gRPC code. We use the Git versioning system for source code management: @@ -174,7 +174,7 @@ to generated code. As we're creating Java code, we use the gRPC Java plugin. To build the plugin: -``` +```sh $ pushd external/grpc_java $ make java_plugin $ popd @@ -182,7 +182,7 @@ $ popd 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 \ @@ -194,27 +194,25 @@ This generates the following classes, which contain all the generated code we ne - [`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 + - an interface for `Greetings` servers to implement -``` + ```java public static interface Greetings { public void hello(ex.grpc.Helloworld.HelloRequest request, com.google.net.stubby.stub.StreamObserver responseObserver); } -``` + ``` - - _stub_ classes that clients can use to talk to a `Greetings` server. + - _stub_ classes that clients can use to talk to a `Greetings` server. -``` + ```java public static class GreetingsStub extends com.google.net.stubby.stub.AbstractStub implements Greetings { ... } -``` - -_Does gRPC output multiple Java classes per proto by default?_ + ``` ### Writing a server @@ -233,7 +231,7 @@ Our server application has two classes: implements the behaviour we require of our GreetingService. There are a number of important features of gRPC being used here: -``` +```java public void hello(Helloworld.HelloRequest req, StreamObserver responseObserver) { Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( @@ -262,7 +260,7 @@ number of important features of gRPC being used here: other main feature required to provde the gRPC service; how to allow a service implementation to be accessed from the network. -``` +```java private void start() throws Exception { server = NettyServerBuilder.forPort(port) .addService(GreetingsGrpc.bindService(new GreetingsImpl())) @@ -302,7 +300,7 @@ transport handling; its constructor accepts the host name and port of the service. The channel in turn is used to construct the Stub. -``` +```java private final ChannelImpl channel; private final GreetingGrpc.GreetingBlockingStub blockingStub; @@ -324,7 +322,7 @@ It: - prints out the greeting -``` +```java public void greet(String name) { logger.debug("Will try to greet " + name + " ..."); try { @@ -344,7 +342,7 @@ It: The main method puts together the example so that it can be run from a command line. -``` +```java /* Access a service running on the local machine on port 50051 */ HelloClient client = new HelloClient("localhost", 50051); String user = "world"; @@ -379,13 +377,13 @@ $ mvn package We've added simple shell scripts to simplifying running the examples. Now that they are built, you can run the server with: -``` +```sh $ ./run_greetings_server.sh ``` and in another terminal window confirm that it receives a message. -``` +```sh $ ./run_greetings_client.sh ```