From 15dd5da9f5a1cd6783ae9640ebfe02efbdcfedbc Mon Sep 17 00:00:00 2001 From: Jayant Kolhe Date: Wed, 4 Feb 2015 09:56:29 -0800 Subject: [PATCH 01/92] Update Step_1.md --- Step_1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Step_1.md b/Step_1.md index 4ac68aba5df..da85cb4e10f 100644 --- a/Step_1.md +++ b/Step_1.md @@ -29,5 +29,5 @@ $ protoc -I . helloworld.proto --plugin=protoc-gen-grpc=external/grpc_java/bins/ --java_out=src/main/java ``` -Next, in [Step-2](Step-2.md), we'll use the generated Stub implementation to +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 5a92194fb0c3fb6936b8144f98853f0b9a234a0f Mon Sep 17 00:00:00 2001 From: Jayant Kolhe Date: Wed, 4 Feb 2015 09:57:40 -0800 Subject: [PATCH 02/92] Update Step_2.md --- Step_2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Step_2.md b/Step_2.md index dd134a989c5..32c578f18a9 100644 --- a/Step_2.md +++ b/Step_2.md @@ -72,7 +72,7 @@ $ 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 +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 From 99a1fe644087da862af2287c452b38b7fd4f1b9c Mon Sep 17 00:00:00 2001 From: Dan Ciruli Date: Wed, 4 Feb 2015 10:07:45 -0800 Subject: [PATCH 03/92] Fixed 2 typos. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9a668f3b1cd..c0fc227b29b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# gRPC Helloworld Tutorial +# gRPC Hello World Tutorial ## TODO: move this to the tutorial sub-folder @@ -8,7 +8,7 @@ various features of gRPC. When you finish the tutorial, you will be able to -- Create an protobuf schema that defines a simple RPC service +- 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 From cdf7f84d073ef17da2b73de53cdcc0164368e109 Mon Sep 17 00:00:00 2001 From: Mugur Marculescu Date: Wed, 4 Feb 2015 20:14:08 -0800 Subject: [PATCH 04/92] Attempt to Fix broken link to helloworld.proto Actually Fix broken link to helloworld.proto --- Step_0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Step_0.md b/Step_0.md index 02a2b04c0e3..a346f77e814 100644 --- a/Step_0.md +++ b/Step_0.md @@ -5,7 +5,7 @@ a message from a remote client. The message contains the users'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](helloworld.proto). +[helloworld.proto](src/main/proto/helloworld.proto). ``` syntax = "proto3"; From 5d8c3b264c89fb1598e4cc418e2c0c4c417d5c4b Mon Sep 17 00:00:00 2001 From: Mugur Marculescu Date: Wed, 4 Feb 2015 21:21:37 -0800 Subject: [PATCH 05/92] Fixing a couple of typos and grammer issues. --- README.md | 18 +++++++++--------- Step_0.md | 6 +++--- Step_1.md | 4 ++-- Step_2.md | 10 +++++----- Step_3.md | 16 ++++++++-------- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index c0fc227b29b..41b79ba883d 100644 --- a/README.md +++ b/README.md @@ -3,16 +3,16 @@ ## 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 simple client and server that introduces +walks you through the construction of a simple client and server and introduces various features of gRPC. When you finish the tutorial, you will be able to -- 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 +- 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. # Get Started @@ -22,7 +22,7 @@ If you just want to read the tutorial, you can go straight to the next step: [St # Working with the code You can follow along with this tutorial and hack on the code in the comfort of -your own computer. In this way you can get hands-on practice of really writing +your own computer. This way you can get hands-on practice of really writing gRPC code. The tutorial relies on the use of the Git versioning system for source code @@ -61,7 +61,7 @@ for instructions. # Install Maven -To simplify building and the managing of gRPC's dependencies, the java client +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. @@ -76,6 +76,6 @@ Go gRPC requires Go 1.4, the latest version of Go. See gRPC uses the latest version of the protocol buffer 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 +generated code is checked into the Git repository. If you want to experiment with generating the code yourself, download and install protoc from its [Git repo](https://github.com/google/protobuf) diff --git a/Step_0.md b/Step_0.md index a346f77e814..07c5bc5690f 100644 --- a/Step_0.md +++ b/Step_0.md @@ -1,10 +1,10 @@ # 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 users's name and +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 +It's shown below in full; it's actually contained in separate file. [helloworld.proto](src/main/proto/helloworld.proto). ``` @@ -33,7 +33,7 @@ service Greeting { ``` The service stanza of the message is an example of protobuf service IDL -(Interface Defintion Language). Here, it defines a simple service that +(Interface Defintion Language). Here, it defines a simple service that receives a request containing a name and returns a response containing a message. diff --git a/Step_1.md b/Step_1.md index da85cb4e10f..c7aed326c38 100644 --- a/Step_1.md +++ b/Step_1.md @@ -1,6 +1,6 @@ # Step-1: Generate a service client. -In this step, we use protoc to generate the java Stub classes. A Stub is the +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. @@ -11,7 +11,7 @@ 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 +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: diff --git a/Step_2.md b/Step_2.md index 32c578f18a9..eafe70b6923 100644 --- a/Step_2.md +++ b/Step_2.md @@ -1,15 +1,15 @@ # 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). +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 +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. +service. The channel in turn is used to construct the Stub. ``` @@ -77,7 +77,7 @@ 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 +- 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 diff --git a/Step_3.md b/Step_3.md index 56d6e7cfd3a..bba8f0aa3fb 100644 --- a/Step_3.md +++ b/Step_3.md @@ -1,16 +1,16 @@ # Step-3: Implement a server. This step extends the generated server skeleton code to write a simple server -that provides the hello service. This in introduces two new classes +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 to accessed over the network: [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.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 -[GreetingsSImpl.java](src/main/java/ex/grpc/GreetingsImpl.java) -implements the behaviour we require of our GreetingService. There are a +[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: ``` @@ -39,7 +39,7 @@ number of important features of gRPC being used here: ## Server implementation [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java) shows the -other main feature to required to provde gRPC service; how to allow a service +other main feature required to provde the gRPC service; how to allow a service implementation to be accessed from the network. ``` @@ -68,14 +68,14 @@ $ 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. +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 ``` -In another termainal window and confirm that it receives a message. +and in another termainal window and confirm that it receives a message. ``` $ ./run_greetings_client.sh From d2828d9b1b0341e068741516fc91702a96844519 Mon Sep 17 00:00:00 2001 From: Mugur Marculescu Date: Wed, 4 Feb 2015 21:50:56 -0800 Subject: [PATCH 06/92] Another grammar fix. --- Step_3.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Step_3.md b/Step_3.md index bba8f0aa3fb..d2d7f4788db 100644 --- a/Step_3.md +++ b/Step_3.md @@ -75,7 +75,7 @@ that they are built, you can run the server with: $ ./run_greetings_server.sh ``` -and in another termainal window and confirm that it receives a message. +and in another termainal window confirm that it receives a message. ``` $ ./run_greetings_client.sh From 8c92a90a4a3bdd0bd5ec37b7f9ad412cd0cd7f1f Mon Sep 17 00:00:00 2001 From: Mugur Marculescu Date: Wed, 4 Feb 2015 21:52:45 -0800 Subject: [PATCH 07/92] Another typo fix. --- Step_3.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Step_3.md b/Step_3.md index d2d7f4788db..7b03cdf585f 100644 --- a/Step_3.md +++ b/Step_3.md @@ -75,7 +75,7 @@ that they are built, you can run the server with: $ ./run_greetings_server.sh ``` -and in another termainal window confirm that it receives a message. +and in another terminal window confirm that it receives a message. ``` $ ./run_greetings_client.sh From a14935fceeaa9111579a65e85929b9a171debe43 Mon Sep 17 00:00:00 2001 From: Mugur Marculescu Date: Thu, 5 Feb 2015 16:14:17 -0800 Subject: [PATCH 08/92] Another typo. --- Step_0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Step_0.md b/Step_0.md index 07c5bc5690f..d0745b0dd1f 100644 --- a/Step_0.md +++ b/Step_0.md @@ -33,7 +33,7 @@ service Greeting { ``` The service stanza of the message is an example of protobuf service IDL -(Interface Defintion Language). Here, it defines a simple service that +(Interface Definition Language). Here, it defines a simple service that receives a request containing a name and returns a response containing a message. From 8f505f74e420a5fe52cf084a55117f5c73e11774 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 5 Feb 2015 17:34:47 -0800 Subject: [PATCH 09/92] Adds the common protos along with a README.md --- protos/README.md | 12 +++++++ protos/helloworld.proto | 51 ++++++++++++++++++++++++++ protos/math.proto | 79 +++++++++++++++++++++++++++++++++++++++++ protos/stock.proto | 71 ++++++++++++++++++++++++++++++++++++ 4 files changed, 213 insertions(+) create mode 100644 protos/README.md create mode 100644 protos/helloworld.proto create mode 100644 protos/math.proto create mode 100644 protos/stock.proto diff --git a/protos/README.md b/protos/README.md new file mode 100644 index 00000000000..29639a68f44 --- /dev/null +++ b/protos/README.md @@ -0,0 +1,12 @@ +# Example protos + +## Contents + +- helloworld.proto + A very simple example used in the overview. + +- stock.proto + A detailed example that's described in detail in the tutorial. + +- math.proto + Another detailed example for further reference. diff --git a/protos/helloworld.proto b/protos/helloworld.proto new file mode 100644 index 00000000000..aa44b851f43 --- /dev/null +++ b/protos/helloworld.proto @@ -0,0 +1,51 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "ex.grpc"; + +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 Greetings { + // Sends a greeting + rpc hello (HelloRequest) returns (HelloReply) { + } +} diff --git a/protos/math.proto b/protos/math.proto new file mode 100644 index 00000000000..46a33aeee53 --- /dev/null +++ b/protos/math.proto @@ -0,0 +1,79 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package math; + +message DivArgs { + optional int64 dividend = 1; + optional int64 divisor = 2; +} + +message DivReply { + optional int64 quotient = 1; + optional int64 remainder = 2; +} + +message FibArgs { + optional int64 limit = 1; +} + +message Num { + optional int64 num = 1; +} + +message FibReply { + optional int64 count = 1; +} + +service Math { + // Div divides args.dividend by args.divisor and returns the quotient and + // remainder. + rpc Div (DivArgs) returns (DivReply) { + } + + // DivMany accepts an arbitrary number of division args from the client stream + // and sends back the results in the reply stream. The stream continues until + // the client closes its end; the server does the same after sending all the + // replies. The stream ends immediately if either end aborts. + rpc DivMany (stream DivArgs) returns (stream DivReply) { + } + + // Fib generates numbers in the Fibonacci sequence. If args.limit > 0, Fib + // generates up to limit numbers; otherwise it continues until the call is + // canceled. + rpc Fib (FibArgs) returns (stream Num) { + } + + // Sum sums a stream of numbers, returning the final result once the stream + // is closed. + rpc Sum (stream Num) returns (Num) { + } +} diff --git a/protos/stock.proto b/protos/stock.proto new file mode 100644 index 00000000000..dcb677e4733 --- /dev/null +++ b/protos/stock.proto @@ -0,0 +1,71 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package examples; + +// Protocol type definitions +message StockRequest { + optional string symbol = 1; + optional int32 num_trades_to_watch = 2; +}; + +message StockReply { + optional float price = 1; + optional string symbol = 2; +}; + +// Interface exported by the server +service Stock { + // A simple blocking RPC. + // + // Obtains the last traded price for the given Stock. + rpc GetLastTradePrice(StockRequest) returns (StockReply) { + }; + + // A Unidirectional server-to-client streaming RPC. + // + // Streams future prices for a given symbol. + rpc WatchFutureTrades(StockRequest) returns (stream StockReply) { + }; + + // A Unidirectional client-to-server streaming RPC. + // + // Gets the highest traded price for a series of symbols + rpc GetHighestTradePrice(stream StockRequest) returns (StockReply) { + }; + + // Bidirectional streaming RPC. + // + // Gets the most recent traded price of series of trades. + rpc GetLastTradePriceMultiple(stream StockRequest) returns + (stream StockReply) { + }; +}; From bb9e6f4e7ce17d5a06e10a487e65ed6a1473155a Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 6 Feb 2015 12:56:33 -0800 Subject: [PATCH 10/92] removed superfluous semi-colons --- protos/stock.proto | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/protos/stock.proto b/protos/stock.proto index dcb677e4733..49efbf2730a 100644 --- a/protos/stock.proto +++ b/protos/stock.proto @@ -35,12 +35,12 @@ package examples; message StockRequest { optional string symbol = 1; optional int32 num_trades_to_watch = 2; -}; +} message StockReply { optional float price = 1; optional string symbol = 2; -}; +} // Interface exported by the server service Stock { @@ -48,24 +48,24 @@ service Stock { // // Obtains the last traded price for the given Stock. rpc GetLastTradePrice(StockRequest) returns (StockReply) { - }; + } // A Unidirectional server-to-client streaming RPC. // // Streams future prices for a given symbol. rpc WatchFutureTrades(StockRequest) returns (stream StockReply) { - }; + } // A Unidirectional client-to-server streaming RPC. // // Gets the highest traded price for a series of symbols rpc GetHighestTradePrice(stream StockRequest) returns (StockReply) { - }; + } // Bidirectional streaming RPC. // // Gets the most recent traded price of series of trades. rpc GetLastTradePriceMultiple(stream StockRequest) returns (stream StockReply) { - }; -}; + } +} From aa7afd63a8611c1e64de21d54da0eeb86a0c8360 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 6 Feb 2015 13:09:20 -0800 Subject: [PATCH 11/92] Moves java overview project to a subdirectory --- pom.xml => java/pom.xml | 0 run_greetings_client.sh => java/run_greetings_client.sh | 0 run_greetings_server.sh => java/run_greetings_server.sh | 0 {src => java/src}/main/java/ex/grpc/GreetingsClient.java | 0 {src => java/src}/main/java/ex/grpc/GreetingsGrpc.java | 0 {src => java/src}/main/java/ex/grpc/GreetingsImpl.java | 0 {src => java/src}/main/java/ex/grpc/GreetingsServer.java | 0 {src => java/src}/main/java/ex/grpc/Helloworld.java | 0 {src => java/src}/main/proto/helloworld.proto | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename pom.xml => java/pom.xml (100%) rename run_greetings_client.sh => java/run_greetings_client.sh (100%) rename run_greetings_server.sh => java/run_greetings_server.sh (100%) rename {src => java/src}/main/java/ex/grpc/GreetingsClient.java (100%) rename {src => java/src}/main/java/ex/grpc/GreetingsGrpc.java (100%) rename {src => java/src}/main/java/ex/grpc/GreetingsImpl.java (100%) rename {src => java/src}/main/java/ex/grpc/GreetingsServer.java (100%) rename {src => java/src}/main/java/ex/grpc/Helloworld.java (100%) rename {src => java/src}/main/proto/helloworld.proto (100%) diff --git a/pom.xml b/java/pom.xml similarity index 100% rename from pom.xml rename to java/pom.xml diff --git a/run_greetings_client.sh b/java/run_greetings_client.sh similarity index 100% rename from run_greetings_client.sh rename to java/run_greetings_client.sh diff --git a/run_greetings_server.sh b/java/run_greetings_server.sh similarity index 100% rename from run_greetings_server.sh rename to java/run_greetings_server.sh diff --git a/src/main/java/ex/grpc/GreetingsClient.java b/java/src/main/java/ex/grpc/GreetingsClient.java similarity index 100% rename from src/main/java/ex/grpc/GreetingsClient.java rename to java/src/main/java/ex/grpc/GreetingsClient.java diff --git a/src/main/java/ex/grpc/GreetingsGrpc.java b/java/src/main/java/ex/grpc/GreetingsGrpc.java similarity index 100% rename from src/main/java/ex/grpc/GreetingsGrpc.java rename to java/src/main/java/ex/grpc/GreetingsGrpc.java diff --git a/src/main/java/ex/grpc/GreetingsImpl.java b/java/src/main/java/ex/grpc/GreetingsImpl.java similarity index 100% rename from src/main/java/ex/grpc/GreetingsImpl.java rename to java/src/main/java/ex/grpc/GreetingsImpl.java diff --git a/src/main/java/ex/grpc/GreetingsServer.java b/java/src/main/java/ex/grpc/GreetingsServer.java similarity index 100% rename from src/main/java/ex/grpc/GreetingsServer.java rename to java/src/main/java/ex/grpc/GreetingsServer.java diff --git a/src/main/java/ex/grpc/Helloworld.java b/java/src/main/java/ex/grpc/Helloworld.java similarity index 100% rename from src/main/java/ex/grpc/Helloworld.java rename to java/src/main/java/ex/grpc/Helloworld.java diff --git a/src/main/proto/helloworld.proto b/java/src/main/proto/helloworld.proto similarity index 100% rename from src/main/proto/helloworld.proto rename to java/src/main/proto/helloworld.proto From c509d3545531f1424335123670c9bcf9ca5ba934 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 6 Feb 2015 13:21:36 -0800 Subject: [PATCH 12/92] Updates the references to the moved java source files. - Also specifies the what type of source is being rendered in the syntax-highlighted sections --- Step_1.md | 9 ++++----- Step_2.md | 2 +- Step_3.md | 23 ++++++++++++----------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Step_1.md b/Step_1.md index c7aed326c38..1e9ca2b2a50 100644 --- a/Step_1.md +++ b/Step_1.md @@ -15,18 +15,17 @@ 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: -``` +```sh $ pushd external/grpc_java $ make java_plugin $ popd ``` To use it to generate the code: -``` -$ mkdir -p src/main/java +```sh $ 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 + --grpc_out=java/src/main/java \ + --java_out=java/src/main/java ``` Next, in [Step - 2](Step_2.md), we'll use the generated Stub implementation to diff --git a/Step_2.md b/Step_2.md index eafe70b6923..d2e1ae48b05 100644 --- a/Step_2.md +++ b/Step_2.md @@ -1,7 +1,7 @@ # 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). +service. The full client is in [GreetingsClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). ## Configuring the service to connect to. diff --git a/Step_3.md b/Step_3.md index 7b03cdf585f..9eb1009d2e6 100644 --- a/Step_3.md +++ b/Step_3.md @@ -3,17 +3,17 @@ 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 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). +- a server that hosts the service implementation and allows access over the network: [GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java). ## Service implementation -[GreetingsImpl.java](src/main/java/ex/grpc/GreetingsImpl.java) +[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: -``` +```java public void hello(Helloworld.HelloRequest req, StreamObserver responseObserver) { Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( @@ -24,7 +24,7 @@ number of important features of gRPC being used here: ``` - 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) +- `GreetingsGrpc.Greetings` declares the method `hello` that was declared in the proto [IDL](java/src/main/proto/helloworld.proto) - `hello's` signature is typesafe: hello(Helloworld.HelloRequest req, StreamObserver responseObserver) - `hello` takes two parameters: @@ -38,11 +38,11 @@ number of important features of gRPC being used here: ## Server implementation -[GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java) shows the +[GreetingsServer.java](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. -``` +```java private void start() throws Exception { server = NettyServerBuilder.forPort(port) .addService(GreetingsGrpc.bindService(new GreetingsImpl())) @@ -62,7 +62,8 @@ implementation to be accessed from the network. This is the same as before: our client and server are part of the same maven package so the same command builds both. -``` +```sh +$ cd java $ mvn package ``` @@ -71,12 +72,12 @@ $ 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. -``` -$ ./run_greetings_client.sh +```sh +$ ./java/run_greetings_client.sh ``` From f751995e86eacf7a475f7fb7ee52d2e45ab0b599 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 6 Feb 2015 13:59:50 -0800 Subject: [PATCH 13/92] Update README.md --- protos/README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/protos/README.md b/protos/README.md index 29639a68f44..374d4350aca 100644 --- a/protos/README.md +++ b/protos/README.md @@ -3,10 +3,8 @@ ## Contents - helloworld.proto - A very simple example used in the overview. - + - A very simple example used in the overview. - stock.proto - A detailed example that's described in detail in the tutorial. - + - A detailed example that's described in detail in the tutorial. - math.proto - Another detailed example for further reference. + - Another detailed example for further reference. From cf6360377c9d42f66b8940f6006c503f276907da Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 9 Feb 2015 17:14:14 +0000 Subject: [PATCH 14/92] 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 15/92] 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 16/92] 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 17/92] 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 18/92] 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 19/92] 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 20/92] 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 21/92] 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 22/92] 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 ``` From 8e9a709d47fcf79379cb04fa0d98a03f5915f8b4 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Thu, 12 Feb 2015 17:48:42 +0000 Subject: [PATCH 23/92] More tidying up of example... --- README.md | 70 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index c7c896db61d..bd0738447a8 100644 --- a/README.md +++ b/README.md @@ -118,10 +118,11 @@ 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](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 +[helloworld.proto](java/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`. +a greeting in a single `HelloReply`. This is the simplest type of RPC you +can specify in gRPC - we'll look at some other types later in this document. ``` syntax = "proto3"; @@ -167,7 +168,8 @@ this up in "what is gRPC"?] 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 +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. @@ -190,17 +192,22 @@ $ protoc -I . helloworld.proto --java_out=src/main/java ``` -This generates the following classes, which contain all the generated code we need to create our example: +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): +- [`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 ```java public static interface Greetings { public void hello(ex.grpc.Helloworld.HelloRequest request, - com.google.net.stubby.stub.StreamObserver responseObserver); + com.google.net.stubby.stub.StreamObserver + responseObserver); } ``` @@ -208,7 +215,8 @@ This generates the following classes, which contain all the generated code we ne ```java public static class GreetingsStub extends - com.google.net.stubby.stub.AbstractStub + com.google.net.stubby.stub.AbstractStub implements Greetings { ... } @@ -217,48 +225,58 @@ public static class GreetingsStub extends ### Writing a 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). +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 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). +- 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: +actually implements our GreetingService's required behaviour. + +As you can see, the class `GreetingsImpl` implements the interface +`GreetingsGrpc.Greetings` that we [generated](#generating) from our proto +[IDL](src/main/proto/helloworld.proto) by implementing the method `hello`: ```java public void hello(Helloworld.HelloRequest req, StreamObserver responseObserver) { - Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( + 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(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. + -`Helloworld.HelloRequest`: the request + -`StreamObserver`: 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 call `responseObserver.onValue()` with the `HelloReply` that we want to send back to the client. +3. Finally, we call `responseObserver.onCompleted()` to indicate that we're +finished dealing with this 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. +other main feature required to provde the gRPC service; making the service +implementation available from the network. ```java private void start() throws Exception { From 2fdb96388faa6ef94fd768ba921dcf0a3ffe9a39 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Thu, 12 Feb 2015 17:51:13 +0000 Subject: [PATCH 24/92] Style tweaks --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bd0738447a8..89e8d2942c3 100644 --- a/README.md +++ b/README.md @@ -264,11 +264,12 @@ As you can see, the class `GreetingsImpl` implements the interface -`Helloworld.HelloRequest`: the request -`StreamObserver`: 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 + 1. We construct and populate a `HelloReply` response object with our exciting message, as specified in our interface definition. -2. We call `responseObserver.onValue()` with the `HelloReply` that we want to send back to the client. -3. Finally, we call `responseObserver.onCompleted()` to indicate that we're + 2. We call `responseObserver.onValue()` with the `HelloReply` that we want to send back to the client. + 3. Finally, we call `responseObserver.onCompleted()` to indicate that we're finished dealing with this RPC. From 034eb2e8097262ee9a6a543f47ab9baa15a92b92 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 11:05:25 +0000 Subject: [PATCH 25/92] Markdown, I hate you. --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 89e8d2942c3..cc0ce4943fd 100644 --- a/README.md +++ b/README.md @@ -213,14 +213,14 @@ which contains (along with some other useful code): - _stub_ classes that clients can use to talk to a `Greetings` server. - ```java +```java public static class GreetingsStub extends com.google.net.stubby.stub.AbstractStub implements Greetings { ... } - ``` +``` ### Writing a server @@ -266,6 +266,7 @@ As you can see, the class `GreetingsImpl` implements the interface 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 call `responseObserver.onValue()` with the `HelloReply` that we want to send back to the client. From 31d143ce0745b485b315c56c1715dc46fe060a5e Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 11:07:16 +0000 Subject: [PATCH 26/92] AAAAAAARRRGHHHHH --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index cc0ce4943fd..16304f65eb3 100644 --- a/README.md +++ b/README.md @@ -213,14 +213,14 @@ which contains (along with some other useful code): - _stub_ classes that clients can use to talk to a `Greetings` server. -```java + ```java public static class GreetingsStub extends com.google.net.stubby.stub.AbstractStub implements Greetings { ... } -``` + ``` ### Writing a server @@ -267,10 +267,10 @@ As you can see, the class `GreetingsImpl` implements the interface 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. - 2. We call `responseObserver.onValue()` with the `HelloReply` that we want to send back to the client. - 3. Finally, we call `responseObserver.onCompleted()` to indicate that we're +2. We call `responseObserver.onValue()` with the `HelloReply` that we want to send back to the client. +3. Finally, we call `responseObserver.onCompleted()` to indicate that we're finished dealing with this RPC. From 0af588a9cf75fd5769bb3bca5a978a3463f80668 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 15:42:03 +0000 Subject: [PATCH 27/92] More tidying up of existing text --- README.md | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 16304f65eb3..8f6fd5cc6d5 100644 --- a/README.md +++ b/README.md @@ -211,7 +211,7 @@ which contains (along with some other useful code): } ``` - - _stub_ classes that clients can use to talk to a `Greetings` server. + - _stub_ classes that clients can use to talk to a `Greetings` server. As you can see, they also implement the `Greetings` interface. ```java public static class GreetingsStub extends @@ -236,7 +236,7 @@ Our server application has two classes: [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). +network: [GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java). #### Service implementation @@ -245,7 +245,7 @@ actually implements our GreetingService's required behaviour. As you can see, the class `GreetingsImpl` implements the interface `GreetingsGrpc.Greetings` that we [generated](#generating) from our proto -[IDL](src/main/proto/helloworld.proto) by implementing the method `hello`: +[IDL](java/src/main/proto/helloworld.proto) by implementing the method `hello`: ```java public void hello(Helloworld.HelloRequest req, @@ -276,11 +276,13 @@ finished dealing with this RPC. #### Server implementation -[GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java) shows the -other main feature required to provde the gRPC service; making the service +[GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) shows the +other main feature required to provide a gRPC service; making the service implementation available from the network. ```java + private ServerImpl server; + ... private void start() throws Exception { server = NettyServerBuilder.forPort(port) .addService(GreetingsGrpc.bindService(new GreetingsImpl())) @@ -291,9 +293,9 @@ implementation available from the network. ``` -- 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 +The `GreetingsServer` class has a `ServerImpl` member that actually runs the server. To create an appropriate `ServerImpl`, we use a special `ServerBuilder` class (in this case a `NettyServerBuilder`) in the `GreetingsServer`'s `start` method, binding the `GreetingsService` implementation that we created to a port. Then we start the server running: the server is now ready to receive requests from `Greetings` service clients on our specified port. We'll cover how all this works in a bit more detail in our language-specific documentation. + +`GreetingsServer` also has a `stop` method that takes care of shutting down the service and cleaning up when the program exits. #### Build it @@ -308,16 +310,16 @@ We'll look at using a client to access the server in the next section. ### 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](#server). You can see the complete client code in [GreetingsClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). 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 -. The internet address -is configured in the client constructor. gRPC Channel is the abstraction over +First let's look at how we connect to the `Greetings` server. The internet address +is configured in the client constructor. gRPC `Channel` provides the abstraction layer over transport handling; its constructor accepts the host name and port of the -service. The channel in turn is used to construct the Stub. +service. The channel in turn is used to construct the stub instance. ```java @@ -335,11 +337,11 @@ service. The channel in turn is used to construct the Stub. #### 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 +The `greet()` method uses the stub to contact the service and obtain a greeting. +In the method we: +- construct and fill in a `HelloRequest` to send to the stub +- get a reply from the stub +- print out the greeting ```java @@ -375,7 +377,7 @@ line. #### Build the client -This is the same as before: our client and server are part of the same maven +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. ``` @@ -407,6 +409,10 @@ and in another terminal window confirm that it receives a message. $ ./run_greetings_client.sh ``` +### Adding another client + +###TODO: Section on Go client for same server + From 26e6d380abce8fd667597acb0c7f785e33beac79 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 15:45:10 +0000 Subject: [PATCH 28/92] Bit of tidying up... --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8f6fd5cc6d5..72a8de9eb06 100644 --- a/README.md +++ b/README.md @@ -338,10 +338,10 @@ service. The channel in turn is used to construct the stub instance. #### Obtaining a greeting The `greet()` method uses the stub to contact the service and obtain a greeting. -In the method we: -- construct and fill in a `HelloRequest` to send to the stub -- get a reply from the stub -- print out the greeting +To do this: + +1. We construct and fill in a `HelloRequest` to send to the stub. +2. We call the RPC with our request and get a `HelloReply` from the stub, from which we can get our greeting. ```java From 27da19feb43157260195732a8f63a5bc3545475b Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 15:58:20 +0000 Subject: [PATCH 29/92] Bit more tidying up --- README.md | 57 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 72a8de9eb06..e3719357ea5 100644 --- a/README.md +++ b/README.md @@ -276,8 +276,8 @@ finished dealing with this RPC. #### Server implementation -[GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) shows the -other main feature required to provide a gRPC service; making the service +[GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) +shows the other main feature required to provide a gRPC service; making the service implementation available from the network. ```java @@ -293,9 +293,16 @@ implementation available from the network. ``` -The `GreetingsServer` class has a `ServerImpl` member that actually runs the server. To create an appropriate `ServerImpl`, we use a special `ServerBuilder` class (in this case a `NettyServerBuilder`) in the `GreetingsServer`'s `start` method, binding the `GreetingsService` implementation that we created to a port. Then we start the server running: the server is now ready to receive requests from `Greetings` service clients on our specified port. We'll cover how all this works in a bit more detail in our language-specific documentation. +The `GreetingsServer` class has a `ServerImpl` member that actually runs the +server. To create an appropriate `ServerImpl`, we use a special `ServerBuilder` +class (in this case a `NettyServerBuilder`) in the `GreetingsServer`'s `start` +method, binding the `GreetingsService` implementation that we created to a +port. Then we start the server running: the server is now ready to receive +requests from `Greetings` service clients on our specified port. We'll cover +how all this works in a bit more detail in our language-specific documentation. -`GreetingsServer` also has a `stop` method that takes care of shutting down the service and cleaning up when the program exits. +`GreetingsServer` also has a `stop` method that takes care of shutting down +the service and cleaning up when the program exits. #### Build it @@ -310,14 +317,20 @@ We'll look at using a client to access the server in the next section. ### 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](#server). You can see the complete client code in [GreetingsClient.java](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](#server). You can see the complete client code in +[GreetingsClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). -Again, 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 -First let's look at how we connect to the `Greetings` server. The internet address -is configured in the client constructor. gRPC `Channel` provides the abstraction layer over +First let's look at how we connect to the `Greetings` server. The internet +address +is configured in the client constructor. gRPC `Channel` provides the +abstraction layer over transport handling; its constructor accepts the host name and port of the service. The channel in turn is used to construct the stub instance. @@ -335,20 +348,28 @@ service. The channel in turn is used to construct the stub instance. ``` +In this case, we create 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. + #### Obtaining a greeting -The `greet()` method uses the stub to contact the service and obtain a greeting. +The `greet()` method uses the stub to contact the service and obtain +a greeting. To do this: 1. We construct and fill in a `HelloRequest` to send to the stub. -2. We call the RPC with our request and get a `HelloReply` from the stub, from which we can get our greeting. +2. We call the RPC with our request and get a `HelloReply` from the stub, +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.HelloRequest request = + Helloworld.HelloRequest.newBuilder().setName(name).build(); Helloworld.HelloReply reply = blockingStub.hello(request); logger.info("Greeting: " + reply.getMessage()); } catch (RuntimeException e) { @@ -377,22 +398,14 @@ line. #### Build the client -This is the same as building the server: our client and server are part of the same maven +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 ``` -#### 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. - ### Try it out! @@ -409,7 +422,7 @@ and in another terminal window confirm that it receives a message. $ ./run_greetings_client.sh ``` -### Adding another client +### Adding another client ###TODO: Section on Go client for same server From 461780145938e452e113f4eb951c3a28ff69b214 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 16:38:49 +0000 Subject: [PATCH 30/92] Starting intro --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index e3719357ea5..592e1663f73 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,33 @@ Hello World example. More documentation is coming soon! ## What is gRPC? +gRPC is It enables communication between clients and servers using any combination of gRPC's supported languages, helping you to build distributed applications and services. + +In gRPC, like + +### Plays well with Protocol Buffers + +While gRPC’s architecture allows it to be extended for use with other +data formats such as JSON, by default it uses protocol buffers, Google’s +mature open source mechanism for serializing structured data. As you'll +see in our example below, you define gRPC interfaces using proto files and +protocol buffer messages, letting you take advantage of protocol buffers’ +efficient serialization, simple IDL, and easy interface updating. You +can find out lots more about protocol buffers in the [Protocol Buffers +documentation](https://developers.google.com/protocol-buffers/docs/overview). + +Note that our examples use a new flavour of protocol buffers called proto3, +which has a slightly simplified syntax, some useful new features, and supports +lots more languages. This is currently available as an alpha release in +[languages] from [wherever it's going], with more languages in development. In +general, we recommend that you use proto3 with gRPC as it lets you use the +full range of gRPC-supported languages, as well as avoiding any compatibility +issues with proto2 clients talking to proto3 servers and vice versa. + +If you need to continue using proto2 for Java, C++, or Python but want +to try gRPC, you can see an example using a proto2 gRPC client and server +[wherever we put it]. + ## TODO: basic conceptual intro (anything more in-depth will go in gRPC Concepts doc) From bdcda72cec23554d5ef1dd5695de9e97e8bb3235 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 16:40:23 +0000 Subject: [PATCH 31/92] Fixed typo --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 592e1663f73..413f5008a2f 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,9 @@ Hello World example. More documentation is coming soon! ## What is gRPC? -gRPC is It enables communication between clients and servers using any combination of gRPC's supported languages, helping you to build distributed applications and services. +gRPC enables communication between clients and servers using any combination of gRPC's supported languages, helping you to build distributed applications and services. -In gRPC, like +In gRPC, like other RPC systems... ### Plays well with Protocol Buffers @@ -46,7 +46,7 @@ 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 +- Create a protocol buffers 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. From 907119eafd930085c8067e7bdaabbe294cef9605 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 16:52:03 +0000 Subject: [PATCH 32/92] Intro tweaks --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 413f5008a2f..2d3a3a8f5b5 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,7 @@ Hello World example. More documentation is coming soon! ## What is gRPC? -gRPC enables communication between clients and servers using any combination of gRPC's supported languages, helping you to build distributed applications and services. - -In gRPC, like other RPC systems... +In gRPC, like other RPC systems, a *client* application can directly call methods on a *server* application on a different machine as if it was a local object, making it easier for you to create distributed applications and services. gRPC clients and servers can run and talk to each other in a variety of environments - from servers inside Google to your own desktop - and can be written in any of gRPC's supported languages. So, for example, you can easily create a gRPC server in Java with clients in Go, Python, or Ruby. ### Plays well with Protocol Buffers @@ -68,9 +66,8 @@ 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](#servicedef). +This section 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](#servicedef). #### Install Git From e82f310a440c75e5234c4aa6b0028ec5b550d8df Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Tue, 17 Feb 2015 16:27:51 +0000 Subject: [PATCH 33/92] Added a simple overview/protocol buffers information --- README.md | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 2d3a3a8f5b5..a1575392e02 100644 --- a/README.md +++ b/README.md @@ -10,32 +10,34 @@ Hello World example. More documentation is coming soon! ## What is gRPC? -In gRPC, like other RPC systems, a *client* application can directly call methods on a *server* application on a different machine as if it was a local object, making it easier for you to create distributed applications and services. gRPC clients and servers can run and talk to each other in a variety of environments - from servers inside Google to your own desktop - and can be written in any of gRPC's supported languages. So, for example, you can easily create a gRPC server in Java with clients in Go, Python, or Ruby. +In gRPC, like other RPC systems, a *client* application can directly call methods on a *server* application on a different machine as if it was a local object, making it easier for you to create distributed applications and services. As in many RPC systems, gRPC is based around the idea of defining a *service*, specifying the methods that can be called remotely with their parameters and return types. On the server side, the server implements this interface and runs a gRPC server to handle client calls. On the client side, the client has a *stub* that provides exactly the same methods as the server. -### Plays well with Protocol Buffers +##TODO: diagram? + +gRPC clients and servers can run and talk to each other in a variety of environments - from servers inside Google to your own desktop - and can be written in any of gRPC's [supported languages](link to list). So, for example, you can easily create a gRPC server in Java with clients in Go, Python, or Ruby. In addition, the latest Google APIs will have gRPC versions of their interfaces, letting you easily build Google functionality into your applications. + + +### Working with protocol buffers While gRPC’s architecture allows it to be extended for use with other -data formats such as JSON, by default it uses protocol buffers, Google’s +data formats such as JSON, by default it uses *protocol buffers*, Google’s mature open source mechanism for serializing structured data. As you'll -see in our example below, you define gRPC interfaces using proto files and -protocol buffer messages, letting you take advantage of protocol buffers’ -efficient serialization, simple IDL, and easy interface updating. You -can find out lots more about protocol buffers in the [Protocol Buffers -documentation](https://developers.google.com/protocol-buffers/docs/overview). +see in our example below, you define gRPC services using *proto files*, with method parameters and return types specified as protocol buffer message types. You +can find out lots more about protocol buffers in the [Protocol Buffers documentation](https://developers.google.com/protocol-buffers/docs/overview). + +#### Protocol buffer versions -Note that our examples use a new flavour of protocol buffers called proto3, +While protocol buffers have been available for open source users for some time, our examples use a new flavour of protocol buffers called proto3, which has a slightly simplified syntax, some useful new features, and supports lots more languages. This is currently available as an alpha release in -[languages] from [wherever it's going], with more languages in development. In -general, we recommend that you use proto3 with gRPC as it lets you use the -full range of gRPC-supported languages, as well as avoiding any compatibility -issues with proto2 clients talking to proto3 servers and vice versa. +[languages] from [wherever it's going], with more languages in development. -If you need to continue using proto2 for Java, C++, or Python but want +In general, we recommend that you use proto3 with gRPC as it lets you use the +full range of gRPC-supported languages, as well as avoiding compatibility +issues with proto2 clients talking to proto3 servers and vice versa. You can find out more about these potential issues in [where should we put this info? It's important but not really part of an overview]. If you need to continue using proto2 for Java, C++, or Python but want to try gRPC, you can see an example using a proto2 gRPC client and server [wherever we put it]. -## TODO: basic conceptual intro (anything more in-depth will go in gRPC Concepts doc) ## Hello gRPC! @@ -46,9 +48,9 @@ construction of a simple gRPC client-server application, showing you how to: - Create a protocol buffers 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 server that implements thid interface. - Create a Java client that accesses the Java server. -- Create a Go client that accesses the same Java server. +- Create a [probably need a different language now] 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 the `grpc-common` GitHub repository. You can @@ -134,12 +136,9 @@ with generating the code yourself, download and install protoc from its 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). +and return types. As you saw in the [overview](#protocolbuffers) above, gRPC does this using [protocol buffers]((https://developers.google.com/protocol-buffers/docs/overview). We use the protocol buffers interface definition language (IDL) to define our service methods, and define the parameters and return +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](java/src/main/proto/helloworld.proto). The `Greeting` service From e416242fe1fcf43c95496c10da28a0131d102457 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Tue, 17 Feb 2015 16:30:13 +0000 Subject: [PATCH 34/92] Tidy formatting --- README.md | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a1575392e02..1820becdf06 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,24 @@ Hello World example. More documentation is coming soon! ## What is gRPC? -In gRPC, like other RPC systems, a *client* application can directly call methods on a *server* application on a different machine as if it was a local object, making it easier for you to create distributed applications and services. As in many RPC systems, gRPC is based around the idea of defining a *service*, specifying the methods that can be called remotely with their parameters and return types. On the server side, the server implements this interface and runs a gRPC server to handle client calls. On the client side, the client has a *stub* that provides exactly the same methods as the server. +In gRPC, like other RPC systems, a *client* application can directly call +methods on a *server* application on a different machine as if it was a +local object, making it easier for you to create distributed applications and +services. As in many RPC systems, gRPC is based around the idea of defining +a *service*, specifying the methods that can be called remotely with their +parameters and return types. On the server side, the server implements this +interface and runs a gRPC server to handle client calls. On the client side, +the client has a *stub* that provides exactly the same methods as the server. ##TODO: diagram? -gRPC clients and servers can run and talk to each other in a variety of environments - from servers inside Google to your own desktop - and can be written in any of gRPC's [supported languages](link to list). So, for example, you can easily create a gRPC server in Java with clients in Go, Python, or Ruby. In addition, the latest Google APIs will have gRPC versions of their interfaces, letting you easily build Google functionality into your applications. +gRPC clients and servers can run and talk to each other in a variety of +environments - from servers inside Google to your own desktop - and can +be written in any of gRPC's [supported languages](link to list). So, for +example, you can easily create a gRPC server in Java with clients in Go, +Python, or Ruby. In addition, the latest Google APIs will have gRPC versions +of their interfaces, letting you easily build Google functionality into +your applications. ### Working with protocol buffers @@ -22,19 +35,26 @@ gRPC clients and servers can run and talk to each other in a variety of environm While gRPC’s architecture allows it to be extended for use with other data formats such as JSON, by default it uses *protocol buffers*, Google’s mature open source mechanism for serializing structured data. As you'll -see in our example below, you define gRPC services using *proto files*, with method parameters and return types specified as protocol buffer message types. You -can find out lots more about protocol buffers in the [Protocol Buffers documentation](https://developers.google.com/protocol-buffers/docs/overview). +see in our example below, you define gRPC services using *proto files*, +with method parameters and return types specified as protocol buffer message +types. You +can find out lots more about protocol buffers in the [Protocol Buffers +documentation](https://developers.google.com/protocol-buffers/docs/overview). #### Protocol buffer versions -While protocol buffers have been available for open source users for some time, our examples use a new flavour of protocol buffers called proto3, +While protocol buffers have been available for open source users for some +time, our examples use a new flavour of protocol buffers called proto3, which has a slightly simplified syntax, some useful new features, and supports lots more languages. This is currently available as an alpha release in [languages] from [wherever it's going], with more languages in development. In general, we recommend that you use proto3 with gRPC as it lets you use the full range of gRPC-supported languages, as well as avoiding compatibility -issues with proto2 clients talking to proto3 servers and vice versa. You can find out more about these potential issues in [where should we put this info? It's important but not really part of an overview]. If you need to continue using proto2 for Java, C++, or Python but want +issues with proto2 clients talking to proto3 servers and vice versa. You +can find out more about these potential issues in [where should we put this +info? It's important but not really part of an overview]. If you need to +continue using proto2 for Java, C++, or Python but want to try gRPC, you can see an example using a proto2 gRPC client and server [wherever we put it]. @@ -83,9 +103,11 @@ the code to hack on #### Get the source code -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 +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-common.git ``` @@ -136,13 +158,17 @@ with generating the code yourself, download and install protoc from its 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. As you saw in the [overview](#protocolbuffers) above, gRPC does this using [protocol buffers]((https://developers.google.com/protocol-buffers/docs/overview). We use the protocol buffers interface definition language (IDL) to define our service methods, and define the parameters and return +and return types. As you saw in the +[overview](#protocolbuffers) above, gRPC does this using [protocol +buffers]((https://developers.google.com/protocol-buffers/docs/overview). We +use the protocol buffers interface definition language (IDL) to define our +service methods, and define the parameters and return 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](java/src/main/proto/helloworld.proto). The `Greeting` service -has one method, `hello`, that lets the server receive a single `HelloRequest` +[helloworld.proto](java/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 single `HelloReply`. This is the simplest type of RPC you can specify in gRPC - we'll look at some other types later in this document. From b789acd2d2ce0d94064527c2890db4887140616f Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Tue, 17 Feb 2015 16:41:45 +0000 Subject: [PATCH 35/92] Fixed typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1820becdf06..fdbd1f0de02 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,7 @@ 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. As you saw in the [overview](#protocolbuffers) above, gRPC does this using [protocol -buffers]((https://developers.google.com/protocol-buffers/docs/overview). We +buffers](https://developers.google.com/protocol-buffers/docs/overview). We use the protocol buffers interface definition language (IDL) to define our service methods, and define the parameters and return types as protocol buffer message types. Both the client and the From 23307f261c68a9b1f85892720f697d44df1fc06d Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 04:12:18 -0800 Subject: [PATCH 36/92] Adds a route guide sample proto --- protos/route_guide.proto | 124 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 protos/route_guide.proto diff --git a/protos/route_guide.proto b/protos/route_guide.proto new file mode 100644 index 00000000000..0850239d014 --- /dev/null +++ b/protos/route_guide.proto @@ -0,0 +1,124 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "ex.grpc"; + +package examples; + +// Points are represented as latitude-longitude pairs in the E7 representation +// (degrees multiplied by 10**7 and rounded to the nearest integer). +// Latitudes should be in the range +/- 90 degrees and longitude should be in +// the range +/- 180 degrees (inclusive). +message Point { + optional int32 latitude = 1; + optional int32 longitude = 2; +} + +// A latitude-longitude rectangle, represented as two diagonally opposite +// points "lo" and "hi". +message Rectangle { + // One corner of the rectangle. + optional Point lo = 1; + + // The other corner of the rectangle. + optional Point hi = 2; +} + +// A feature names something at a given point. +// +// If a feature could not be named, the name value is blank. +message Feature { + // The name of the feature. + optional string name = 1; + + // The point where the feature is detected. + optional Point location = 2; +} + +// A RouteNote is a message sent while at a given point. +message RouteNote { + // The location at from which the message is sent. + optional Point location = 1; + + // The message to be sent + optional string message = 2; +} + +// Route summary is the message received in response to a RecordRoute rpc. +// +// It details the number of individual points received, the number of detected +// features and the total distance covered as the cumulative sum of the +// distance between each point. +message RouteSummary { + // The number of points received. + optional int32 point_count = 1; + + // The number of known features passed while traversing the route. + optional int32 feature_count = 2; + + // The distance covered in metres. + optional int32 distance = 3; + + // The duration of the traversal in seconds. + optional int32 elapsed_time = 4; +} + +// Interface exported by the server +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) { + } + + // A server-to-client streaming RPC. + // + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) { + } + + // A client-to-server streaming RPC. + // + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) { + } + + // Bidirectional streaming RPC. + // + // Accepts a streams of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) { + } +} From 9ab2c8b5bac6d2fd905a9ca341d3d44b935ae994 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 08:08:15 -0800 Subject: [PATCH 37/92] Another pass at the docs --- protos/route_guide.proto | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/protos/route_guide.proto b/protos/route_guide.proto index 0850239d014..57576937a6f 100644 --- a/protos/route_guide.proto +++ b/protos/route_guide.proto @@ -54,7 +54,7 @@ message Rectangle { // A feature names something at a given point. // -// If a feature could not be named, the name value is blank. +// If a feature could not be named, the name is empty. message Feature { // The name of the feature. optional string name = 1; @@ -65,18 +65,18 @@ message Feature { // A RouteNote is a message sent while at a given point. message RouteNote { - // The location at from which the message is sent. + // The location from which the message is sent. optional Point location = 1; - // The message to be sent + // The message to be sent. optional string message = 2; } -// Route summary is the message received in response to a RecordRoute rpc. +// A RouteSummary is received in response to a RecordRoute rpc. // -// It details the number of individual points received, the number of detected -// features and the total distance covered as the cumulative sum of the -// distance between each point. +// It contains the number of individual points received, the number of +// detected features, and the total distance covered as the cumulative sum of +// the distance between each point. message RouteSummary { // The number of points received. optional int32 point_count = 1; @@ -115,9 +115,9 @@ service RouteGuide { rpc RecordRoute(stream Point) returns (RouteSummary) { } - // Bidirectional streaming RPC. + // A Bidirectional streaming RPC. // - // Accepts a streams of RouteNotes sent while a route is being traversed, + // Accepts a stream of RouteNotes sent while a route is being traversed, // while receiving other RouteNotes (e.g. from other users). rpc RouteChat(stream RouteNote) returns (stream RouteNote) { } From 66e79fa3618f8987fa9398eb2321fe89f42326e6 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 14:07:48 -0800 Subject: [PATCH 38/92] Cleans up helloworld.proto --- protos/helloworld.proto | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/protos/helloworld.proto b/protos/helloworld.proto index aa44b851f43..86402ad71f9 100644 --- a/protos/helloworld.proto +++ b/protos/helloworld.proto @@ -33,19 +33,18 @@ option java_package = "ex.grpc"; package helloworld; +// The greeting service definition. +service Greetings { + // Sends a greeting + rpc hello (HelloRequest) returns (HelloReply) {} +} + // The request message containing the user's name. message HelloRequest { - optional string name = 1; + string name = 1; } // The response message containing the greetings message HelloReply { - optional string message = 1; -} - -// The greeting service definition. -service Greetings { - // Sends a greeting - rpc hello (HelloRequest) returns (HelloReply) { - } + string message = 1; } From c1ee3824b4a20a31fce4cd53ae69128e2d28bdc6 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 14:15:05 -0800 Subject: [PATCH 39/92] Cleans up route_guide.proto --- protos/route_guide.proto | 84 +++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/protos/route_guide.proto b/protos/route_guide.proto index 57576937a6f..7cda80efad8 100644 --- a/protos/route_guide.proto +++ b/protos/route_guide.proto @@ -33,23 +33,51 @@ option java_package = "ex.grpc"; package examples; +// Interface exported by the server. +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} + + // A server-to-client streaming RPC. + // + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} + + // A client-to-server streaming RPC. + // + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} + + // A Bidirectional streaming RPC. + // + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +} + // Points are represented as latitude-longitude pairs in the E7 representation // (degrees multiplied by 10**7 and rounded to the nearest integer). // Latitudes should be in the range +/- 90 degrees and longitude should be in // the range +/- 180 degrees (inclusive). message Point { - optional int32 latitude = 1; - optional int32 longitude = 2; + int32 latitude = 1; + int32 longitude = 2; } // A latitude-longitude rectangle, represented as two diagonally opposite // points "lo" and "hi". message Rectangle { // One corner of the rectangle. - optional Point lo = 1; + Point lo = 1; // The other corner of the rectangle. - optional Point hi = 2; + Point hi = 2; } // A feature names something at a given point. @@ -57,19 +85,19 @@ message Rectangle { // If a feature could not be named, the name is empty. message Feature { // The name of the feature. - optional string name = 1; + string name = 1; // The point where the feature is detected. - optional Point location = 2; + Point location = 2; } // A RouteNote is a message sent while at a given point. message RouteNote { // The location from which the message is sent. - optional Point location = 1; + Point location = 1; // The message to be sent. - optional string message = 2; + string message = 2; } // A RouteSummary is received in response to a RecordRoute rpc. @@ -79,46 +107,14 @@ message RouteNote { // the distance between each point. message RouteSummary { // The number of points received. - optional int32 point_count = 1; + int32 point_count = 1; // The number of known features passed while traversing the route. - optional int32 feature_count = 2; + int32 feature_count = 2; // The distance covered in metres. - optional int32 distance = 3; + int32 distance = 3; // The duration of the traversal in seconds. - optional int32 elapsed_time = 4; -} - -// Interface exported by the server -service RouteGuide { - // A simple RPC. - // - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) { - } - - // A server-to-client streaming RPC. - // - // Obtains the Features available within the given Rectangle. Results are - // streamed rather than returned at once (e.g. in a response message with a - // repeated field), as the rectangle may cover a large area and contain a - // huge number of features. - rpc ListFeatures(Rectangle) returns (stream Feature) { - } - - // A client-to-server streaming RPC. - // - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) { - } - - // A Bidirectional streaming RPC. - // - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) { - } + int32 elapsed_time = 4; } From c5a093c784e1c686bcd9731158d2323d04da19c1 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 14:28:50 -0800 Subject: [PATCH 40/92] Renames method and service name --- protos/helloworld.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protos/helloworld.proto b/protos/helloworld.proto index 86402ad71f9..4781fb48304 100644 --- a/protos/helloworld.proto +++ b/protos/helloworld.proto @@ -34,9 +34,9 @@ option java_package = "ex.grpc"; package helloworld; // The greeting service definition. -service Greetings { +service Greeter { // Sends a greeting - rpc hello (HelloRequest) returns (HelloReply) {} + rpc sayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. From 01acb4cc49cf72d51594410a709ef7ad6a857627 Mon Sep 17 00:00:00 2001 From: louiscryan Date: Wed, 18 Feb 2015 15:34:00 -0800 Subject: [PATCH 41/92] Initial checkin of protocol draft. --- PROTOCOL-HTTP2.md | 190 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 PROTOCOL-HTTP2.md diff --git a/PROTOCOL-HTTP2.md b/PROTOCOL-HTTP2.md new file mode 100644 index 00000000000..810c6b7e529 --- /dev/null +++ b/PROTOCOL-HTTP2.md @@ -0,0 +1,190 @@ +# gRPC over HTTP2 + +## Introduction +This document serves as a detailed description for an implementation of gRPC carried over HTTP2 draft 17 framing. It assumes familiarity with the HTTP2 specification. + +## Protocol +Production rules are using ABNF syntax. + +### Outline + +The following is the general sequence of message atoms in a GRPC request & response message stream + +* Request → Request-Headers *Delimited-Message EOS +* Response → (Response-Headers *Delimited-Message Trailers) / Trailers-Only + + +### Requests + +* Request → Request-Headers *Delimited-Message EOS + +Request-Headers are delivered as HTTP2 headers in HEADERS + CONTINUATION frames. + +* **Request-Headers** → Call-Definition *Custom-Metadata +* **Call-Definition** → Method Scheme Path TE [Authority] [Timeout] [Content-Type] [Message-Type] [Message-Encoding] [User-Agent] +* **Method** → “:method POST” +* **Scheme** → “:scheme ” (“http” / “https”) +* **Path** → “:path” {_path identifying method within exposed API_} +* **Authority** → “:authority” {_virtual host name of authority_} +* **TE** → “te” “trailers” # Used to detect incompatible proxies +* **Timeout** → “grpc-timeout” TimeoutValue TimeoutUnit +* **TimeoutValue** → {_positive integer as ASCII string of at most 8 digits_} +* **TimeoutUnit** → Hour / Minute / Second / Millisecond / Microsecond / Nanosecond +* **Hour** → “H” +* **Minute** → “M” +* **Second** → “S” +* **Millisecond** → “m” +* **Microsecond** → “u” +* **Nanosecond** → “n” +* **Content-Type** → “content-type” “application/grpc” [(“+proto” / “+json” / {_custom_})] +* **Message-Encoding** → “grpc-encoding ” (“gzip” / “deflate” / “snappy” / {_custom_} ) +* **User-Agent** → “user-agent” {_structured user-agent string_} +* **Message-Type** → “grpc-message-type” {_type name for message schema_} +* **Custom-Metadata** → Binary-Header / ASCII-Header +* **Binary-Header** → {lowercase ASCII header name ending in “-bin” } {_base64 encoded value_} +* **ASCII-Header** → {lowercase ASCII header name} {_value_} + + +HTTP2 requires that reserved headers, ones starting with “:” appear before all other headers. Additionally implementations should send **Timeout** immediately after the reserved headers and they should send the **Call-Definition** headers before sending **Custom-Metadata**. + +If **Timeout** is omitted a server should assume an infinite timeout. Client implementations are free to send a default minimum timeout based on their deployment requirements. + +**Custom-Metadata** is an arbitrary set of key-value pairs defined by the application layer. Aside from transport limits on the total length of HTTP2 HEADERS the only other constraint is that header names starting with “grpc-” are reserved for future use. + +Note that HTTP2 does not allow arbitrary octet sequences for header values so binary header values must be encoded using Base64 as per https://tools.ietf.org/html/rfc4648#section-4. Implementations MUST accept padded and un-padded values and should emit un-padded values. Applications define binary headers by having their names end with “-bin”. Runtime libraries use this suffix to detect binary headers and properly apply base64 encoding & decoding as headers are sent and received. + +The repeated sequence of **Delimited-Message** items is delivered in DATA frames + +* **Delimited-Message** → Compressed-Flag Message-Length Message +* **Compressed-Flag** → 0 / 1 # encoded as 1 byte unsigned integer +* **Message-Length** → {_length of Message_} # encoded as 4 byte unsigned integer +* **Message** → *{binary octet} + +A **Compressed-Flag** value of 1 indicates that the binary octet sequence of **Message** is compressed using the mechanism declared by the **Message-Encoding** header. A value of 0 indicates that no encoding of **Message** bytes has occurred. Compression contexts are NOT maintained over message boundaries, implementations must create a new context for each message in the stream. If the **Message-Encoding** header is omitted then the **Compressed-Flag** must be 0. + +For requests, **EOS** (end-of-stream) is indicated by the presence of the END_STREAM flag on the last received DATA frame. In scenarios where the **Request** stream needs to be closed but no data remains to be sent implementations MUST send an empty DATA frame with this flag set. + +###Responses + +* **Response** → (Response-Headers *Delimited-Message Trailers) / Trailers-Only +* **Response-Headers** → HTTP-Status [Message-Encoding] Content-Type *Custom-Metadata +* **Trailers-Only** → HTTP-Status Content-Type Trailers +* **Trailers** → Status [Status-Message] *Custom-Metadata +* **HTTP-Status** → “:status 200” +* **Status** → “grpc-status” +* **Status-Message** → “grpc-message” + +**Response-Headers** & **Trailers-Only** are each delivered in a single HTTP2 HEADERS frame block. Most responses are expected to have both headers and trailers but **Trailers-Only** is permitted for calls that produce an immediate error. Status must be sent in **Trailers** even if the status code is OK. + +For responses end-of-stream is indicated by the presence of the END_STREAM flag on the last received HEADERS frame that carries **Trailers**. + +Implementations should expect broken deployments to send non-200 HTTP status codes in responses as well as a variety of non-GRPC content-types and to omit **Status** & **Status-Message**. Implementations must synthesize a **Status** & **Status-Message** to propagate to the application layer when this occurs. + +####Example + +Sample unary-call showing HTTP2 framing sequence + +**Request** + +``` +HEADERS (flags = END_HEADERS) +:method = POST +:scheme = http +:path = /google.pubsub.v2.PublisherService/CreateTopic +:authority = pubsub.googleapis.com +grpc-timeout = 1S +content-type = application/grpc+proto +grpc-encoding = gzip +authorization = Bearer y235.wef315yfh138vh31hv93hv8h3v + +DATA (flags = END_STREAM) + +``` +**Response** +``` +HEADERS (flags = END_HEADERS) +:status = 200 +grpc-encoding = gzip + +DATA + + +HEADERS (flags = END_STREAM, END_HEADERS) +grpc-status = 0 # OK +trace-proto-bin = jher831yy13JHy3hc +``` +####User Agents + +While the protocol does not require a user-agent to function it is recommended that clients provide a structured user-agent string that provides a basic description of the calling library, version & platform to facilitate issue diagnosis in heterogeneous environments. The following structure is recommended to library developers +``` +User-Agent → “grpc-” Language ?(“-” Variant) “/” Version ?( “ (“ *(AdditionalProperty “;”) “)” ) +``` +E.g. + +``` +grpc-java/1.2.3 +grpc-ruby/1.2.3 +grpc-ruby-jruby/1.3.4 +grpc-java-android/0.9.1 (gingerbread/1.2.4; nexus5; tmobile) +``` +####HTTP2 Transport Mapping + +#####Stream Identification +All GRPC calls need to specify an internal ID. We will use HTTP2 stream-ids as call identifiers in this scheme. NOTE: These id’s are contextual to an open HTTP2 session and will not be unique within a given process that is handling more than one HTTP2 session nor can they be used as GUIDs. + +#####Data Frames +DATA frame boundaries have no relation to **Delimited-Message** boundaries and implementations should make no assumptions about their alignment. + +#####Errors + +When an application or runtime error occurs during an RPC a **Status** and **Status-Message** are delivered in **Trailers**. + +In some cases it is possible that the framing of the message stream has become corrupt and the RPC runtime will choose to use an **RST_STREAM** frame to indicate this state to its peer. RPC runtime implementations should interpret RST_STREAM as immediate full-closure of the stream and should propagate an error up to the calling application layer. + +The following mapping from RST_STREAM error codes to GRPC error codes is applied. + +HTTP2 Code|GRPC Code +----------|----------- +NO_ERROR(0)|INTERNAL - An explicit GRPC status of OK should have been sent but this might be used to aggressively lameduck in some scenarios. +PROTOCOL_ERROR(1)|INTERNAL +INTERNAL_ERROR(2)|INTERNAL +FLOW_CONTROL_ERROR(3)|INTERNAL +SETTINGS_TIMEOUT(4)|INTERNAL +STREAM_CLOSED|No mapping as there is no open stream to propagate to. Implementations should log. +FRAME_SIZE_ERROR|INTERNAL +REFUSED_STREAM|UNAVAILABLE - Indicates that no processing occurred and the request can be retried, possibly elsewhere. +CANCEL(8)|Mapped to call cancellation when sent by a client.Mapped to CANCELLED when sent by a server. Note that servers should only use this mechanism when they need to cancel a call but the payload byte sequence is incomplete. +COMPRESSION_ERROR|INTERNAL +CONNECT_ERROR|INTERNAL +ENHANCE_YOUR_CALM|RESOURCE_EXHAUSTED ...with additional error detail provided by runtime to indicate that the exhausted resource is bandwidth. +INADEQUATE_SECURITY| PERMISSION_DENIED … with additional detail indicating that permission was denied as protocol is not secure enough for call. + + +#####Security + +The HTTP2 specification mandates the use of TLS 1.2 or higher when TLS is used with HTTP2. It also places some additional constraints on the allowed ciphers in deployments to avoid known-problems as well as requiring SNI support. It is also expected that HTTP2 will be used in conjunction with proprietary transport security mechanisms about which the specification can make no meaningful recommendations. + +#####Connection Management +######GOAWAY Frame +Sent by servers to clients to indicate that they will no longer accept any new streams on the associated connections. This frame includes the id of the last successfully accepted stream by the server. Clients should consider any stream initiated after the last successfully accepted stream as UNAVAILABLE and retry the call elsewhere. Clients are free to continue working with the already accepted streams until they complete or the connection is terminated. + +Servers should send GOAWAY before terminating a connection to reliably inform clients which work has been accepted by the server and is being executed. + +######PING Frame +Both clients and servers can send a PING frame that the peer must respond to by precisely echoing what they received. This is used to assert that the connection is still live as well as providing a means to estimate end-to-end latency. If a server initiated PING does not receive a response within the deadline expected by the runtime all outstanding calls on the server will be closed with a CANCELLED status. An expired client initiated PING will cause all calls to be closed with an UNAVAILABLE status. Note that the frequency of PINGs is highly dependent on the network environment, implementations are free to adjust PING frequency based on network and application requirements. + +######Connection failure +If a detectable connection failure occurs on the client all calls will be closed with an UNAVAILABLE status. For servers open calls will be closed with a CANCELLED status. + + +### Appendix A - GRPC for Protobuf + +The service interfaces declared by protobuf are easily mapped onto GRPC by code generation extensions to protoc. The following defines the mapping to be used + + +* **Path** → / Service-Name / {_method name_} +* **Service-Name** → ?( {_proto package name_} "." ) {_service name_} +* **Message-Type** → {_fully qualified proto message name_} +* **Content-Type** → "application/grpc+proto" + + From 87faa1cf45e498dd2b5969eb39bcbda89ab7eddd Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 17:22:46 -0800 Subject: [PATCH 42/92] Updates generated code to reflect the proto changes in #19 --- .../{GreetingsGrpc.java => GreeterGrpc.java} | 126 +++++++++--------- .../{GreetingsImpl.java => GreeterImpl.java} | 4 +- .../main/java/ex/grpc/GreetingsClient.java | 6 +- .../main/java/ex/grpc/GreetingsServer.java | 2 +- java/src/main/java/ex/grpc/Helloworld.java | 12 +- 5 files changed, 75 insertions(+), 75 deletions(-) rename java/src/main/java/ex/grpc/{GreetingsGrpc.java => GreeterGrpc.java} (51%) rename java/src/main/java/ex/grpc/{GreetingsImpl.java => GreeterImpl.java} (75%) diff --git a/java/src/main/java/ex/grpc/GreetingsGrpc.java b/java/src/main/java/ex/grpc/GreeterGrpc.java similarity index 51% rename from java/src/main/java/ex/grpc/GreetingsGrpc.java rename to java/src/main/java/ex/grpc/GreeterGrpc.java index 97c2f00a1e0..080c3dfc434 100644 --- a/java/src/main/java/ex/grpc/GreetingsGrpc.java +++ b/java/src/main/java/ex/grpc/GreeterGrpc.java @@ -13,150 +13,150 @@ import static com.google.net.stubby.stub.ServerCalls.asyncUnaryRequestCall; import static com.google.net.stubby.stub.ServerCalls.asyncStreamingRequestCall; @javax.annotation.Generated("by gRPC proto compiler") -public class GreetingsGrpc { +public class GreeterGrpc { private static final com.google.net.stubby.stub.Method METHOD_HELLO = + ex.grpc.Helloworld.HelloReply> METHOD_SAY_HELLO = com.google.net.stubby.stub.Method.create( - com.google.net.stubby.MethodType.UNARY, "hello", + com.google.net.stubby.MethodType.UNARY, "sayHello", com.google.net.stubby.proto.ProtoUtils.marshaller(ex.grpc.Helloworld.HelloRequest.PARSER), com.google.net.stubby.proto.ProtoUtils.marshaller(ex.grpc.Helloworld.HelloReply.PARSER)); - public static GreetingsStub newStub(com.google.net.stubby.Channel channel) { - return new GreetingsStub(channel, CONFIG); + public static GreeterStub newStub(com.google.net.stubby.Channel channel) { + return new GreeterStub(channel, CONFIG); } - public static GreetingsBlockingStub newBlockingStub( + public static GreeterBlockingStub newBlockingStub( com.google.net.stubby.Channel channel) { - return new GreetingsBlockingStub(channel, CONFIG); + return new GreeterBlockingStub(channel, CONFIG); } - public static GreetingsFutureStub newFutureStub( + public static GreeterFutureStub newFutureStub( com.google.net.stubby.Channel channel) { - return new GreetingsFutureStub(channel, CONFIG); + return new GreeterFutureStub(channel, CONFIG); } - public static final GreetingsServiceDescriptor CONFIG = - new GreetingsServiceDescriptor(); + public static final GreeterServiceDescriptor CONFIG = + new GreeterServiceDescriptor(); @javax.annotation.concurrent.Immutable - public static class GreetingsServiceDescriptor extends - com.google.net.stubby.stub.AbstractServiceDescriptor { + public static class GreeterServiceDescriptor extends + com.google.net.stubby.stub.AbstractServiceDescriptor { public final com.google.net.stubby.MethodDescriptor hello; + ex.grpc.Helloworld.HelloReply> sayHello; - private GreetingsServiceDescriptor() { - hello = createMethodDescriptor( - "helloworld.Greetings", METHOD_HELLO); + private GreeterServiceDescriptor() { + sayHello = createMethodDescriptor( + "helloworld.Greeter", METHOD_SAY_HELLO); } - private GreetingsServiceDescriptor( + private GreeterServiceDescriptor( java.util.Map> methodMap) { - hello = (com.google.net.stubby.MethodDescriptor) methodMap.get( - CONFIG.hello.getName()); + CONFIG.sayHello.getName()); } @java.lang.Override - protected GreetingsServiceDescriptor build( + protected GreeterServiceDescriptor build( java.util.Map> methodMap) { - return new GreetingsServiceDescriptor(methodMap); + return new GreeterServiceDescriptor(methodMap); } @java.lang.Override public com.google.common.collect.ImmutableList> methods() { return com.google.common.collect.ImmutableList.>of( - hello); + sayHello); } } - public static interface Greetings { + public static interface Greeter { - public void hello(ex.grpc.Helloworld.HelloRequest request, + public void sayHello(ex.grpc.Helloworld.HelloRequest request, com.google.net.stubby.stub.StreamObserver responseObserver); } - public static interface GreetingsBlockingClient { + public static interface GreeterBlockingClient { - public ex.grpc.Helloworld.HelloReply hello(ex.grpc.Helloworld.HelloRequest request); + public ex.grpc.Helloworld.HelloReply sayHello(ex.grpc.Helloworld.HelloRequest request); } - public static interface GreetingsFutureClient { + public static interface GreeterFutureClient { - public com.google.common.util.concurrent.ListenableFuture hello( + public com.google.common.util.concurrent.ListenableFuture sayHello( ex.grpc.Helloworld.HelloRequest request); } - public static class GreetingsStub extends - com.google.net.stubby.stub.AbstractStub - implements Greetings { - private GreetingsStub(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { + public static class GreeterStub extends + com.google.net.stubby.stub.AbstractStub + implements Greeter { + private GreeterStub(com.google.net.stubby.Channel channel, + GreeterServiceDescriptor config) { super(channel, config); } @java.lang.Override - protected GreetingsStub build(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { - return new GreetingsStub(channel, config); + protected GreeterStub build(com.google.net.stubby.Channel channel, + GreeterServiceDescriptor config) { + return new GreeterStub(channel, config); } @java.lang.Override - public void hello(ex.grpc.Helloworld.HelloRequest request, + public void sayHello(ex.grpc.Helloworld.HelloRequest request, com.google.net.stubby.stub.StreamObserver responseObserver) { asyncUnaryCall( - channel.newCall(config.hello), request, responseObserver); + channel.newCall(config.sayHello), request, responseObserver); } } - public static class GreetingsBlockingStub extends - com.google.net.stubby.stub.AbstractStub - implements GreetingsBlockingClient { - private GreetingsBlockingStub(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { + public static class GreeterBlockingStub extends + com.google.net.stubby.stub.AbstractStub + implements GreeterBlockingClient { + private GreeterBlockingStub(com.google.net.stubby.Channel channel, + GreeterServiceDescriptor config) { super(channel, config); } @java.lang.Override - protected GreetingsBlockingStub build(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { - return new GreetingsBlockingStub(channel, config); + protected GreeterBlockingStub build(com.google.net.stubby.Channel channel, + GreeterServiceDescriptor config) { + return new GreeterBlockingStub(channel, config); } @java.lang.Override - public ex.grpc.Helloworld.HelloReply hello(ex.grpc.Helloworld.HelloRequest request) { + public ex.grpc.Helloworld.HelloReply sayHello(ex.grpc.Helloworld.HelloRequest request) { return blockingUnaryCall( - channel.newCall(config.hello), request); + channel.newCall(config.sayHello), request); } } - public static class GreetingsFutureStub extends - com.google.net.stubby.stub.AbstractStub - implements GreetingsFutureClient { - private GreetingsFutureStub(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { + public static class GreeterFutureStub extends + com.google.net.stubby.stub.AbstractStub + implements GreeterFutureClient { + private GreeterFutureStub(com.google.net.stubby.Channel channel, + GreeterServiceDescriptor config) { super(channel, config); } @java.lang.Override - protected GreetingsFutureStub build(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { - return new GreetingsFutureStub(channel, config); + protected GreeterFutureStub build(com.google.net.stubby.Channel channel, + GreeterServiceDescriptor config) { + return new GreeterFutureStub(channel, config); } @java.lang.Override - public com.google.common.util.concurrent.ListenableFuture hello( + public com.google.common.util.concurrent.ListenableFuture sayHello( ex.grpc.Helloworld.HelloRequest request) { return unaryFutureCall( - channel.newCall(config.hello), request); + channel.newCall(config.sayHello), request); } } public static com.google.net.stubby.ServerServiceDefinition bindService( - final Greetings serviceImpl) { - return com.google.net.stubby.ServerServiceDefinition.builder("helloworld.Greetings") + final Greeter serviceImpl) { + return com.google.net.stubby.ServerServiceDefinition.builder("helloworld.Greeter") .addMethod(createMethodDefinition( - METHOD_HELLO, + METHOD_SAY_HELLO, asyncUnaryRequestCall( new com.google.net.stubby.stub.ServerCalls.UnaryRequestMethod< ex.grpc.Helloworld.HelloRequest, @@ -165,7 +165,7 @@ public class GreetingsGrpc { public void invoke( ex.grpc.Helloworld.HelloRequest request, com.google.net.stubby.stub.StreamObserver responseObserver) { - serviceImpl.hello(request, responseObserver); + serviceImpl.sayHello(request, responseObserver); } }))).build(); } diff --git a/java/src/main/java/ex/grpc/GreetingsImpl.java b/java/src/main/java/ex/grpc/GreeterImpl.java similarity index 75% rename from java/src/main/java/ex/grpc/GreetingsImpl.java rename to java/src/main/java/ex/grpc/GreeterImpl.java index 005489acaa2..825ba8631ec 100644 --- a/java/src/main/java/ex/grpc/GreetingsImpl.java +++ b/java/src/main/java/ex/grpc/GreeterImpl.java @@ -2,10 +2,10 @@ package ex.grpc; import com.google.net.stubby.stub.StreamObserver; -public class GreetingsImpl implements GreetingsGrpc.Greetings { +public class GreeterImpl implements GreeterGrpc.Greeter { @Override - public void hello(Helloworld.HelloRequest req, + public void sayHello(Helloworld.HelloRequest req, StreamObserver responseObserver) { Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( "Hello " + req.getName()).build(); diff --git a/java/src/main/java/ex/grpc/GreetingsClient.java b/java/src/main/java/ex/grpc/GreetingsClient.java index 4ae2e7076bc..141ad1e20a6 100644 --- a/java/src/main/java/ex/grpc/GreetingsClient.java +++ b/java/src/main/java/ex/grpc/GreetingsClient.java @@ -13,13 +13,13 @@ public class GreetingsClient { private final Logger logger = Logger.getLogger( GreetingsClient.class.getName()); private final ChannelImpl channel; - private final GreetingsGrpc.GreetingsBlockingStub blockingStub; + private final GreeterGrpc.GreeterBlockingStub blockingStub; public GreetingsClient(String host, int port) { channel = NettyChannelBuilder.forAddress(host, port) .negotiationType(NegotiationType.PLAINTEXT) .build(); - blockingStub = GreetingsGrpc.newBlockingStub(channel); + blockingStub = GreeterGrpc.newBlockingStub(channel); } public void shutdown() throws InterruptedException { @@ -31,7 +31,7 @@ public class GreetingsClient { logger.fine("Will try to greet " + name + " ..."); Helloworld.HelloRequest req = Helloworld.HelloRequest.newBuilder().setName(name).build(); - Helloworld.HelloReply reply = blockingStub.hello(req); + Helloworld.HelloReply reply = blockingStub.sayHello(req); logger.info("Greeting: " + reply.getMessage()); } catch (RuntimeException e) { logger.log(Level.WARNING, "RPC failed", e); diff --git a/java/src/main/java/ex/grpc/GreetingsServer.java b/java/src/main/java/ex/grpc/GreetingsServer.java index 834ae985a44..237309d13c7 100644 --- a/java/src/main/java/ex/grpc/GreetingsServer.java +++ b/java/src/main/java/ex/grpc/GreetingsServer.java @@ -16,7 +16,7 @@ public class GreetingsServer { private void start() throws Exception { server = NettyServerBuilder.forPort(port) - .addService(GreetingsGrpc.bindService(new GreetingsImpl())) + .addService(GreeterGrpc.bindService(new GreeterImpl())) .build(); server.startAsync(); server.awaitRunning(5, TimeUnit.SECONDS); diff --git a/java/src/main/java/ex/grpc/Helloworld.java b/java/src/main/java/ex/grpc/Helloworld.java index f72040fa2bf..b25a63fca32 100644 --- a/java/src/main/java/ex/grpc/Helloworld.java +++ b/java/src/main/java/ex/grpc/Helloworld.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: src/main/proto/helloworld.proto +// source: helloworld.proto package ex.grpc; @@ -915,11 +915,11 @@ public final class Helloworld { descriptor; static { java.lang.String[] descriptorData = { - "\n\037src/main/proto/helloworld.proto\022\nhello" + - "world\"\034\n\014HelloRequest\022\014\n\004name\030\001 \001(\t\"\035\n\nH" + - "elloReply\022\017\n\007message\030\001 \001(\t2H\n\tGreetings\022" + - ";\n\005hello\022\030.helloworld.HelloRequest\032\026.hel" + - "loworld.HelloReply\"\000B\t\n\007ex.grpcb\006proto3" + "\n\020helloworld.proto\022\nhelloworld\"\034\n\014HelloR" + + "equest\022\014\n\004name\030\001 \001(\t\"\035\n\nHelloReply\022\017\n\007me" + + "ssage\030\001 \001(\t2I\n\007Greeter\022>\n\010sayHello\022\030.hel" + + "loworld.HelloRequest\032\026.helloworld.HelloR" + + "eply\"\000B\t\n\007ex.grpcb\006proto3" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { From 2604848108f26d4b4a38ca9316db376d5e470634 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 17:31:03 -0800 Subject: [PATCH 43/92] Updates the main to reflect the proto changes in #19 --- README.md | 57 +++++++++++++++++++++++++------------------------------ 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index fdbd1f0de02..1203465660d 100644 --- a/README.md +++ b/README.md @@ -247,26 +247,26 @@ 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), +- [`GreeterGrpc.java`](java/src/main/java/ex/grpc/GreeterGrpc.java), which contains (along with some other useful code): - - an interface for `Greetings` servers to implement + - an interface for `Greeter` servers to implement ```java - public static interface Greetings { + public static interface Greeter { - public void hello(ex.grpc.Helloworld.HelloRequest request, + public void sayHello(ex.grpc.Helloworld.HelloRequest request, com.google.net.stubby.stub.StreamObserver responseObserver); } ``` - - _stub_ classes that clients can use to talk to a `Greetings` server. As you can see, they also implement the `Greetings` interface. + - _stub_ classes that clients can use to talk to a `Greeter` server. As you can see, they also implement the `Greeter` interface. ```java -public static class GreetingsStub extends - com.google.net.stubby.stub.AbstractStub - implements Greetings { +public static class GreeterStub extends + com.google.net.stubby.stub.AbstractStub + implements Greeter { ... } ``` @@ -282,18 +282,18 @@ 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). +[GreeterImpl.java](java/src/main/java/ex/grpc/GreeterImpl.java). - a server that hosts the service implementation and allows access over the -network: [GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java). +network: [GreeterServer.java](java/src/main/java/ex/grpc/GreeterServer.java). #### Service implementation -[GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java) +[GreeterImpl.java](java/src/main/java/ex/grpc/GreeterImpl.java) actually implements our GreetingService's required behaviour. -As you can see, the class `GreetingsImpl` implements the interface -`GreetingsGrpc.Greetings` that we [generated](#generating) from our proto +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`: ```java @@ -325,7 +325,7 @@ finished dealing with this RPC. #### Server implementation -[GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) +[GreeterServer.java](java/src/main/java/ex/grpc/GreeterServer.java) shows the other main feature required to provide a gRPC service; making the service implementation available from the network. @@ -334,7 +334,7 @@ implementation available from the network. ... private void start() throws Exception { server = NettyServerBuilder.forPort(port) - .addService(GreetingsGrpc.bindService(new GreetingsImpl())) + .addService(GreeterGrpc.bindService(new GreeterImpl())) .build(); server.startAsync(); server.awaitRunning(5, TimeUnit.SECONDS); @@ -342,15 +342,15 @@ implementation available from the network. ``` -The `GreetingsServer` class has a `ServerImpl` member that actually runs the +The `GreeterServer` class has a `ServerImpl` member that actually runs the server. To create an appropriate `ServerImpl`, we use a special `ServerBuilder` -class (in this case a `NettyServerBuilder`) in the `GreetingsServer`'s `start` -method, binding the `GreetingsService` implementation that we created to a +class (in this case a `NettyServerBuilder`) in the `GreeterServer`'s `start` +method, binding the `GreeterService` implementation that we created to a port. Then we start the server running: the server is now ready to receive -requests from `Greetings` 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. -`GreetingsServer` also has a `stop` method that takes care of shutting down +`GreeterServer` also has a `stop` method that takes care of shutting down the service and cleaning up when the program exits. #### Build it @@ -367,9 +367,9 @@ We'll look at using a client to access the server in the next section. ### 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 +to write a simple client that can access the `Greeter` server we created in the [previous section](#server). You can see the complete client code in -[GreetingsClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). +[GreetingClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). Again, we're not going to go into much detail about how to implement a client - we'll leave that for the tutorial. @@ -386,13 +386,13 @@ service. The channel in turn is used to construct the stub instance. ```java private final ChannelImpl channel; - private final GreetingGrpc.GreetingBlockingStub blockingStub; + private final GreeterGrpc.GreeterBlockingStub blockingStub; public HelloClient(String host, int port) { channel = NettyChannelBuilder.forAddress(host, port) .negotiationType(NegotiationType.PLAINTEXT) .build(); - blockingStub = GreetingGrpc.newBlockingStub(channel); + blockingStub = GreeterGrpc.newBlockingStub(channel); } ``` @@ -419,7 +419,7 @@ from which we can get our greeting. try { Helloworld.HelloRequest request = Helloworld.HelloRequest.newBuilder().setName(name).build(); - Helloworld.HelloReply reply = blockingStub.hello(request); + Helloworld.HelloReply reply = blockingStub.sayHello(request); logger.info("Greeting: " + reply.getMessage()); } catch (RuntimeException e) { logger.log(Level.WARNING, "RPC failed", e); @@ -474,8 +474,3 @@ $ ./run_greetings_client.sh ### Adding another client ###TODO: Section on Go client for same server - - - - - From a16a4d551f9035bd720107732ab71bb9bf337dda Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 17:43:41 -0800 Subject: [PATCH 44/92] Complete the change s/Greetings/Greeter --- README.md | 6 +++--- java/{run_greetings_client.sh => run_greeter_client.sh} | 4 ++-- java/{run_greetings_server.sh => run_greeter_server.sh} | 4 ++-- .../ex/grpc/{GreetingsClient.java => GreeterClient.java} | 8 ++++---- .../ex/grpc/{GreetingsServer.java => GreeterServer.java} | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) rename java/{run_greetings_client.sh => run_greeter_client.sh} (80%) rename java/{run_greetings_server.sh => run_greeter_server.sh} (78%) rename java/src/main/java/ex/grpc/{GreetingsClient.java => GreeterClient.java} (89%) rename java/src/main/java/ex/grpc/{GreetingsServer.java => GreeterServer.java} (88%) diff --git a/README.md b/README.md index 1203465660d..71f3004c71d 100644 --- a/README.md +++ b/README.md @@ -369,7 +369,7 @@ We'll look at using a client to access the server in the next section. Client-side gRPC is pretty simple. In this step, we'll use the generated code to write a simple client that can access the `Greeter` server we created in the [previous section](#server). You can see the complete client code in -[GreetingClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). +[GreeterClient.java](java/src/main/java/ex/grpc/GreeterClient.java). Again, we're not going to go into much detail about how to implement a client - we'll leave that for the tutorial. @@ -462,13 +462,13 @@ 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 +$ ./run_greeter_server.sh ``` and in another terminal window confirm that it receives a message. ```sh -$ ./run_greetings_client.sh +$ ./run_greeter_client.sh ``` ### Adding another client diff --git a/java/run_greetings_client.sh b/java/run_greeter_client.sh similarity index 80% rename from java/run_greetings_client.sh rename to java/run_greeter_client.sh index 8155589adf7..e86ab4ae891 100755 --- a/java/run_greetings_client.sh +++ b/java/run_greeter_client.sh @@ -1,6 +1,6 @@ #!/bin/bash -e -TARGET='Greetings Client' -TARGET_CLASS='ex.grpc.GreetingsClient' +TARGET='Greeter Client' +TARGET_CLASS='ex.grpc.GreeterClient' TARGET_ARGS="$@" cd "$(dirname "$0")" diff --git a/java/run_greetings_server.sh b/java/run_greeter_server.sh similarity index 78% rename from java/run_greetings_server.sh rename to java/run_greeter_server.sh index 248229e129e..836abc7f48a 100755 --- a/java/run_greetings_server.sh +++ b/java/run_greeter_server.sh @@ -1,6 +1,6 @@ #!/bin/bash -e -TARGET='Greetings Server' -TARGET_CLASS='ex.grpc.GreetingsServer' +TARGET='Greeter Server' +TARGET_CLASS='ex.grpc.GreeterServer' cd "$(dirname "$0")" mvn -q -nsu -am package -Dcheckstyle.skip=true -DskipTests diff --git a/java/src/main/java/ex/grpc/GreetingsClient.java b/java/src/main/java/ex/grpc/GreeterClient.java similarity index 89% rename from java/src/main/java/ex/grpc/GreetingsClient.java rename to java/src/main/java/ex/grpc/GreeterClient.java index 141ad1e20a6..9a4615132d6 100644 --- a/java/src/main/java/ex/grpc/GreetingsClient.java +++ b/java/src/main/java/ex/grpc/GreeterClient.java @@ -9,13 +9,13 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.concurrent.TimeUnit; -public class GreetingsClient { +public class GreeterClient { private final Logger logger = Logger.getLogger( - GreetingsClient.class.getName()); + GreeterClient.class.getName()); private final ChannelImpl channel; private final GreeterGrpc.GreeterBlockingStub blockingStub; - public GreetingsClient(String host, int port) { + public GreeterClient(String host, int port) { channel = NettyChannelBuilder.forAddress(host, port) .negotiationType(NegotiationType.PLAINTEXT) .build(); @@ -40,7 +40,7 @@ public class GreetingsClient { } public static void main(String[] args) throws Exception { - GreetingsClient client = new GreetingsClient("localhost", 50051); + GreeterClient client = new GreeterClient("localhost", 50051); try { /* Access a service running on the local machine on port 50051 */ String user = "world"; diff --git a/java/src/main/java/ex/grpc/GreetingsServer.java b/java/src/main/java/ex/grpc/GreeterServer.java similarity index 88% rename from java/src/main/java/ex/grpc/GreetingsServer.java rename to java/src/main/java/ex/grpc/GreeterServer.java index 237309d13c7..bb05680b0a6 100644 --- a/java/src/main/java/ex/grpc/GreetingsServer.java +++ b/java/src/main/java/ex/grpc/GreeterServer.java @@ -7,9 +7,9 @@ import com.google.net.stubby.transport.netty.NettyServerBuilder; import java.util.concurrent.TimeUnit; /** - * Server that manages startup/shutdown of a {@code Greetings} server. + * Server that manages startup/shutdown of a {@code Greeter} server. */ -public class GreetingsServer { +public class GreeterServer { /* The port on which the server should run */ private int port = 50051; private ServerImpl server; @@ -33,7 +33,7 @@ public class GreetingsServer { * Main launches the server from the command line. */ public static void main(String[] args) throws Exception { - final GreetingsServer server = new GreetingsServer(); + final GreeterServer server = new GreeterServer(); Runtime.getRuntime().addShutdownHook(new Thread() { @Override From 5aa9eeba547205b309c66aed97253b4fb670fa60 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 19 Feb 2015 07:30:43 -0800 Subject: [PATCH 45/92] Removes the unused protos, updates the README to reflect the protos in use --- java/src/main/proto/helloworld.proto | 22 -------- protos/README.md | 10 ++-- protos/math.proto | 79 ---------------------------- protos/stock.proto | 71 ------------------------- 4 files changed, 4 insertions(+), 178 deletions(-) delete mode 100644 java/src/main/proto/helloworld.proto delete mode 100644 protos/math.proto delete mode 100644 protos/stock.proto diff --git a/java/src/main/proto/helloworld.proto b/java/src/main/proto/helloworld.proto deleted file mode 100644 index da5c3a1d85d..00000000000 --- a/java/src/main/proto/helloworld.proto +++ /dev/null @@ -1,22 +0,0 @@ -syntax = "proto3"; - -option java_package = "ex.grpc"; - -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 Greetings { - // Sends a greeting - rpc hello (HelloRequest) returns (HelloReply) { - } -} diff --git a/protos/README.md b/protos/README.md index 374d4350aca..48df7c8943e 100644 --- a/protos/README.md +++ b/protos/README.md @@ -2,9 +2,7 @@ ## Contents -- helloworld.proto - - A very simple example used in the overview. -- stock.proto - - A detailed example that's described in detail in the tutorial. -- math.proto - - Another detailed example for further reference. +- [helloworld.proto] + - The simple example used in the overview. +- [route_guide.proto] + - An example service described in detail in the tutorial. diff --git a/protos/math.proto b/protos/math.proto deleted file mode 100644 index 46a33aeee53..00000000000 --- a/protos/math.proto +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2015, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -package math; - -message DivArgs { - optional int64 dividend = 1; - optional int64 divisor = 2; -} - -message DivReply { - optional int64 quotient = 1; - optional int64 remainder = 2; -} - -message FibArgs { - optional int64 limit = 1; -} - -message Num { - optional int64 num = 1; -} - -message FibReply { - optional int64 count = 1; -} - -service Math { - // Div divides args.dividend by args.divisor and returns the quotient and - // remainder. - rpc Div (DivArgs) returns (DivReply) { - } - - // DivMany accepts an arbitrary number of division args from the client stream - // and sends back the results in the reply stream. The stream continues until - // the client closes its end; the server does the same after sending all the - // replies. The stream ends immediately if either end aborts. - rpc DivMany (stream DivArgs) returns (stream DivReply) { - } - - // Fib generates numbers in the Fibonacci sequence. If args.limit > 0, Fib - // generates up to limit numbers; otherwise it continues until the call is - // canceled. - rpc Fib (FibArgs) returns (stream Num) { - } - - // Sum sums a stream of numbers, returning the final result once the stream - // is closed. - rpc Sum (stream Num) returns (Num) { - } -} diff --git a/protos/stock.proto b/protos/stock.proto deleted file mode 100644 index 49efbf2730a..00000000000 --- a/protos/stock.proto +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2015, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -package examples; - -// Protocol type definitions -message StockRequest { - optional string symbol = 1; - optional int32 num_trades_to_watch = 2; -} - -message StockReply { - optional float price = 1; - optional string symbol = 2; -} - -// Interface exported by the server -service Stock { - // A simple blocking RPC. - // - // Obtains the last traded price for the given Stock. - rpc GetLastTradePrice(StockRequest) returns (StockReply) { - } - - // A Unidirectional server-to-client streaming RPC. - // - // Streams future prices for a given symbol. - rpc WatchFutureTrades(StockRequest) returns (stream StockReply) { - } - - // A Unidirectional client-to-server streaming RPC. - // - // Gets the highest traded price for a series of symbols - rpc GetHighestTradePrice(stream StockRequest) returns (StockReply) { - } - - // Bidirectional streaming RPC. - // - // Gets the most recent traded price of series of trades. - rpc GetLastTradePriceMultiple(stream StockRequest) returns - (stream StockReply) { - } -} From 554b4d7e202ff57b5f60619e6eb675858fb689a6 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Thu, 19 Feb 2015 16:05:49 +0000 Subject: [PATCH 46/92] More tidying up, pared down explanations for server and client code as was getting a bit too Java-specific. --- README.md | 72 ++++++++++++++----------------------------------------- 1 file changed, 18 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index fdbd1f0de02..5669b8318c5 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Hello World example. More documentation is coming soon! ## What is gRPC? -In gRPC, like other RPC systems, a *client* application can directly call +In gRPC a *client* application can directly call methods on a *server* application on a different machine as if it was a local object, making it easier for you to create distributed applications and services. As in many RPC systems, gRPC is based around the idea of defining @@ -32,9 +32,8 @@ your applications. ### Working with protocol buffers -While gRPC’s architecture allows it to be extended for use with other -data formats such as JSON, by default it uses *protocol buffers*, Google’s -mature open source mechanism for serializing structured data. As you'll +By default gRPC uses *protocol buffers*, Google’s +mature open source mechanism for serializing structured data (although it can be used with other data formats such as JSON). As you'll see in our example below, you define gRPC services using *proto files*, with method parameters and return types specified as protocol buffer message types. You @@ -68,7 +67,7 @@ construction of a simple gRPC client-server application, showing you how to: - Create a protocol buffers schema that defines a simple RPC service with a single Hello World method. -- Create a Java server that implements thid interface. +- Create a Java server that implements this interface. - Create a Java client that accesses the Java server. - Create a [probably need a different language now] client that accesses the same Java server. - Update the service with more advanced features like RPC streaming. @@ -82,7 +81,7 @@ than how to install and run a few git commands. 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 +Java developer - the concepts introduced here are similar for all languages, and complete tutorials and reference documentation for all gRPC languages are coming soon. @@ -209,9 +208,7 @@ 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"?] +defined in our `Greeting` service. (If you didn't install `protoc` on your system and are working along with the example, you can skip this step and move @@ -276,7 +273,7 @@ public static class GreetingsStub extends 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 +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: @@ -293,7 +290,7 @@ network: [GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) actually implements our GreetingService's required behaviour. As you can see, the class `GreetingsImpl` implements the interface -`GreetingsGrpc.Greetings` that we [generated](#generating) from our proto +`GreetingsGrpc.Greetings` that we [generated](#Generating gRPC code) from our proto [IDL](java/src/main/proto/helloworld.proto) by implementing the method `hello`: ```java @@ -306,9 +303,6 @@ As you can see, the class `GreetingsImpl` implements the interface responseObserver.onCompleted(); } ``` -- `hello's` signature is typesafe: - `hello(Helloworld.HelloRequest req, StreamObserver - responseObserver)` - `hello` takes two parameters: -`Helloworld.HelloRequest`: the request -`StreamObserver`: a response observer, which is @@ -318,9 +312,7 @@ 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 call `responseObserver.onValue()` with the `HelloReply` that we want to send back to the client. -3. Finally, we call `responseObserver.onCompleted()` to indicate that we're -finished dealing with this RPC. +2. We use the`responseObserver` to return the `HelloReply` to the client and then specify that we've finished dealing with the RPC #### Server implementation @@ -342,17 +334,11 @@ implementation available from the network. ``` -The `GreetingsServer` class has a `ServerImpl` member that actually runs the -server. To create an appropriate `ServerImpl`, we use a special `ServerBuilder` -class (in this case a `NettyServerBuilder`) in the `GreetingsServer`'s `start` -method, binding the `GreetingsService` implementation that we created to a +Here we create an appropriate gRPC server, binding the `GreetingsService` implementation that we created to a port. Then we start the server running: the server is now ready to receive requests from `Greetings` service clients on our specified port. We'll cover how all this works in a bit more detail in our language-specific documentation. -`GreetingsServer` also has a `stop` method that takes care of shutting down -the service and cleaning up when the program exits. - #### Build it Once we've implemented everything, we use Maven to build the server: @@ -376,12 +362,7 @@ Again, we're not going to go into much detail about how to implement a client #### Connecting to the service -First let's look at how we connect to the `Greetings` server. The internet -address -is configured in the client constructor. gRPC `Channel` provides the -abstraction layer over -transport handling; its constructor accepts the host name and port of the -service. The channel in turn is used to construct the stub instance. +First let's look at how we connect to the `Greetings` server. First we need to create a gRPC channel, specifying the hostname and port of the server we want to connect to. Then we use the channel to construct the stub instance. ```java @@ -402,14 +383,12 @@ 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. -#### Obtaining a greeting +#### Calling an RPC -The `greet()` method uses the stub to contact the service and obtain -a greeting. -To do this: +Now we can contact the service and obtain a greeting: -1. We construct and fill in a `HelloRequest` to send to the stub. -2. We call the RPC with our request and get a `HelloReply` from the stub, +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. @@ -429,27 +408,10 @@ from which we can get our greeting. ``` -#### Running from the command line - -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"; - if (args.length > 1) { - user = args[1]; - } - client.greet(user); - -``` - #### 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. +the same maven package so the same command builds both. ``` $ mvn package @@ -473,6 +435,8 @@ $ ./run_greetings_client.sh ### Adding another client +Finally, let's look at one of gRPC's most useful features - interoperability between code in different languages. So far, we've just generated Java code from our `Greetings` service definition. + ###TODO: Section on Go client for same server From e1a9ebdce3911f5b834d6590d5235b5f8d450ab3 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Thu, 19 Feb 2015 17:35:10 +0000 Subject: [PATCH 47/92] Couple more small fixes --- README.md | 76 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 5669b8318c5..4701619b699 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # Getting started -## 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. @@ -33,7 +31,8 @@ your applications. ### Working with protocol buffers By default gRPC uses *protocol buffers*, Google’s -mature open source mechanism for serializing structured data (although it can be used with other data formats such as JSON). As you'll +mature open source mechanism for serializing structured data (although it +can be used with other data formats such as JSON). As you'll see in our example below, you define gRPC services using *proto files*, with method parameters and return types specified as protocol buffer message types. You @@ -65,14 +64,17 @@ 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 protocol buffers schema that defines a simple RPC service with a single +- Create a protocol buffers schema that defines a simple RPC service with +a single Hello World method. - Create a Java server that implements this interface. - Create a Java client that accesses the Java server. -- Create a [probably need a different language now] client that accesses the same Java server. +- Create a [probably need a different language now] 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 the `grpc-common` GitHub repository. 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: @@ -81,14 +83,16 @@ than how to install and run a few git commands. This is an introductory example rather than a comprehensive tutorial, so don't worry if you're not a Go or -Java developer - the concepts introduced here are similar for all languages, and complete tutorials and reference documentation for all gRPC +Java developer - the concepts introduced here are similar for all languages, +and complete tutorials and reference documentation for all gRPC languages are coming soon. ### Setup This section 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](#servicedef). +the example code. If you just want to read the example, you can go straight +to the [next step](#servicedef). #### Install Git @@ -167,7 +171,8 @@ server use interface code generated from the service definition. Here's our example service definition, defined using protocol buffers IDL in [helloworld.proto](java/src/main/proto/helloworld.proto). The `Greeting` -service has one method, `hello`, that lets the server receive a single `HelloRequest` +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 single `HelloReply`. This is the simplest type of RPC you can specify in gRPC - we'll look at some other types later in this document. @@ -179,22 +184,20 @@ option java_package = "ex.grpc"; package helloworld; +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc sayHello (HelloRequest) returns (HelloReply) {} +} + // The request message containing the user's name. message HelloRequest { - optional string name = 1; + 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) { - } + string message = 1; } ``` @@ -257,7 +260,8 @@ which contains (along with some other useful code): } ``` - - _stub_ classes that clients can use to talk to a `Greetings` server. As you can see, they also implement the `Greetings` interface. + - _stub_ classes that clients can use to talk to a `Greetings` server. As + you can see, they also implement the `Greetings` interface. ```java public static class GreetingsStub extends @@ -282,7 +286,8 @@ Our server application has two classes: [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](java/src/main/java/ex/grpc/GreetingsServer.java). +network: +[GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java). #### Service implementation @@ -290,8 +295,9 @@ network: [GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) actually implements our GreetingService's required behaviour. As you can see, the class `GreetingsImpl` implements the interface -`GreetingsGrpc.Greetings` that we [generated](#Generating gRPC code) from our proto -[IDL](java/src/main/proto/helloworld.proto) by implementing the method `hello`: +`GreetingsGrpc.Greetings` that we [generated](#generating) from +our proto +[IDL](proto/helloworld.proto) by implementing the method `hello`: ```java public void hello(Helloworld.HelloRequest req, @@ -312,13 +318,15 @@ 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 use the`responseObserver` to return the `HelloReply` to the client +and then specify that we've finished dealing with the RPC #### Server implementation [GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.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. ```java @@ -334,7 +342,8 @@ implementation available from the network. ``` -Here we create an appropriate gRPC server, binding the `GreetingsService` implementation that we created to a +Here we create an appropriate gRPC server, binding the `GreetingsService` +implementation that we created to a port. Then we start the server running: the server is now ready to receive requests from `Greetings` service clients on our specified port. We'll cover how all this works in a bit more detail in our language-specific documentation. @@ -357,12 +366,14 @@ to write a simple client that can access the `Greetings` server we created in the [previous section](#server). You can see the complete client code in [GreetingsClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). -Again, 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 -First let's look at how we connect to the `Greetings` server. First we need to create a gRPC channel, specifying the hostname and port of the server we want to connect to. Then we use the channel to construct the stub instance. +First let's look at how we connect to the `Greetings` server. First we need +to create a gRPC channel, specifying the hostname and port of the server we +want to connect to. Then we use the channel to construct the stub instance. ```java @@ -388,7 +399,8 @@ to the server, where the response is returned asynchronously. 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, +2. We call the stub's `hello()` RPC with our request and get a `HelloReply` +back, from which we can get our greeting. @@ -435,7 +447,9 @@ $ ./run_greetings_client.sh ### Adding another client -Finally, let's look at one of gRPC's most useful features - interoperability between code in different languages. So far, we've just generated Java code from our `Greetings` service definition. +Finally, let's look at one of gRPC's most useful features - interoperability +between code in different languages. So far, we've just generated Java code +from our `Greetings` service definition.... ###TODO: Section on Go client for same server From 48dbd9bd6062193c955ee02523d40ed41791287c Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Thu, 19 Feb 2015 17:47:29 +0000 Subject: [PATCH 48/92] Mergey mergey --- README.md | 63 ++++++++++++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 4701619b699..43c65b42a10 100644 --- a/README.md +++ b/README.md @@ -247,27 +247,26 @@ 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), +- [`GreeterGrpc.java`](java/src/main/java/ex/grpc/GreeterGrpc.java), which contains (along with some other useful code): - - an interface for `Greetings` servers to implement + - an interface for `Greeter` servers to implement ```java - public static interface Greetings { + public static interface Greeter { - public void hello(ex.grpc.Helloworld.HelloRequest request, + public void sayHello(ex.grpc.Helloworld.HelloRequest request, com.google.net.stubby.stub.StreamObserver responseObserver); } ``` - - _stub_ classes that clients can use to talk to a `Greetings` server. As - you can see, they also implement the `Greetings` interface. + - _stub_ classes that clients can use to talk to a `Greeter` server. As you can see, they also implement the `Greeter` interface. ```java -public static class GreetingsStub extends - com.google.net.stubby.stub.AbstractStub - implements Greetings { +public static class GreeterStub extends + com.google.net.stubby.stub.AbstractStub + implements Greeter { ... } ``` @@ -283,21 +282,18 @@ 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). +[GreeterImpl.java](java/src/main/java/ex/grpc/GreeterImpl.java). - a server that hosts the service implementation and allows access over the -network: -[GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java). +network: [GreeterServer.java](java/src/main/java/ex/grpc/GreeterServer.java). #### Service implementation -[GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java) +[GreeterImpl.java](java/src/main/java/ex/grpc/GreeterImpl.java) actually implements our GreetingService's required behaviour. -As you can see, the class `GreetingsImpl` implements the interface -`GreetingsGrpc.Greetings` that we [generated](#generating) from -our proto -[IDL](proto/helloworld.proto) by implementing the method `hello`: +As you can see, the class `GreeterImpl` implements the interface +`GreeterGrpc.Greeter` that we [generated](#generating) from our proto ```java public void hello(Helloworld.HelloRequest req, @@ -324,9 +320,8 @@ and then specify that we've finished dealing with the RPC #### Server implementation -[GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) -shows the other main feature required to provide a gRPC service; making -the service +[GreeterServer.java](java/src/main/java/ex/grpc/GreeterServer.java) +shows the other main feature required to provide a gRPC service; making the service implementation available from the network. ```java @@ -334,7 +329,7 @@ implementation available from the network. ... private void start() throws Exception { server = NettyServerBuilder.forPort(port) - .addService(GreetingsGrpc.bindService(new GreetingsImpl())) + .addService(GreeterGrpc.bindService(new GreeterImpl())) .build(); server.startAsync(); server.awaitRunning(5, TimeUnit.SECONDS); @@ -342,10 +337,11 @@ implementation available from the network. ``` -Here we create an appropriate gRPC server, binding the `GreetingsService` + +Here we create an appropriate gRPC server, binding the `GreeterService` implementation that we created to a port. Then we start the server running: the server is now ready to receive -requests from `Greetings` 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. #### Build it @@ -362,9 +358,9 @@ We'll look at using a client to access the server in the next section. ### 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 +to write a simple client that can access the `Greeter` server we created in the [previous section](#server). You can see the complete client code in -[GreetingsClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). +[GreeterClient.java](java/src/main/java/ex/grpc/GreeterClient.java). Again, we're not going to go into much detail about how to implement a client; we'll leave that for the tutorial. @@ -378,13 +374,13 @@ want to connect to. Then we use the channel to construct the stub instance. ```java private final ChannelImpl channel; - private final GreetingGrpc.GreetingBlockingStub blockingStub; + private final GreeterGrpc.GreeterBlockingStub blockingStub; public HelloClient(String host, int port) { channel = NettyChannelBuilder.forAddress(host, port) .negotiationType(NegotiationType.PLAINTEXT) .build(); - blockingStub = GreetingGrpc.newBlockingStub(channel); + blockingStub = GreeterGrpc.newBlockingStub(channel); } ``` @@ -410,7 +406,7 @@ from which we can get our greeting. try { Helloworld.HelloRequest request = Helloworld.HelloRequest.newBuilder().setName(name).build(); - Helloworld.HelloReply reply = blockingStub.hello(request); + Helloworld.HelloReply reply = blockingStub.sayHello(request); logger.info("Greeting: " + reply.getMessage()); } catch (RuntimeException e) { logger.log(Level.WARNING, "RPC failed", e); @@ -436,13 +432,13 @@ 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 +$ ./run_greeter_server.sh ``` and in another terminal window confirm that it receives a message. ```sh -$ ./run_greetings_client.sh +$ ./run_greeter_client.sh ``` ### Adding another client @@ -452,8 +448,3 @@ between code in different languages. So far, we've just generated Java code from our `Greetings` service definition.... ###TODO: Section on Go client for same server - - - - - From 49f3ccdd012153c8c286f54baf2d4a925c1b4314 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 19 Feb 2015 11:09:19 -0800 Subject: [PATCH 49/92] Adds a helloworld sample in ruby. --- ruby/.gitignore | 15 +++++++++ ruby/Gemfile | 15 +++++++++ ruby/README.md | 35 +++++++++++++++++++ ruby/greeter.gemspec | 23 +++++++++++++ ruby/greeter_client.rb | 50 +++++++++++++++++++++++++++ ruby/greeter_server.rb | 60 +++++++++++++++++++++++++++++++++ ruby/lib/helloworld.rb | 18 ++++++++++ ruby/lib/helloworld_services.rb | 24 +++++++++++++ 8 files changed, 240 insertions(+) create mode 100644 ruby/.gitignore create mode 100644 ruby/Gemfile create mode 100644 ruby/README.md create mode 100644 ruby/greeter.gemspec create mode 100755 ruby/greeter_client.rb create mode 100755 ruby/greeter_server.rb create mode 100644 ruby/lib/helloworld.rb create mode 100644 ruby/lib/helloworld_services.rb diff --git a/ruby/.gitignore b/ruby/.gitignore new file mode 100644 index 00000000000..62fcb4fa943 --- /dev/null +++ b/ruby/.gitignore @@ -0,0 +1,15 @@ +/.bundle/ +/.yardoc +/Gemfile.lock +/_yardoc/ +/coverage/ +/doc/ +/pkg/ +/spec/reports/ +/tmp/ +*.bundle +*.so +*.o +*.a +mkmf.log +vendor diff --git a/ruby/Gemfile b/ruby/Gemfile new file mode 100644 index 00000000000..2d76038e09d --- /dev/null +++ b/ruby/Gemfile @@ -0,0 +1,15 @@ +# -*- ruby -*- +# encoding: utf-8 + +source 'https://rubygems.org/' + +# Update this to reflect the local installation of gRPC. +gem 'grpc', path: '/usr/local/google/repos/grpc/src/ruby' + +# TODO: fix this if/when the gRPC repo structure changes. +# +# At the moment it's not possible to use grpc Ruby via git/github reference +# +# git 'git@github.com:grpc/grpc.git' do +# gem 'grpc' +# end diff --git a/ruby/README.md b/ruby/README.md new file mode 100644 index 00000000000..668baf3eb71 --- /dev/null +++ b/ruby/README.md @@ -0,0 +1,35 @@ +gRPC Ruby Helloworld +==================== + +INSTALLATION PREREQUISITES +-------------------------- + +This requires Ruby 2.x, as the gRPC API surface uses keyword args. + +INSTALL +------- + +- Clone this repository. +- Follow the instructions in [INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL) to install the gRPC C core. +- *Temporary* Install gRPC for Ruby from source on your local machine and update path: to refer to it [Gemfile]. + - this is needed until the gRPC ruby gem is published +- Use bundler to install +```sh +$ # from this directory +$ gem install bundler && bundle install +``` + +USAGE +----- + +- Run the server +```sh +$ # from this directory +$ bundle exec ./greeter_server.rb & +``` + +- Run the client +```sh +$ # from this directory +$ bundle exec ./greeter_client.rb +``` diff --git a/ruby/greeter.gemspec b/ruby/greeter.gemspec new file mode 100644 index 00000000000..d0ccf32f7d5 --- /dev/null +++ b/ruby/greeter.gemspec @@ -0,0 +1,23 @@ +# -*- ruby -*- +# encoding: utf-8 + +Gem::Specification.new do |s| + s.name = 'grpc' + s.version = '0.0.0' + s.authors = ['gRPC Authors'] + s.email = 'temiola@google.com' + s.homepage = 'https://github.com/google/grpc-common' + s.summary = 'gRPC Ruby overview sample' + s.description = 'Demonstrates how' + + s.files = `git ls-files -- ruby/*`.split("\n") + s.executables = `git ls-files -- ruby/greeter*.rb`.split("\n").map do |f| + File.basename(f) + end + s.require_paths = ['lib'] + s.platform = Gem::Platform::RUBY + + s.add_dependency 'grpc', '~> 0.0.1' + + s.add_development_dependency 'bundler', '~> 1.7' +end diff --git a/ruby/greeter_client.rb b/ruby/greeter_client.rb new file mode 100755 index 00000000000..e6cb4bad33e --- /dev/null +++ b/ruby/greeter_client.rb @@ -0,0 +1,50 @@ +#!/usr/bin/env ruby + +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Sample app that connects to a Greeter service. +# +# Usage: $ path/to/greeter_client.rb + +this_dir = File.expand_path(File.dirname(__FILE__)) +lib_dir = File.join(this_dir, 'lib') +$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) + +require 'grpc' +require 'helloworld_services' + +def main + stub = Helloworld::Greeter::Stub.new('localhost:50051') + user = ARGV.size > 0 ? ARGV[0] : 'world' + message = stub.say_hello(Helloworld::HelloRequest.new(name: user)).message + p "Greeting: #{message}" +end + +main diff --git a/ruby/greeter_server.rb b/ruby/greeter_server.rb new file mode 100755 index 00000000000..eb1a6ab454c --- /dev/null +++ b/ruby/greeter_server.rb @@ -0,0 +1,60 @@ +#!/usr/bin/env ruby + +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Sample gRPC server that implements the Greeter::Helloworld service. +# +# Usage: $ path/to/greeter_server.rb + +this_dir = File.expand_path(File.dirname(__FILE__)) +lib_dir = File.join(this_dir, 'lib') +$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) + +require 'grpc' +require 'helloworld_services' + +# GreeterServer is simple server that implements the Helloworld Greeter server. +class GreeterServer < Helloworld::Greeter::Service + # say_hello implements the sayHello rpc method. + def say_hello(hello_req, _unused_call) + Helloworld::HelloReply.new(message: "Hello #{hello_req.name}") + end +end + +# main starts an RpcServer that receives requests to GreeterServer at the sample +# server port. +def main + s = GRPC::RpcServer.new + s.add_http2_port('0.0.0.0:50051') + s.handle(GreeterServer) + s.run +end + +main diff --git a/ruby/lib/helloworld.rb b/ruby/lib/helloworld.rb new file mode 100644 index 00000000000..82bdd78e2a4 --- /dev/null +++ b/ruby/lib/helloworld.rb @@ -0,0 +1,18 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: helloworld.proto + +require 'google/protobuf' + +Google::Protobuf::DescriptorPool.generated_pool.build do + add_message "helloworld.HelloRequest" do + optional :name, :string, 1 + end + add_message "helloworld.HelloReply" do + optional :message, :string, 1 + end +end + +module Helloworld + HelloRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("helloworld.HelloRequest").msgclass + HelloReply = Google::Protobuf::DescriptorPool.generated_pool.lookup("helloworld.HelloReply").msgclass +end diff --git a/ruby/lib/helloworld_services.rb b/ruby/lib/helloworld_services.rb new file mode 100644 index 00000000000..9bd528485af --- /dev/null +++ b/ruby/lib/helloworld_services.rb @@ -0,0 +1,24 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# Source: helloworld.proto for package 'helloworld' + +require 'grpc' +require 'helloworld' + +module Helloworld + module Greeter + + # TODO: add proto service documentation here + class Service + + include GRPC::GenericService + + self.marshal_class_method = :encode + self.unmarshal_class_method = :decode + self.service_name = 'helloworld.Greeter' + + rpc :sayHello, HelloRequest, HelloReply + end + + Stub = Service.rpc_stub_class + end +end From c1500a5abb97912618fe72bbf89a4a531ecbc453 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 19 Feb 2015 11:46:19 -0800 Subject: [PATCH 50/92] Minor corrections --- ruby/greeter.gemspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruby/greeter.gemspec b/ruby/greeter.gemspec index d0ccf32f7d5..be1afae7de2 100644 --- a/ruby/greeter.gemspec +++ b/ruby/greeter.gemspec @@ -6,9 +6,9 @@ Gem::Specification.new do |s| s.version = '0.0.0' s.authors = ['gRPC Authors'] s.email = 'temiola@google.com' - s.homepage = 'https://github.com/google/grpc-common' + s.homepage = 'https://github.com/grpc/grpc-common' s.summary = 'gRPC Ruby overview sample' - s.description = 'Demonstrates how' + s.description = 'Simple demo of using gRPC from Ruby' s.files = `git ls-files -- ruby/*`.split("\n") s.executables = `git ls-files -- ruby/greeter*.rb`.split("\n").map do |f| From 7b68400fa42ad54fd35fe28d29e6415c5de35441 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 19 Feb 2015 12:52:26 -0800 Subject: [PATCH 51/92] Fixes the gem name. --- ruby/greeter.gemspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruby/greeter.gemspec b/ruby/greeter.gemspec index be1afae7de2..795c84c0f5f 100644 --- a/ruby/greeter.gemspec +++ b/ruby/greeter.gemspec @@ -2,8 +2,8 @@ # encoding: utf-8 Gem::Specification.new do |s| - s.name = 'grpc' - s.version = '0.0.0' + s.name = 'grpc-greeter' + s.version = '0.1.0' s.authors = ['gRPC Authors'] s.email = 'temiola@google.com' s.homepage = 'https://github.com/grpc/grpc-common' From e89af55a86cd742a076463ee5a639212b029e511 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 19 Feb 2015 13:33:04 -0800 Subject: [PATCH 52/92] Added node hello world example --- node/.gitignore | 3 ++ node/README.md | 30 ++++++++++++++++++++ node/greeter_client.js | 52 ++++++++++++++++++++++++++++++++++ node/greeter_server.js | 63 ++++++++++++++++++++++++++++++++++++++++++ node/helloworld.proto | 50 +++++++++++++++++++++++++++++++++ node/package.json | 7 +++++ 6 files changed, 205 insertions(+) create mode 100644 node/.gitignore create mode 100644 node/README.md create mode 100644 node/greeter_client.js create mode 100644 node/greeter_server.js create mode 100644 node/helloworld.proto create mode 100644 node/package.json diff --git a/node/.gitignore b/node/.gitignore new file mode 100644 index 00000000000..3d06f5db7b3 --- /dev/null +++ b/node/.gitignore @@ -0,0 +1,3 @@ +*~ +node_modules +npm-debug.log \ No newline at end of file diff --git a/node/README.md b/node/README.md new file mode 100644 index 00000000000..4b2c9026892 --- /dev/null +++ b/node/README.md @@ -0,0 +1,30 @@ +# gRPC Node.js Helloworld + +## INSTALLATION REQUIREMENTS + +This requires Node 10.x or greater. + +## INSTALL + + - Clone this repository + - Follow the instructions in [INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL) to install the gRPC C core. + - Run `npm install` to install dependencies + - If `grpc` is not found, clone the [gRPC](https://github.com/grpc/grpc) repository and run `npm install path/to/grpc/src/node`. + +## USAGE + + - Run the server + ```sh + $ # from this directory + $ nodejs ./greeter_server.js & + ``` + - Run the client + ```sh + $ # from this directory + $ nodejs ./greeter_client.js + ``` + +## NOTE + +This directory has a copy of `helloworld.proto` because it currently depends on +some Protocol Buffer 2.0 syntax that is deprecated in Protocol Buffer 3.0. diff --git a/node/greeter_client.js b/node/greeter_client.js new file mode 100644 index 00000000000..ab7050ab213 --- /dev/null +++ b/node/greeter_client.js @@ -0,0 +1,52 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +var PROTO_PATH = __dirname + '/helloworld.proto'; + +var grpc = require('grpc'); +var hello_proto = grpc.load(PROTO_PATH).helloworld; + +function main() { + var client = new hello_proto.Greeter('localhost:50051'); + var user; + if (process.argv.length >= 3) { + user = process.argv[2]; + } else { + user = 'world'; + } + client.sayHello({name: user}, function(err, response) { + console.log('Greeting:', response.message); + }); +} + +main(); diff --git a/node/greeter_server.js b/node/greeter_server.js new file mode 100644 index 00000000000..6d4183c0ced --- /dev/null +++ b/node/greeter_server.js @@ -0,0 +1,63 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +var PROTO_PATH = __dirname + '/helloworld.proto'; + +var grpc = require('grpc'); +var hello_proto = grpc.load(PROTO_PATH).helloworld; + +var Server = grpc.buildServer([hello_proto.Greeter.service]); + +/** + * Implements the sayHello RPC method. + */ +function sayHello(call, callback) { + callback(null, {message: 'Hello ' + call.request.name}); +} + +/** + * Starts an RPC server that receives requests for the Greeter service at the + * sample server port + */ +function main() { + var server = new Server({ + "helloworld.Greeter": { + sayHello: sayHello + } + }); + + server.bind('0.0.0.0:50051'); + server.listen(); +} + +main(); diff --git a/node/helloworld.proto b/node/helloworld.proto new file mode 100644 index 00000000000..e1f5700725a --- /dev/null +++ b/node/helloworld.proto @@ -0,0 +1,50 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "ex.grpc"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc sayHello (HelloRequest) returns (HelloReply) {} +} + +// 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; +} diff --git a/node/package.json b/node/package.json new file mode 100644 index 00000000000..435654034fa --- /dev/null +++ b/node/package.json @@ -0,0 +1,7 @@ +{ + "name": "grpc-greeter", + "version": "0.1.0", + "dependencies": { + "grpc" : "~0.2.0" + } +} From ec8fa8339ed06df87c529f4900a03d8d234d0116 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 19 Feb 2015 13:35:13 -0800 Subject: [PATCH 53/92] Fixed formatting --- node/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/node/README.md b/node/README.md index 4b2c9026892..57dc83ee3f3 100644 --- a/node/README.md +++ b/node/README.md @@ -14,11 +14,14 @@ This requires Node 10.x or greater. ## USAGE - Run the server + ```sh $ # from this directory $ nodejs ./greeter_server.js & ``` + - Run the client + ```sh $ # from this directory $ nodejs ./greeter_client.js From d95693724c45648f2f023cff29df11fc1d9910dd Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Thu, 19 Feb 2015 14:22:52 -0800 Subject: [PATCH 54/92] Add helloworld example in c++ --- cpp/helloworld/Makefile | 47 +++ cpp/helloworld/greeter_client.cc | 91 +++++ cpp/helloworld/greeter_server.cc | 84 ++++ cpp/helloworld/helloworld.pb.cc | 640 +++++++++++++++++++++++++++++++ cpp/helloworld/helloworld.pb.h | 359 +++++++++++++++++ 5 files changed, 1221 insertions(+) create mode 100644 cpp/helloworld/Makefile create mode 100644 cpp/helloworld/greeter_client.cc create mode 100644 cpp/helloworld/greeter_server.cc create mode 100644 cpp/helloworld/helloworld.pb.cc create mode 100644 cpp/helloworld/helloworld.pb.h diff --git a/cpp/helloworld/Makefile b/cpp/helloworld/Makefile new file mode 100644 index 00000000000..38f4ff081fd --- /dev/null +++ b/cpp/helloworld/Makefile @@ -0,0 +1,47 @@ +# +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +CC=g++ +CCFLAGS=-I/usr/local/include -std=c++11 +LDFLAGS=-L/usr/local/lib -lgrpc -lgrpc++ -lprotobuf -ldl + +all: greeter_client greeter_server + +greeter_client: helloworld.pb.cc greeter_client.cc + $(CC) $(CCFLAGS) greeter_client.cc helloworld.pb.cc $(LDFLAGS) -o greeter_client.out + + +greeter_server: helloworld.pb.cc greeter_server.cc + $(CC) $(CCFLAGS) greeter_server.cc helloworld.pb.cc $(LDFLAGS) -o greeter_server.out + +clean: + rm *.out + diff --git a/cpp/helloworld/greeter_client.cc b/cpp/helloworld/greeter_client.cc new file mode 100644 index 00000000000..4a51f5eb382 --- /dev/null +++ b/cpp/helloworld/greeter_client.cc @@ -0,0 +1,91 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "helloworld.pb.h" + +using grpc::ChannelArguments; +using grpc::ChannelInterface; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterClient { + public: + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + std::string SayHello(const std::string& user) { + HelloRequest request; + request.set_name(user); + HelloReply reply; + ClientContext context; + + Status status = stub_->sayHello(&context, request, &reply); + if (status.IsOk()) { + return reply.message(); + } else { + return "Rpc failed"; + } + } + + void Shutdown() { stub_.reset(); } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + grpc_init(); + + GreeterClient greeter( + grpc::CreateChannel("localhost:50051", ChannelArguments())); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter received: " << reply << std::endl; + + greeter.Shutdown(); + + grpc_shutdown(); +} diff --git a/cpp/helloworld/greeter_server.cc b/cpp/helloworld/greeter_server.cc new file mode 100644 index 00000000000..3a2ab60e892 --- /dev/null +++ b/cpp/helloworld/greeter_server.cc @@ -0,0 +1,84 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "helloworld.pb.h" + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterServiceImpl final : public Greeter::Service { + Status sayHello(ServerContext* context, const HelloRequest* request, + HelloReply* reply) override { + std::string prefix("Hello "); + reply->set_message(prefix + request->name()); + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; + + ServerBuilder builder; + builder.AddPort(server_address); + builder.RegisterService(&service); + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + while (true) { + std::this_thread::sleep_for(std::chrono::seconds(5)); + } +} + +int main(int argc, char** argv) { + grpc_init(); + + RunServer(); + + grpc_shutdown(); + return 0; +} diff --git a/cpp/helloworld/helloworld.pb.cc b/cpp/helloworld/helloworld.pb.cc new file mode 100644 index 00000000000..a5b82c5ed5b --- /dev/null +++ b/cpp/helloworld/helloworld.pb.cc @@ -0,0 +1,640 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "helloworld.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace helloworld { + +namespace { + +const ::google::protobuf::Descriptor* HelloRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + HelloRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* HelloReply_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + HelloReply_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_helloworld_2eproto() { + protobuf_AddDesc_helloworld_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "helloworld.proto"); + GOOGLE_CHECK(file != NULL); + HelloRequest_descriptor_ = file->message_type(0); + static const int HelloRequest_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HelloRequest, name_), + }; + HelloRequest_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + HelloRequest_descriptor_, + HelloRequest::default_instance_, + HelloRequest_offsets_, + -1, + -1, + -1, + sizeof(HelloRequest), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HelloRequest, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HelloRequest, _is_default_instance_)); + HelloReply_descriptor_ = file->message_type(1); + static const int HelloReply_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HelloReply, message_), + }; + HelloReply_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + HelloReply_descriptor_, + HelloReply::default_instance_, + HelloReply_offsets_, + -1, + -1, + -1, + sizeof(HelloReply), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HelloReply, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HelloReply, _is_default_instance_)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_helloworld_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + HelloRequest_descriptor_, &HelloRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + HelloReply_descriptor_, &HelloReply::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_helloworld_2eproto() { + delete HelloRequest::default_instance_; + delete HelloRequest_reflection_; + delete HelloReply::default_instance_; + delete HelloReply_reflection_; +} + +void protobuf_AddDesc_helloworld_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\020helloworld.proto\022\nhelloworld\"\034\n\014HelloR" + "equest\022\014\n\004name\030\001 \001(\t\"\035\n\nHelloReply\022\017\n\007me" + "ssage\030\001 \001(\t2I\n\007Greeter\022>\n\010sayHello\022\030.hel" + "loworld.HelloRequest\032\026.helloworld.HelloR" + "eply\"\000B\t\n\007ex.grpcb\006proto3", 185); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "helloworld.proto", &protobuf_RegisterTypes); + HelloRequest::default_instance_ = new HelloRequest(); + HelloReply::default_instance_ = new HelloReply(); + HelloRequest::default_instance_->InitAsDefaultInstance(); + HelloReply::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_helloworld_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_helloworld_2eproto { + StaticDescriptorInitializer_helloworld_2eproto() { + protobuf_AddDesc_helloworld_2eproto(); + } +} static_descriptor_initializer_helloworld_2eproto_; + +namespace { + +static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; +static void MergeFromFail(int line) { + GOOGLE_CHECK(false) << __FILE__ << ":" << line; +} + +} // namespace + + +// =================================================================== + +#ifndef _MSC_VER +const int HelloRequest::kNameFieldNumber; +#endif // !_MSC_VER + +HelloRequest::HelloRequest() + : ::google::protobuf::Message() , _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:helloworld.HelloRequest) +} + +void HelloRequest::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +HelloRequest::HelloRequest(const HelloRequest& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:helloworld.HelloRequest) +} + +void HelloRequest::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +HelloRequest::~HelloRequest() { + // @@protoc_insertion_point(destructor:helloworld.HelloRequest) + SharedDtor(); +} + +void HelloRequest::SharedDtor() { + name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void HelloRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* HelloRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return HelloRequest_descriptor_; +} + +const HelloRequest& HelloRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_helloworld_2eproto(); + return *default_instance_; +} + +HelloRequest* HelloRequest::default_instance_ = NULL; + +HelloRequest* HelloRequest::New(::google::protobuf::Arena* arena) const { + HelloRequest* n = new HelloRequest; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void HelloRequest::Clear() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +bool HelloRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:helloworld.HelloRequest) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "helloworld.HelloRequest.name"); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:helloworld.HelloRequest) + return true; +failure: + // @@protoc_insertion_point(parse_failure:helloworld.HelloRequest) + return false; +#undef DO_ +} + +void HelloRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:helloworld.HelloRequest) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "helloworld.HelloRequest.name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->name(), output); + } + + // @@protoc_insertion_point(serialize_end:helloworld.HelloRequest) +} + +::google::protobuf::uint8* HelloRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:helloworld.HelloRequest) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "helloworld.HelloRequest.name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:helloworld.HelloRequest) + return target; +} + +int HelloRequest::ByteSize() const { + int total_size = 0; + + // optional string name = 1; + if (this->name().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void HelloRequest::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const HelloRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void HelloRequest::MergeFrom(const HelloRequest& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.name().size() > 0) { + + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } +} + +void HelloRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void HelloRequest::CopyFrom(const HelloRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool HelloRequest::IsInitialized() const { + + return true; +} + +void HelloRequest::Swap(HelloRequest* other) { + if (other == this) return; + InternalSwap(other); +} +void HelloRequest::InternalSwap(HelloRequest* other) { + name_.Swap(&other->name_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata HelloRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = HelloRequest_descriptor_; + metadata.reflection = HelloRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int HelloReply::kMessageFieldNumber; +#endif // !_MSC_VER + +HelloReply::HelloReply() + : ::google::protobuf::Message() , _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:helloworld.HelloReply) +} + +void HelloReply::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +HelloReply::HelloReply(const HelloReply& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:helloworld.HelloReply) +} + +void HelloReply::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +HelloReply::~HelloReply() { + // @@protoc_insertion_point(destructor:helloworld.HelloReply) + SharedDtor(); +} + +void HelloReply::SharedDtor() { + message_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void HelloReply::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* HelloReply::descriptor() { + protobuf_AssignDescriptorsOnce(); + return HelloReply_descriptor_; +} + +const HelloReply& HelloReply::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_helloworld_2eproto(); + return *default_instance_; +} + +HelloReply* HelloReply::default_instance_ = NULL; + +HelloReply* HelloReply::New(::google::protobuf::Arena* arena) const { + HelloReply* n = new HelloReply; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void HelloReply::Clear() { + message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +bool HelloReply::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:helloworld.HelloReply) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string message = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_message())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->message().data(), this->message().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "helloworld.HelloReply.message"); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:helloworld.HelloReply) + return true; +failure: + // @@protoc_insertion_point(parse_failure:helloworld.HelloReply) + return false; +#undef DO_ +} + +void HelloReply::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:helloworld.HelloReply) + // optional string message = 1; + if (this->message().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->message().data(), this->message().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "helloworld.HelloReply.message"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->message(), output); + } + + // @@protoc_insertion_point(serialize_end:helloworld.HelloReply) +} + +::google::protobuf::uint8* HelloReply::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:helloworld.HelloReply) + // optional string message = 1; + if (this->message().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->message().data(), this->message().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "helloworld.HelloReply.message"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->message(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:helloworld.HelloReply) + return target; +} + +int HelloReply::ByteSize() const { + int total_size = 0; + + // optional string message = 1; + if (this->message().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->message()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void HelloReply::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const HelloReply* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void HelloReply::MergeFrom(const HelloReply& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.message().size() > 0) { + + message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_); + } +} + +void HelloReply::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void HelloReply::CopyFrom(const HelloReply& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool HelloReply::IsInitialized() const { + + return true; +} + +void HelloReply::Swap(HelloReply* other) { + if (other == this) return; + InternalSwap(other); +} +void HelloReply::InternalSwap(HelloReply* other) { + message_.Swap(&other->message_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata HelloReply::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = HelloReply_descriptor_; + metadata.reflection = HelloReply_reflection_; + return metadata; +} + + +static const char* Greeter_method_names[] = { + "/helloworld.Greeter/sayHello", +}; + +Greeter::Stub* Greeter::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel) { + Greeter::Stub* stub = new Greeter::Stub(); + stub->set_channel(channel); + return stub; +}; + +::grpc::Status Greeter::Stub::sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) { + return ::grpc::BlockingUnaryCall(channel(),::grpc::RpcMethod(Greeter_method_names[0]), context, request, response); +} + +::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* Greeter::Stub::sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq, void* tag) { + return new ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>(channel(), cq, ::grpc::RpcMethod(Greeter_method_names[0]), context, request, tag); +} + +Greeter::AsyncService::AsyncService(::grpc::CompletionQueue* cq) : ::grpc::AsynchronousService(cq, Greeter_method_names, 1) {} + +Greeter::Service::~Service() { + delete service_; +} + +::grpc::Status Greeter::Service::sayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) { + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED); +} + +void Greeter::AsyncService::RequestsayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* cq, void* tag) { + AsynchronousService::RequestAsyncUnary(0, context, request, response, cq, tag); +} + +::grpc::RpcService* Greeter::Service::service() { + if (service_ != nullptr) { + return service_; + } + service_ = new ::grpc::RpcService(); + service_->AddMethod(new ::grpc::RpcServiceMethod( + Greeter_method_names[0], + ::grpc::RpcMethod::NORMAL_RPC, + new ::grpc::RpcMethodHandler< Greeter::Service, ::helloworld::HelloRequest, ::helloworld::HelloReply>( + std::function< ::grpc::Status(Greeter::Service*, ::grpc::ServerContext*, const ::helloworld::HelloRequest*, ::helloworld::HelloReply*)>(&Greeter::Service::sayHello), this), + new ::helloworld::HelloRequest, new ::helloworld::HelloReply)); + return service_; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace helloworld + +// @@protoc_insertion_point(global_scope) diff --git a/cpp/helloworld/helloworld.pb.h b/cpp/helloworld/helloworld.pb.h new file mode 100644 index 00000000000..f49adae84a8 --- /dev/null +++ b/cpp/helloworld/helloworld.pb.h @@ -0,0 +1,359 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto + +#ifndef PROTOBUF_helloworld_2eproto__INCLUDED +#define PROTOBUF_helloworld_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace grpc { +class CompletionQueue; +class ChannelInterface; +class RpcService; +class ServerContext; +template class ClientAsyncResponseReader; +template class ServerAsyncResponseWriter; +} // namespace grpc +// @@protoc_insertion_point(includes) + +namespace helloworld { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_helloworld_2eproto(); +void protobuf_AssignDesc_helloworld_2eproto(); +void protobuf_ShutdownFile_helloworld_2eproto(); + +class HelloRequest; +class HelloReply; + +// =================================================================== + +class HelloRequest : public ::google::protobuf::Message { + public: + HelloRequest(); + virtual ~HelloRequest(); + + HelloRequest(const HelloRequest& from); + + inline HelloRequest& operator=(const HelloRequest& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const HelloRequest& default_instance(); + + void Swap(HelloRequest* other); + + // implements Message ---------------------------------------------- + + inline HelloRequest* New() const { return New(NULL); } + + HelloRequest* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const HelloRequest& from); + void MergeFrom(const HelloRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(HelloRequest* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // @@protoc_insertion_point(class_scope:helloworld.HelloRequest) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + mutable int _cached_size_; + friend void protobuf_AddDesc_helloworld_2eproto(); + friend void protobuf_AssignDesc_helloworld_2eproto(); + friend void protobuf_ShutdownFile_helloworld_2eproto(); + + void InitAsDefaultInstance(); + static HelloRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class HelloReply : public ::google::protobuf::Message { + public: + HelloReply(); + virtual ~HelloReply(); + + HelloReply(const HelloReply& from); + + inline HelloReply& operator=(const HelloReply& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const HelloReply& default_instance(); + + void Swap(HelloReply* other); + + // implements Message ---------------------------------------------- + + inline HelloReply* New() const { return New(NULL); } + + HelloReply* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const HelloReply& from); + void MergeFrom(const HelloReply& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(HelloReply* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string message = 1; + inline void clear_message(); + static const int kMessageFieldNumber = 1; + inline const ::std::string& message() const; + inline void set_message(const ::std::string& value); + inline void set_message(const char* value); + inline void set_message(const char* value, size_t size); + inline ::std::string* mutable_message(); + inline ::std::string* release_message(); + inline void set_allocated_message(::std::string* message); + + // @@protoc_insertion_point(class_scope:helloworld.HelloReply) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr message_; + mutable int _cached_size_; + friend void protobuf_AddDesc_helloworld_2eproto(); + friend void protobuf_AssignDesc_helloworld_2eproto(); + friend void protobuf_ShutdownFile_helloworld_2eproto(); + + void InitAsDefaultInstance(); + static HelloReply* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// HelloRequest + +// optional string name = 1; +inline void HelloRequest::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& HelloRequest::name() const { + // @@protoc_insertion_point(field_get:helloworld.HelloRequest.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void HelloRequest::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:helloworld.HelloRequest.name) +} +inline void HelloRequest::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:helloworld.HelloRequest.name) +} +inline void HelloRequest::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:helloworld.HelloRequest.name) +} +inline ::std::string* HelloRequest::mutable_name() { + + // @@protoc_insertion_point(field_mutable:helloworld.HelloRequest.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* HelloRequest::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void HelloRequest::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:helloworld.HelloRequest.name) +} + +// ------------------------------------------------------------------- + +// HelloReply + +// optional string message = 1; +inline void HelloReply::clear_message() { + message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& HelloReply::message() const { + // @@protoc_insertion_point(field_get:helloworld.HelloReply.message) + return message_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void HelloReply::set_message(const ::std::string& value) { + + message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:helloworld.HelloReply.message) +} +inline void HelloReply::set_message(const char* value) { + + message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:helloworld.HelloReply.message) +} +inline void HelloReply::set_message(const char* value, size_t size) { + + message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:helloworld.HelloReply.message) +} +inline ::std::string* HelloReply::mutable_message() { + + // @@protoc_insertion_point(field_mutable:helloworld.HelloReply.message) + return message_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* HelloReply::release_message() { + + return message_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void HelloReply::set_allocated_message(::std::string* message) { + if (message != NULL) { + + } else { + + } + message_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), message); + // @@protoc_insertion_point(field_set_allocated:helloworld.HelloReply.message) +} + + +class Greeter final { + public: + class Stub final : public ::grpc::InternalStub { + public: + ::grpc::Status sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response); + ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq, void* tag); + }; + static Stub* NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); + + class Service : public ::grpc::SynchronousService { + public: + Service() : service_(nullptr) {} + virtual ~Service(); + virtual ::grpc::Status sayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response); + ::grpc::RpcService* service() override final; + private: + ::grpc::RpcService* service_; + }; + class AsyncService final : public ::grpc::AsynchronousService { + public: + explicit AsyncService(::grpc::CompletionQueue* cq); + ~AsyncService() {}; + void RequestsayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* cq, void *tag); + }; +}; + +// @@protoc_insertion_point(namespace_scope) + +} // namespace helloworld + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_helloworld_2eproto__INCLUDED From 72bc5647960e0ec6cc9e8b5889acdf68f346286f Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Thu, 19 Feb 2015 14:45:41 -0800 Subject: [PATCH 55/92] Resolve comments on makefile --- cpp/helloworld/Makefile | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/cpp/helloworld/Makefile b/cpp/helloworld/Makefile index 38f4ff081fd..7211aa5cbe2 100644 --- a/cpp/helloworld/Makefile +++ b/cpp/helloworld/Makefile @@ -29,19 +29,28 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -CC=g++ -CCFLAGS=-I/usr/local/include -std=c++11 -LDFLAGS=-L/usr/local/lib -lgrpc -lgrpc++ -lprotobuf -ldl +CXX=g++ +CPPFLAGS=-I/usr/local/include -pthread +CXXFLAGS=-std=c++11 +LDFLAGS=-L/usr/local/lib -lgrpc -lgrpc++ -lprotobuf -lpthread -ldl all: greeter_client greeter_server -greeter_client: helloworld.pb.cc greeter_client.cc - $(CC) $(CCFLAGS) greeter_client.cc helloworld.pb.cc $(LDFLAGS) -o greeter_client.out +helloworld.o: helloworld.pb.cc + $(CXX) -c $(CXXFLAGS) $^ +greeter_client.o: greeter_client.cc + $(CXX) -c $(CXXFLAGS) $^ -greeter_server: helloworld.pb.cc greeter_server.cc - $(CC) $(CCFLAGS) greeter_server.cc helloworld.pb.cc $(LDFLAGS) -o greeter_server.out +greeter_server.o: greeter_server.cc + $(CXX) -c $(CXXFLAGS) $^ + +greeter_client: helloworld.pb.o greeter_client.o + $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ + +greeter_server: helloworld.pb.o greeter_server.o + $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ clean: - rm *.out + rm -f *.o greeter_client greeter_server From 2e4032e14c5f0d6b6b40b85e8321ee752d84ecf3 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Thu, 19 Feb 2015 14:52:47 -0800 Subject: [PATCH 56/92] resolve comments --- cpp/helloworld/Makefile | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cpp/helloworld/Makefile b/cpp/helloworld/Makefile index 7211aa5cbe2..b9579e0c96d 100644 --- a/cpp/helloworld/Makefile +++ b/cpp/helloworld/Makefile @@ -36,15 +36,6 @@ LDFLAGS=-L/usr/local/lib -lgrpc -lgrpc++ -lprotobuf -lpthread -ldl all: greeter_client greeter_server -helloworld.o: helloworld.pb.cc - $(CXX) -c $(CXXFLAGS) $^ - -greeter_client.o: greeter_client.cc - $(CXX) -c $(CXXFLAGS) $^ - -greeter_server.o: greeter_server.cc - $(CXX) -c $(CXXFLAGS) $^ - greeter_client: helloworld.pb.o greeter_client.o $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ From f00df5bb8ac523a095ec7319e726697b3187af43 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 20 Feb 2015 11:50:29 +0000 Subject: [PATCH 57/92] Simple streaming example for overview --- protos/hellostreamingworld.proto | 53 ++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 protos/hellostreamingworld.proto diff --git a/protos/hellostreamingworld.proto b/protos/hellostreamingworld.proto new file mode 100644 index 00000000000..ec8405c78b3 --- /dev/null +++ b/protos/hellostreamingworld.proto @@ -0,0 +1,53 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "ex.grpc"; + +package hellostreamingworld; + +// The greeting service definition. +service MultiGreeter { + // Sends multiple greetings + rpc sayHello (HelloRequest) returns (stream HelloReply) {} +} + +// The request message containing the user's name and how many greetings +// they want. +message HelloRequest { + string name = 1; + string num_greetings = 2; +} + +// A response message containing a greeting +message HelloReply { + string message = 1; +} + From 81580a97bbe5411e8576409a2b681a34a070a165 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 20 Feb 2015 03:47:37 -0800 Subject: [PATCH 58/92] Adds a helloworld sample in Go. --- go/README.md | 51 +++++++++++++++ go/greeter_client/main.go | 70 +++++++++++++++++++++ go/greeter_server/main.go | 65 ++++++++++++++++++++ go/helloworld/helloworld.pb.go | 109 +++++++++++++++++++++++++++++++++ 4 files changed, 295 insertions(+) create mode 100644 go/README.md create mode 100644 go/greeter_client/main.go create mode 100644 go/greeter_server/main.go create mode 100644 go/helloworld/helloworld.pb.go diff --git a/go/README.md b/go/README.md new file mode 100644 index 00000000000..df81915c9b7 --- /dev/null +++ b/go/README.md @@ -0,0 +1,51 @@ +gRPC Go Hello World +=================== + +PREREQUISITES +------------- + +- This requires Go 1.4.x +- Requires that [GOPATH is set](https://golang.org/doc/code.html#GOPATH) +```sh +$ go help gopath +$ # ensure the PATH contains $GOPATH/bin or $GOBIN +$ export PATH=PATH: +``` + +INSTALL +------- + +```sh +$ export GOPATH= +$ go install -u github.com/grpc-common/go/greeter_client +$ go install -u github.com/grpc-common/go/greeter_server +``` + +OPTIONAL - Rebuild the generated code +------------------------------------- + +1 First [install protoc](https://github.com/google/protobuf/blob/master/INSTALL.txt) + - For now, this needs to be installed from source + - This is will change once proto3 is officially released +2 Install the protoc Go plugin. +```sh +$ go install -a github.com/golang/protobuf/protoc-gen-go +$ # ensure the PATH contains $GOPATH/bin or $GOBIN +$ export PATH=PATH: +$ +$ # from ths dir; invoke protoc +$ protoc -I ../protos ../protos/helloworld.proto --go_out=plugins=grpc:. +``` + +TRY IT! +------- + +- Run the server +```sh +$ greeter_server & +``` + +- Run the client +```sh +$ greeter_client +``` diff --git a/go/greeter_client/main.go b/go/greeter_client/main.go new file mode 100644 index 00000000000..abe33c0e2ad --- /dev/null +++ b/go/greeter_client/main.go @@ -0,0 +1,70 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +package main + +import ( + "log" + "os" + + pb "github.com/grpc-common/go/helloworld" + "golang.org/x/net/context" + "google.golang.org/grpc" +) + +const ( + address = "localhost:50051" + defaultName = "world" +) + +func main() { + // Set up a connection to the server. + var opts []grpc.DialOption + conn, err := grpc.Dial(address, opts...) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + defer conn.Close() + + // Contact the server and print out its response. + name := defaultName + if len(os.Args) > 1 { + name = os.Args[1] + } + c := pb.NewGreeterClient(conn) + r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name}) + if err != nil { + log.Fatalf("could not greet: %v", err) + } + log.Printf("Greeting: %s", r.Message) +} diff --git a/go/greeter_server/main.go b/go/greeter_server/main.go new file mode 100644 index 00000000000..643524bde76 --- /dev/null +++ b/go/greeter_server/main.go @@ -0,0 +1,65 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +package main + +import ( + "log" + "net" + + pb "github.com/grpc-common/go/helloworld" + "golang.org/x/net/context" + "google.golang.org/grpc" +) + +const ( + port = ":50051" +) + +// server is used to implement hellowrld.GreeterServer. +type server struct{} + +// SayHello implements helloworld.GreeterServer +func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { + return &pb.HelloReply{Message: "Hello " + in.Name}, nil +} + +func main() { + l, err := net.Listen("tcp", port) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + s := grpc.NewServer() + pb.RegisterGreeterServer(s, &server{}) + s.Serve(l) +} diff --git a/go/helloworld/helloworld.pb.go b/go/helloworld/helloworld.pb.go new file mode 100644 index 00000000000..399adda5eaf --- /dev/null +++ b/go/helloworld/helloworld.pb.go @@ -0,0 +1,109 @@ +// Code generated by protoc-gen-go. +// source: helloworld.proto +// DO NOT EDIT! + +/* +Package helloworld is a generated protocol buffer package. + +It is generated from these files: + helloworld.proto + +It has these top-level messages: + HelloRequest + HelloReply +*/ +package helloworld + +import proto "github.com/golang/protobuf/proto" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal + +// The request message containing the user's name. +type HelloRequest struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` +} + +func (m *HelloRequest) Reset() { *m = HelloRequest{} } +func (m *HelloRequest) String() string { return proto.CompactTextString(m) } +func (*HelloRequest) ProtoMessage() {} + +// The response message containing the greetings +type HelloReply struct { + Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` +} + +func (m *HelloReply) Reset() { *m = HelloReply{} } +func (m *HelloReply) String() string { return proto.CompactTextString(m) } +func (*HelloReply) ProtoMessage() {} + +func init() { +} + +// Client API for Greeter service + +type GreeterClient interface { + // Sends a greeting + SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) +} + +type greeterClient struct { + cc *grpc.ClientConn +} + +func NewGreeterClient(cc *grpc.ClientConn) GreeterClient { + return &greeterClient{cc} +} + +func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) { + out := new(HelloReply) + err := grpc.Invoke(ctx, "/helloworld.Greeter/sayHello", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for Greeter service + +type GreeterServer interface { + // Sends a greeting + SayHello(context.Context, *HelloRequest) (*HelloReply, error) +} + +func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) { + s.RegisterService(&_Greeter_serviceDesc, srv) +} + +func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, buf []byte) (proto.Message, error) { + in := new(HelloRequest) + if err := proto.Unmarshal(buf, in); err != nil { + return nil, err + } + out, err := srv.(GreeterServer).SayHello(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + +var _Greeter_serviceDesc = grpc.ServiceDesc{ + ServiceName: "helloworld.Greeter", + HandlerType: (*GreeterServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "sayHello", + Handler: _Greeter_SayHello_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, +} From ea8eb3c7030da5a4396eba646b5f5e6291413030 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 20 Feb 2015 07:48:04 -0800 Subject: [PATCH 59/92] Pushes the optional code-gen section to the bottom --- go/README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/go/README.md b/go/README.md index df81915c9b7..2bcb5ab0a91 100644 --- a/go/README.md +++ b/go/README.md @@ -21,8 +21,21 @@ $ go install -u github.com/grpc-common/go/greeter_client $ go install -u github.com/grpc-common/go/greeter_server ``` -OPTIONAL - Rebuild the generated code -------------------------------------- +TRY IT! +------- + +- Run the server +```sh +$ greeter_server & +``` + +- Run the client +```sh +$ greeter_client +``` + +OPTIONAL - Rebuilding the generated code +---------------------------------------- 1 First [install protoc](https://github.com/google/protobuf/blob/master/INSTALL.txt) - For now, this needs to be installed from source @@ -36,16 +49,3 @@ $ $ # from ths dir; invoke protoc $ protoc -I ../protos ../protos/helloworld.proto --go_out=plugins=grpc:. ``` - -TRY IT! -------- - -- Run the server -```sh -$ greeter_server & -``` - -- Run the client -```sh -$ greeter_client -``` From 4ee7225fbf09b1944dd2a4a31f35dae6f3929047 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 20 Feb 2015 08:14:34 -0800 Subject: [PATCH 60/92] Changed the documentation title --- go/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/README.md b/go/README.md index 2bcb5ab0a91..d464b45d364 100644 --- a/go/README.md +++ b/go/README.md @@ -1,5 +1,5 @@ -gRPC Go Hello World -=================== +gRPC in 3 minutes (Go) +====================== PREREQUISITES ------------- From 600d70cd8dbebd1ef86cad1d1ba0faf600002250 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Fri, 20 Feb 2015 10:50:46 -0800 Subject: [PATCH 61/92] change proto README cpp node ruby --- README.md | 6 +++--- cpp/helloworld/greeter_client.cc | 2 +- cpp/helloworld/greeter_server.cc | 2 +- cpp/helloworld/helloworld.pb.cc | 14 +++++++------- cpp/helloworld/helloworld.pb.h | 8 ++++---- node/greeter_client.js | 2 +- node/greeter_server.js | 6 +++--- node/helloworld.proto | 2 +- protos/helloworld.proto | 2 +- ruby/greeter_server.rb | 2 +- ruby/lib/helloworld_services.rb | 2 +- 11 files changed, 24 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 3a2fb8d7d1e..c48007a1cbd 100644 --- a/README.md +++ b/README.md @@ -187,7 +187,7 @@ package helloworld; // The greeting service definition. service Greeter { // Sends a greeting - rpc sayHello (HelloRequest) returns (HelloReply) {} + rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. @@ -254,7 +254,7 @@ which contains (along with some other useful code): ```java public static interface Greeter { - public void sayHello(ex.grpc.Helloworld.HelloRequest request, + public void SayHello(ex.grpc.Helloworld.HelloRequest request, com.google.net.stubby.stub.StreamObserver responseObserver); } @@ -405,7 +405,7 @@ from which we can get our greeting. try { Helloworld.HelloRequest request = Helloworld.HelloRequest.newBuilder().setName(name).build(); - Helloworld.HelloReply reply = blockingStub.sayHello(request); + Helloworld.HelloReply reply = blockingStub.SayHello(request); logger.info("Greeting: " + reply.getMessage()); } catch (RuntimeException e) { logger.log(Level.WARNING, "RPC failed", e); diff --git a/cpp/helloworld/greeter_client.cc b/cpp/helloworld/greeter_client.cc index 4a51f5eb382..3c2bbc20747 100644 --- a/cpp/helloworld/greeter_client.cc +++ b/cpp/helloworld/greeter_client.cc @@ -62,7 +62,7 @@ class GreeterClient { HelloReply reply; ClientContext context; - Status status = stub_->sayHello(&context, request, &reply); + Status status = stub_->SayHello(&context, request, &reply); if (status.IsOk()) { return reply.message(); } else { diff --git a/cpp/helloworld/greeter_server.cc b/cpp/helloworld/greeter_server.cc index 3a2ab60e892..01a0bf242dd 100644 --- a/cpp/helloworld/greeter_server.cc +++ b/cpp/helloworld/greeter_server.cc @@ -52,7 +52,7 @@ using helloworld::HelloReply; using helloworld::Greeter; class GreeterServiceImpl final : public Greeter::Service { - Status sayHello(ServerContext* context, const HelloRequest* request, + Status SayHello(ServerContext* context, const HelloRequest* request, HelloReply* reply) override { std::string prefix("Hello "); reply->set_message(prefix + request->name()); diff --git a/cpp/helloworld/helloworld.pb.cc b/cpp/helloworld/helloworld.pb.cc index a5b82c5ed5b..9540f2c94c1 100644 --- a/cpp/helloworld/helloworld.pb.cc +++ b/cpp/helloworld/helloworld.pb.cc @@ -109,7 +109,7 @@ void protobuf_AddDesc_helloworld_2eproto() { ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( "\n\020helloworld.proto\022\nhelloworld\"\034\n\014HelloR" "equest\022\014\n\004name\030\001 \001(\t\"\035\n\nHelloReply\022\017\n\007me" - "ssage\030\001 \001(\t2I\n\007Greeter\022>\n\010sayHello\022\030.hel" + "ssage\030\001 \001(\t2I\n\007Greeter\022>\n\010SayHello\022\030.hel" "loworld.HelloRequest\032\026.helloworld.HelloR" "eply\"\000B\t\n\007ex.grpcb\006proto3", 185); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( @@ -587,7 +587,7 @@ void HelloReply::InternalSwap(HelloReply* other) { static const char* Greeter_method_names[] = { - "/helloworld.Greeter/sayHello", + "/helloworld.Greeter/SayHello", }; Greeter::Stub* Greeter::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel) { @@ -596,11 +596,11 @@ Greeter::Stub* Greeter::NewStub(const std::shared_ptr< ::grpc::ChannelInterface> return stub; }; -::grpc::Status Greeter::Stub::sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) { +::grpc::Status Greeter::Stub::SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) { return ::grpc::BlockingUnaryCall(channel(),::grpc::RpcMethod(Greeter_method_names[0]), context, request, response); } -::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* Greeter::Stub::sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq, void* tag) { +::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* Greeter::Stub::SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq, void* tag) { return new ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>(channel(), cq, ::grpc::RpcMethod(Greeter_method_names[0]), context, request, tag); } @@ -610,11 +610,11 @@ Greeter::Service::~Service() { delete service_; } -::grpc::Status Greeter::Service::sayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) { +::grpc::Status Greeter::Service::SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED); } -void Greeter::AsyncService::RequestsayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* cq, void* tag) { +void Greeter::AsyncService::RequestSayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* cq, void* tag) { AsynchronousService::RequestAsyncUnary(0, context, request, response, cq, tag); } @@ -627,7 +627,7 @@ void Greeter::AsyncService::RequestsayHello(::grpc::ServerContext* context, ::he Greeter_method_names[0], ::grpc::RpcMethod::NORMAL_RPC, new ::grpc::RpcMethodHandler< Greeter::Service, ::helloworld::HelloRequest, ::helloworld::HelloReply>( - std::function< ::grpc::Status(Greeter::Service*, ::grpc::ServerContext*, const ::helloworld::HelloRequest*, ::helloworld::HelloReply*)>(&Greeter::Service::sayHello), this), + std::function< ::grpc::Status(Greeter::Service*, ::grpc::ServerContext*, const ::helloworld::HelloRequest*, ::helloworld::HelloReply*)>(&Greeter::Service::SayHello), this), new ::helloworld::HelloRequest, new ::helloworld::HelloReply)); return service_; } diff --git a/cpp/helloworld/helloworld.pb.h b/cpp/helloworld/helloworld.pb.h index f49adae84a8..1eb870166af 100644 --- a/cpp/helloworld/helloworld.pb.h +++ b/cpp/helloworld/helloworld.pb.h @@ -319,8 +319,8 @@ class Greeter final { public: class Stub final : public ::grpc::InternalStub { public: - ::grpc::Status sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response); - ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq, void* tag); + ::grpc::Status SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response); + ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq, void* tag); }; static Stub* NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); @@ -328,7 +328,7 @@ class Greeter final { public: Service() : service_(nullptr) {} virtual ~Service(); - virtual ::grpc::Status sayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response); + virtual ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response); ::grpc::RpcService* service() override final; private: ::grpc::RpcService* service_; @@ -337,7 +337,7 @@ class Greeter final { public: explicit AsyncService(::grpc::CompletionQueue* cq); ~AsyncService() {}; - void RequestsayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* cq, void *tag); + void RequestSayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* cq, void *tag); }; }; diff --git a/node/greeter_client.js b/node/greeter_client.js index ab7050ab213..db45afca77a 100644 --- a/node/greeter_client.js +++ b/node/greeter_client.js @@ -44,7 +44,7 @@ function main() { } else { user = 'world'; } - client.sayHello({name: user}, function(err, response) { + client.SayHello({name: user}, function(err, response) { console.log('Greeting:', response.message); }); } diff --git a/node/greeter_server.js b/node/greeter_server.js index 6d4183c0ced..fa95cea2e9a 100644 --- a/node/greeter_server.js +++ b/node/greeter_server.js @@ -39,9 +39,9 @@ var hello_proto = grpc.load(PROTO_PATH).helloworld; var Server = grpc.buildServer([hello_proto.Greeter.service]); /** - * Implements the sayHello RPC method. + * Implements the SayHello RPC method. */ -function sayHello(call, callback) { +function SayHello(call, callback) { callback(null, {message: 'Hello ' + call.request.name}); } @@ -52,7 +52,7 @@ function sayHello(call, callback) { function main() { var server = new Server({ "helloworld.Greeter": { - sayHello: sayHello + SayHello: SayHello } }); diff --git a/node/helloworld.proto b/node/helloworld.proto index e1f5700725a..a52c947f895 100644 --- a/node/helloworld.proto +++ b/node/helloworld.proto @@ -36,7 +36,7 @@ package helloworld; // The greeting service definition. service Greeter { // Sends a greeting - rpc sayHello (HelloRequest) returns (HelloReply) {} + rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. diff --git a/protos/helloworld.proto b/protos/helloworld.proto index 4781fb48304..f9abd3d87f7 100644 --- a/protos/helloworld.proto +++ b/protos/helloworld.proto @@ -36,7 +36,7 @@ package helloworld; // The greeting service definition. service Greeter { // Sends a greeting - rpc sayHello (HelloRequest) returns (HelloReply) {} + rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. diff --git a/ruby/greeter_server.rb b/ruby/greeter_server.rb index eb1a6ab454c..d4f9cf7d0f8 100755 --- a/ruby/greeter_server.rb +++ b/ruby/greeter_server.rb @@ -42,7 +42,7 @@ require 'helloworld_services' # GreeterServer is simple server that implements the Helloworld Greeter server. class GreeterServer < Helloworld::Greeter::Service - # say_hello implements the sayHello rpc method. + # say_hello implements the SayHello rpc method. def say_hello(hello_req, _unused_call) Helloworld::HelloReply.new(message: "Hello #{hello_req.name}") end diff --git a/ruby/lib/helloworld_services.rb b/ruby/lib/helloworld_services.rb index 9bd528485af..7da45ebc6b2 100644 --- a/ruby/lib/helloworld_services.rb +++ b/ruby/lib/helloworld_services.rb @@ -16,7 +16,7 @@ module Helloworld self.unmarshal_class_method = :decode self.service_name = 'helloworld.Greeter' - rpc :sayHello, HelloRequest, HelloReply + rpc :SayHello, HelloRequest, HelloReply end Stub = Service.rpc_stub_class From 3440548d83452321d72e2b93992c298f999f1359 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Fri, 20 Feb 2015 11:35:20 -0800 Subject: [PATCH 62/92] revert js changes. --- node/greeter_client.js | 2 +- node/greeter_server.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/node/greeter_client.js b/node/greeter_client.js index db45afca77a..ab7050ab213 100644 --- a/node/greeter_client.js +++ b/node/greeter_client.js @@ -44,7 +44,7 @@ function main() { } else { user = 'world'; } - client.SayHello({name: user}, function(err, response) { + client.sayHello({name: user}, function(err, response) { console.log('Greeting:', response.message); }); } diff --git a/node/greeter_server.js b/node/greeter_server.js index fa95cea2e9a..2fb95f0f90e 100644 --- a/node/greeter_server.js +++ b/node/greeter_server.js @@ -41,7 +41,7 @@ var Server = grpc.buildServer([hello_proto.Greeter.service]); /** * Implements the SayHello RPC method. */ -function SayHello(call, callback) { +function sayHello(call, callback) { callback(null, {message: 'Hello ' + call.request.name}); } @@ -52,7 +52,7 @@ function SayHello(call, callback) { function main() { var server = new Server({ "helloworld.Greeter": { - SayHello: SayHello + sayHello: sayHello } }); From b7538ee7554fde3e5225db379c816ed78f4c93f7 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 20 Feb 2015 22:56:43 +0100 Subject: [PATCH 63/92] Improving user experience. --- cpp/helloworld/Makefile | 79 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 8 deletions(-) diff --git a/cpp/helloworld/Makefile b/cpp/helloworld/Makefile index b9579e0c96d..83f2ad49044 100644 --- a/cpp/helloworld/Makefile +++ b/cpp/helloworld/Makefile @@ -29,19 +29,82 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -CXX=g++ -CPPFLAGS=-I/usr/local/include -pthread -CXXFLAGS=-std=c++11 -LDFLAGS=-L/usr/local/lib -lgrpc -lgrpc++ -lprotobuf -lpthread -ldl +CXX = g++ +CPPFLAGS = -I/usr/local/include -pthread +CXXFLAGS = -std=c++11 +LDFLAGS = -L/usr/local/lib -lgrpc -lgrpc++ -lprotobuf -lpthread -ldl +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` -all: greeter_client greeter_server +PROTOS_PATH = ../../protos + +vpath %.proto $(PROTOS_PATH) + +all: system-check greeter_client greeter_server greeter_client: helloworld.pb.o greeter_client.o - $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ + $(CXX) $^ $(LDFLAGS) -o $@ greeter_server: helloworld.pb.o greeter_server.o - $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ + $(CXX) $^ $(LDFLAGS) -o $@ + +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< clean: - rm -f *.o greeter_client greeter_server + rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server + + +# The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + +PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + +SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif +system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-alpha-1" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif From 8c0464dcf64507d028601abe97e003720c656922 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 20 Feb 2015 14:19:31 -0800 Subject: [PATCH 64/92] Fixes var name --- go/greeter_server/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/greeter_server/main.go b/go/greeter_server/main.go index 643524bde76..231f5c607ba 100644 --- a/go/greeter_server/main.go +++ b/go/greeter_server/main.go @@ -55,11 +55,11 @@ func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloRe } func main() { - l, err := net.Listen("tcp", port) + lis, err := net.Listen("tcp", port) if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterGreeterServer(s, &server{}) - s.Serve(l) + s.Serve(lis) } From bc0c2dcc6b91e56eaacab5990106450d0560d542 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 20 Feb 2015 15:24:56 -0800 Subject: [PATCH 65/92] Created new top-level README_NEW --- README_NEW.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 README_NEW.md diff --git a/README_NEW.md b/README_NEW.md new file mode 100644 index 00000000000..583136bc0dd --- /dev/null +++ b/README_NEW.md @@ -0,0 +1,8 @@ + +# Please pick your language to proceed: +### [C++](https://github.com/grpc/grpc-common/tree/master/cpp) +### [Java](https://github.com/grpc/grpc-common/tree/master/java) +### [Python](https://github.com/grpc/grpc-common/tree/master/python) +### [Go](https://github.com/grpc/grpc-common/tree/master/go) +### [ruby](https://github.com/grpc/grpc-common/tree/master/ruby) +### [Node.js](https://github.com/grpc/grpc-common/tree/master/node) From 3a5592ce1ebfe3af2169b05827d5b9eee6ad8067 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 20 Feb 2015 15:32:42 -0800 Subject: [PATCH 66/92] Created cpp/README --- cpp/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 cpp/README.md diff --git a/cpp/README.md b/cpp/README.md new file mode 100644 index 00000000000..376a3731c30 --- /dev/null +++ b/cpp/README.md @@ -0,0 +1,8 @@ +#gRPC C++ Getting started + +First you need to install gRPC on your system. Follow the instructions here: +[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/INSTALL). + +After installing, you can proceed to the [gRPC C++ Hello World tutorial](https://github.com/grpc/grpc-common/cpp/helloworld). + +A more detailed tutorial is coming soon. From aa6c5fd7769cf2d398852153e9c89bbe5a0e0b4e Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 20 Feb 2015 15:41:55 -0800 Subject: [PATCH 67/92] Fixed broken link --- cpp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/README.md b/cpp/README.md index 376a3731c30..a95bd3c8f0e 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -1,7 +1,7 @@ #gRPC C++ Getting started First you need to install gRPC on your system. Follow the instructions here: -[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/INSTALL). +[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). After installing, you can proceed to the [gRPC C++ Hello World tutorial](https://github.com/grpc/grpc-common/cpp/helloworld). From 2f22e84f725b2aa90c203410dff0b75c8ec25599 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 20 Feb 2015 16:39:32 -0800 Subject: [PATCH 68/92] Created helloworld tutorial outline --- cpp/helloworld/README.md | 95 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 cpp/helloworld/README.md diff --git a/cpp/helloworld/README.md b/cpp/helloworld/README.md new file mode 100644 index 00000000000..952325b4461 --- /dev/null +++ b/cpp/helloworld/README.md @@ -0,0 +1,95 @@ +# gRPC C++ Hello World Tutorial + +### Install gRPC +Make sure you have installed gRPC on your system. Follow the instructions here: +[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). + +### Get the tutorial source code + +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: + + +```sh +$ git clone https://github.com/google/grpc-common.git +``` + +Change your current directory to grpc-common/cpp/helloworld + +```sh +$ cd grpc-common/cpp/helloworld/ +``` + +### 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. As you saw in the +[overview](#protocolbuffers) above, gRPC does this using [protocol +buffers](https://developers.google.com/protocol-buffers/docs/overview). We +use the protocol buffers interface definition language (IDL) to define our +service methods, and define the parameters and return +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](https://github.com/grpc/grpc-common/blob/master/protos/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 single `HelloReply`. This is the simplest type of RPC you +can specify in gRPC - we'll look at some other types later in this document. + +``` +syntax = "proto3"; + +option java_package = "ex.grpc"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} + +``` + + +### 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. 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. + +To generate the client and server side interfaces: + +```sh +$ make helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + +```sh +$protoc -I ../../protos/ --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin helloworld.proto +``` + +### Writing a client + +This is an incomplete tutorial. For now the reader should refer to [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). + +### Writing a server + +This is an incomplete tutorial. For now the reader should refer to [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). From ca8c87738c5eb2c40173506131997efb03a30cde Mon Sep 17 00:00:00 2001 From: David Symonds Date: Sat, 21 Feb 2015 12:11:55 +1100 Subject: [PATCH 69/92] Tidy up README.md. Simply Go version requirement. Use `go get` instead of `go install`. Don't mention $GOBIN, which is irrelevant for most people. Fix a couple of typos. --- go/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/go/README.md b/go/README.md index d464b45d364..5d837f969da 100644 --- a/go/README.md +++ b/go/README.md @@ -4,7 +4,7 @@ gRPC in 3 minutes (Go) PREREQUISITES ------------- -- This requires Go 1.4.x +- This requires Go 1.4 - Requires that [GOPATH is set](https://golang.org/doc/code.html#GOPATH) ```sh $ go help gopath @@ -42,10 +42,10 @@ OPTIONAL - Rebuilding the generated code - This is will change once proto3 is officially released 2 Install the protoc Go plugin. ```sh -$ go install -a github.com/golang/protobuf/protoc-gen-go -$ # ensure the PATH contains $GOPATH/bin or $GOBIN -$ export PATH=PATH: +$ go get -a github.com/golang/protobuf/protoc-gen-go +$ # ensure the PATH contains $GOPATH/bin +$ export PATH=PATH:$GOPATH/bin $ -$ # from ths dir; invoke protoc +$ # from this dir; invoke protoc $ protoc -I ../protos ../protos/helloworld.proto --go_out=plugins=grpc:. ``` From 8169a6876245770f453e2cfe2517be91315bcf07 Mon Sep 17 00:00:00 2001 From: David Symonds Date: Sat, 21 Feb 2015 12:23:36 +1100 Subject: [PATCH 70/92] Update to match standard Go style. Remove completely unused dial options, and reorder a bit of code to match what real code would look like. --- go/greeter_client/main.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/go/greeter_client/main.go b/go/greeter_client/main.go index abe33c0e2ad..3398040d7e5 100644 --- a/go/greeter_client/main.go +++ b/go/greeter_client/main.go @@ -49,19 +49,18 @@ const ( func main() { // Set up a connection to the server. - var opts []grpc.DialOption - conn, err := grpc.Dial(address, opts...) + conn, err := grpc.Dial(address) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() + c := pb.NewGreeterClient(conn) // Contact the server and print out its response. name := defaultName if len(os.Args) > 1 { name = os.Args[1] } - c := pb.NewGreeterClient(conn) r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name}) if err != nil { log.Fatalf("could not greet: %v", err) From 051969c36a39221578a5346c99130802a56b5da0 Mon Sep 17 00:00:00 2001 From: David Symonds Date: Sat, 21 Feb 2015 12:27:23 +1100 Subject: [PATCH 71/92] More README.md improvements. Suggest the standard `go get` for downloading the demo. Remove instruction to set GOPATH during install flow, since the prerequisites section already does that. --- go/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/go/README.md b/go/README.md index 5d837f969da..7b90157043d 100644 --- a/go/README.md +++ b/go/README.md @@ -16,9 +16,8 @@ INSTALL ------- ```sh -$ export GOPATH= -$ go install -u github.com/grpc-common/go/greeter_client -$ go install -u github.com/grpc-common/go/greeter_server +$ go get -u github.com/grpc-common/go/greeter_client +$ go get -u github.com/grpc-common/go/greeter_server ``` TRY IT! From 6c359b36cd9f940d913d428bbaeb38a07806c4ce Mon Sep 17 00:00:00 2001 From: Qi Zhao Date: Fri, 20 Feb 2015 17:33:15 -0800 Subject: [PATCH 72/92] make the format correct. --- go/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/go/README.md b/go/README.md index 7b90157043d..2cab9092ae2 100644 --- a/go/README.md +++ b/go/README.md @@ -39,6 +39,7 @@ OPTIONAL - Rebuilding the generated code 1 First [install protoc](https://github.com/google/protobuf/blob/master/INSTALL.txt) - For now, this needs to be installed from source - This is will change once proto3 is officially released + 2 Install the protoc Go plugin. ```sh $ go get -a github.com/golang/protobuf/protoc-gen-go From d314cd2e884dc3730c879e7a2b7e1c84538cdeaa Mon Sep 17 00:00:00 2001 From: Qi Zhao Date: Fri, 20 Feb 2015 17:54:59 -0800 Subject: [PATCH 73/92] Improve README.md --- go/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/go/README.md b/go/README.md index 2cab9092ae2..bf5d6c8cf48 100644 --- a/go/README.md +++ b/go/README.md @@ -8,8 +8,8 @@ PREREQUISITES - Requires that [GOPATH is set](https://golang.org/doc/code.html#GOPATH) ```sh $ go help gopath -$ # ensure the PATH contains $GOPATH/bin or $GOBIN -$ export PATH=PATH: +$ # ensure the PATH contains $GOPATH/bin +$ export PATH=$PATH:$GOPATH/bin ``` INSTALL @@ -43,8 +43,6 @@ OPTIONAL - Rebuilding the generated code 2 Install the protoc Go plugin. ```sh $ go get -a github.com/golang/protobuf/protoc-gen-go -$ # ensure the PATH contains $GOPATH/bin -$ export PATH=PATH:$GOPATH/bin $ $ # from this dir; invoke protoc $ protoc -I ../protos ../protos/helloworld.proto --go_out=plugins=grpc:. From 29bfc13ddae6c4d143519e01d5cc970b75168869 Mon Sep 17 00:00:00 2001 From: Jayant Kolhe Date: Fri, 20 Feb 2015 17:55:23 -0800 Subject: [PATCH 74/92] Update README.md Fix broken link --- cpp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/README.md b/cpp/README.md index a95bd3c8f0e..84fa34e7055 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -3,6 +3,6 @@ First you need to install gRPC on your system. Follow the instructions here: [https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). -After installing, you can proceed to the [gRPC C++ Hello World tutorial](https://github.com/grpc/grpc-common/cpp/helloworld). +After installing, you can proceed to the [gRPC C++ Hello World tutorial](helloworld/README.md). A more detailed tutorial is coming soon. From eb158ffb584e5067460e812a058b46ea517a1de2 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Sat, 21 Feb 2015 06:29:53 -0800 Subject: [PATCH 75/92] Update README.md --- ruby/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ruby/README.md b/ruby/README.md index 668baf3eb71..1fc19a4f246 100644 --- a/ruby/README.md +++ b/ruby/README.md @@ -1,26 +1,26 @@ -gRPC Ruby Helloworld -==================== +gRPC in 3 minutes (Ruby) +======================== -INSTALLATION PREREQUISITES --------------------------- +PREREQUISITES +------------- -This requires Ruby 2.x, as the gRPC API surface uses keyword args. +This requires Ruby 2.1, as the gRPC API surface uses keyword args. INSTALL ------- - Clone this repository. - Follow the instructions in [INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL) to install the gRPC C core. -- *Temporary* Install gRPC for Ruby from source on your local machine and update path: to refer to it [Gemfile]. - - this is needed until the gRPC ruby gem is published +- *Temporary* Install the full gRPC distribution from source on your local machine and update path: in [Gemfile] to refer src/ruby within it. + - this is necessary until the gRPC ruby gem is published - Use bundler to install ```sh $ # from this directory $ gem install bundler && bundle install ``` -USAGE ------ +Try it! +------- - Run the server ```sh From 9b3b2a23c15e39b1d8bd8f3b2416ff5ea59f3d77 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 23 Feb 2015 13:36:27 +0000 Subject: [PATCH 76/92] Added Go client example section, more tidying up of general info including protobuf. --- README.md | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 3a2fb8d7d1e..cb30f7d3c31 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,12 @@ 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! +## What's in this repository? + +The `grpc-common` repository contains documentation, resources, and examples for all gRPC users + +You can find out about the gRPC source code repositories in [`grpc`](https://github.com/grpc/grpc). + ## What is gRPC? In gRPC a *client* application can directly call @@ -69,23 +75,18 @@ a single Hello World method. - Create a Java server that implements this interface. - Create a Java client that accesses the Java server. -- Create a [probably need a different language now] client that accesses +- Create a Go client that accesses the same Java server. -- Update the service with more advanced features like RPC streaming. +- Update the service with a streaming RPC. 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: +repository. 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. This is an introductory example rather than a comprehensive tutorial, so don't worry if you're not a Go or -Java developer - the concepts introduced here are similar for all languages, -and complete tutorials and reference documentation for all gRPC -languages are coming soon. +Java developer - the concepts are similar for all languages, and you can find more implementations of our Hello World example in other languages in the language-specific folders in this repository. Complete tutorials and reference documentation for all gRPC languages are coming soon. ### Setup @@ -170,7 +171,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](java/src/main/proto/helloworld.proto). The `Greeting` +[helloworld.proto](protos/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 @@ -223,13 +224,7 @@ 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: - -```sh -$ pushd external/grpc_java -$ make java_plugin -$ popd -``` +To build the plugin, follow the instructions in the relevant repo: for Java, the instructions are in [`grpc-java1](https://github.com/grpc/grpc-java). To use it to generate the code: @@ -440,6 +435,7 @@ and in another terminal window confirm that it receives a message. $ ./run_greeter_client.sh ``` + ### Adding another client From 683232652ecb6cb86cea2e743e69f009bfe39de9 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 23 Feb 2015 13:37:41 +0000 Subject: [PATCH 77/92] More tidying up --- README.md | 83 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 73 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index cb30f7d3c31..edb2b9daf89 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,14 @@ Hello World example. More documentation is coming soon! ## What's in this repository? -The `grpc-common` repository contains documentation, resources, and examples for all gRPC users +The `grpc-common` repository contains documentation, resources, and examples +for all gRPC users. You can find examples and instructions specific to your +favourite language in the relevant subdirectory. + +You can find out about the gRPC source code repositories in +[`grpc`](https://github.com/grpc/grpc). Each repository provides instructions +for building the appropriate libraries for your language. -You can find out about the gRPC source code repositories in [`grpc`](https://github.com/grpc/grpc). ## What is gRPC? @@ -51,7 +56,11 @@ While protocol buffers have been available for open source users for some time, our examples use a new flavour of protocol buffers called proto3, which has a slightly simplified syntax, some useful new features, and supports lots more languages. This is currently available as an alpha release in -[languages] from [wherever it's going], with more languages in development. +Java, C++ from [the protocol buffers Github +repo](https://github.com/google/protobuf/releases), as well as a Go language +generator [wherever that is](), with more languages in development. Full +documentation for proto3 is currently in development but you can see +the major differences from the current default version in the [release notes](https://github.com/google/protobuf/releases). In general, we recommend that you use proto3 with gRPC as it lets you use the full range of gRPC-supported languages, as well as avoiding compatibility @@ -86,7 +95,10 @@ than how to install and run a few git commands. This is an introductory example rather than a comprehensive tutorial, so don't worry if you're not a Go or -Java developer - the concepts are similar for all languages, and you can find more implementations of our Hello World example in other languages in the language-specific folders in this repository. Complete tutorials and reference documentation for all gRPC languages are coming soon. +Java developer - the concepts are similar for all languages, and you can +find more implementations of our Hello World example in other languages in +the language-specific folders in this repository. Complete tutorials and +reference documentation for all gRPC languages are coming soon. ### Setup @@ -224,7 +236,8 @@ 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-java1](https://github.com/grpc/grpc-java). +To build the plugin, follow the instructions in the relevant repo: for Java, +the instructions are in [`grpc-java1](https://github.com/grpc/grpc-java). To use it to generate the code: @@ -236,6 +249,8 @@ $ protoc -I . helloworld.proto --java_out=src/main/java ``` +[need to update this once I get the plugin built] + This generates the following classes, which contain all the generated code we need to create our example: @@ -435,12 +450,60 @@ and in another terminal window confirm that it receives a message. $ ./run_greeter_client.sh ``` - ### Adding another client - Finally, let's look at one of gRPC's most useful features - interoperability -between code in different languages. So far, we've just generated Java code -from our `Greeter` service definition.... +between code in different languages. So far, we've just looked at Java code +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) +that we used for the Java example. + +So, for example, if we visit the [`go` +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 +at `localhost:50051` and uses a stub to call the `SayHello` method with a +`HelloRequest`: + +```go +const ( + address = "localhost:50051" + defaultName = "world" +) + +func main() { + // Set up a connection to the server. + conn, err := grpc.Dial(address) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + defer conn.Close() + c := pb.NewGreeterClient(conn) + + // Contact the server and print out its response. + name := defaultName + if len(os.Args) > 1 { + name = os.Args[1] + } + r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: + name}) + if err != nil { + log.Fatalf("could not greet: %v", err) + } + log.Printf("Greeting: %s", r.Message) +} +``` + + +If we run the Java server from earlier in another terminal window, we can +run the Go client and connect to it just like the Java client, even though +it's written in a different language. + +``` +$ greeter_client +``` -###TODO: Section on Go client for same server From 5279a5f7ae94077948d74127a46af5201770075e Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 23 Feb 2015 13:39:16 +0000 Subject: [PATCH 78/92] Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index edb2b9daf89..7f695cab907 100644 --- a/README.md +++ b/README.md @@ -237,7 +237,7 @@ 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-java1](https://github.com/grpc/grpc-java). +the instructions are in [`grpc-java`](https://github.com/grpc/grpc-java). To use it to generate the code: From 54e0c6d4121e986b3b1acd35cbc74cba3bde4a72 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 23 Feb 2015 16:00:38 +0000 Subject: [PATCH 79/92] Starting the C++ Route Guide tutorial... --- cpp/cpptutorial.md | 108 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 cpp/cpptutorial.md diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md new file mode 100644 index 00000000000..d6c38f4f9bc --- /dev/null +++ b/cpp/cpptutorial.md @@ -0,0 +1,108 @@ +#gRPC Basics: C++ + +This tutorial provides a basic C++ programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate server and client code using the protocol buffer compiler. +- Use the C++ gRPC API to write a simple client and server for your service. + +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. + +This isn't a comprehensive guide to using gRPC in C++: more reference documentation is coming soon. + +## Why use gRPC? + +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +With gRPC we can define our service once in a .proto file and implement clients and servers in , which in turn - all the complexity of communication between different languages and environments is handled for you by gRPC. gRPC also + +We also get all the advantages of working with protocol buffers + +[possibly insert more advantages here] + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/cpp/route_guide](https://github.com/grpc/grpc-common/cpp/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/google/grpc-common.git +``` + +Then change your current directory to `grpc-common/cpp/route_guide`: +```shell +$ cd grpc-common/cpp/route_guide +``` + +Although we've provided the complete example so you don't need to generate the gRPC code yourself, if you want to try generating your own server and client interface code you can follow the setup instructions for the C++ gRPC libraries in [grpc/grpc/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). + + +## Defining the service + +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +``` +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +``` + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. +``` + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} +``` + +- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. +``` + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. +``` + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +``` + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + + +## Generating client and server code + +Now we need to ... + + +## Creating the server + +First let's look at implementing our R + +There are two parts to making our `RouteGuide` service work: +- + + +## Creating the client + + + + + + From 450d112c02270149222578ec2238cca6516be285 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 23 Feb 2015 16:05:25 +0000 Subject: [PATCH 80/92] Small fixes in snippets. --- cpp/cpptutorial.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index d6c38f4f9bc..6f3f330c2c6 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -55,7 +55,7 @@ Then you define `rpc` methods inside your service definition, specifying their r rpc GetFeature(Point) returns (Feature) {} ``` -- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. +- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. ``` // Obtains the Features available within the given Rectangle. Results are // streamed rather than returned at once (e.g. in a response message with a @@ -64,25 +64,30 @@ Then you define `rpc` methods inside your service definition, specifying their r rpc ListFeatures(Rectangle) returns (stream Feature) {} ``` -- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. +- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. ``` // Accepts a stream of Points on a route being traversed, returning a // RouteSummary when traversal is completed. rpc RecordRoute(stream Point) returns (RouteSummary) {} ``` -- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. +- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. ``` - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} ``` Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: ``` - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} +// Points are represented as latitude-longitude pairs in the E7 representation +// (degrees multiplied by 10**7 and rounded to the nearest integer). +// Latitudes should be in the range +/- 90 degrees and longitude should be in +// the range +/- 180 degrees (inclusive). +message Point { + int32 latitude = 1; + int32 longitude = 2; +} ``` From 7a21966ee7e0c4487887d34dda969e8b3457edf9 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 23 Feb 2015 16:42:21 +0000 Subject: [PATCH 81/92] More tutorial.. --- cpp/cpptutorial.md | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index 6f3f330c2c6..ade134c86b4 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -14,9 +14,7 @@ This isn't a comprehensive guide to using gRPC in C++: more reference documentat Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. -With gRPC we can define our service once in a .proto file and implement clients and servers in , which in turn - all the complexity of communication between different languages and environments is handled for you by gRPC. gRPC also - -We also get all the advantages of working with protocol buffers +With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. [possibly insert more advantages here] @@ -93,15 +91,32 @@ message Point { ## Generating client and server code -Now we need to ... +Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. + +For simplicity, we've provided a [makefile](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've followed the [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): + +```shell +$ make route_guide.pb.cc +``` + +which actually runs: + +[actual command] + +Running this command generates the following files: +- `route_guide.pb.h` +- `route_guide.pb.cc` + +These contain ## Creating the server -First let's look at implementing our R +First let's look at how we create a `RouteGuide` server. There are two parts to making our `RouteGuide` service work: -- +- Implementing the service interface generated from our service definition: doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and return the service responses ## Creating the client From 453eca38bb747d09a6ee0feaa97d6d8e9feaa68d Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 23 Feb 2015 16:58:19 +0000 Subject: [PATCH 82/92] Generating code... --- cpp/cpptutorial.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index ade134c86b4..21026781638 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -104,10 +104,12 @@ which actually runs: [actual command] Running this command generates the following files: -- `route_guide.pb.h` -- `route_guide.pb.cc` +- `route_guide.pb.h`, the header which declares your generated classes +- `route_guide.pb.cc`, which contains the implementation of your classes -These contain +These contain: +- All the protocol buffer code to populate, serialize, and retrieve our request and response message types +- A class called `RouteGuide` that contains both a remote interface type (or *stub*) for clients to call and an abstract interface for servers to implement, both with the methods defined in the `RouteGuide` service. ## Creating the server From 10135581963735854ed4918f805ab0c10f7a95d3 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Mon, 23 Feb 2015 09:22:26 -0800 Subject: [PATCH 83/92] Update README.md --- cpp/README.md | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/cpp/README.md b/cpp/README.md index 84fa34e7055..c1c79b592b3 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -3,6 +3,100 @@ First you need to install gRPC on your system. Follow the instructions here: [https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). -After installing, you can proceed to the [gRPC C++ Hello World tutorial](helloworld/README.md). +# gRPC C++ Hello World Tutorial + +### Install gRPC +Make sure you have installed gRPC on your system. Follow the instructions here: +[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). + +### Get the tutorial source code + +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: + + +```sh +$ git clone https://github.com/google/grpc-common.git +``` + +Change your current directory to grpc-common/cpp/helloworld + +```sh +$ cd grpc-common/cpp/helloworld/ +``` + +### 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. As you saw in the +[overview](#protocolbuffers) above, gRPC does this using [protocol +buffers](https://developers.google.com/protocol-buffers/docs/overview). We +use the protocol buffers interface definition language (IDL) to define our +service methods, and define the parameters and return +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](https://github.com/grpc/grpc-common/blob/master/protos/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 single `HelloReply`. This is the simplest type of RPC you +can specify in gRPC - we'll look at some other types later in this document. + +``` +syntax = "proto3"; + +option java_package = "ex.grpc"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} + +``` + + +### 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. 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. + +To generate the client and server side interfaces: + +```sh +$ make helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + +```sh +$protoc -I ../../protos/ --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin helloworld.proto +``` + +### Writing a client + +This is an incomplete tutorial. For now the reader should refer to [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). + +### Writing a server + +This is an incomplete tutorial. For now the reader should refer to [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). A more detailed tutorial is coming soon. From 9f5d6f64511a59efa374ae7920f266ffca391a38 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Mon, 23 Feb 2015 09:25:14 -0800 Subject: [PATCH 84/92] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index c123ba0a5a5..df3108d839a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,11 @@ +# Please pick your language to proceed: +* [C++](https://github.com/grpc/grpc-common/tree/master/cpp) +* [Java](https://github.com/grpc/grpc-common/tree/master/java) +* [Python](https://github.com/grpc/grpc-common/tree/master/python) +* [Go](https://github.com/grpc/grpc-common/tree/master/go) +* [ruby](https://github.com/grpc/grpc-common/tree/master/ruby) +* [Node.js](https://github.com/grpc/grpc-common/tree/master/node) + # Getting started Welcome to the developer documentation for gRPC, a language-neutral, From 686042c703f367f4cc3351179bfd8de2b52e3727 Mon Sep 17 00:00:00 2001 From: Mugur Marculescu Date: Mon, 23 Feb 2015 09:30:21 -0800 Subject: [PATCH 85/92] Delete README_NEW.md Content links moved to main README.md --- README_NEW.md | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 README_NEW.md diff --git a/README_NEW.md b/README_NEW.md deleted file mode 100644 index 583136bc0dd..00000000000 --- a/README_NEW.md +++ /dev/null @@ -1,8 +0,0 @@ - -# Please pick your language to proceed: -### [C++](https://github.com/grpc/grpc-common/tree/master/cpp) -### [Java](https://github.com/grpc/grpc-common/tree/master/java) -### [Python](https://github.com/grpc/grpc-common/tree/master/python) -### [Go](https://github.com/grpc/grpc-common/tree/master/go) -### [ruby](https://github.com/grpc/grpc-common/tree/master/ruby) -### [Node.js](https://github.com/grpc/grpc-common/tree/master/node) From d1e11e74939dded780bdaf1693451002d4059c3f Mon Sep 17 00:00:00 2001 From: LisaFC Date: Mon, 23 Feb 2015 18:16:08 +0000 Subject: [PATCH 86/92] Update README.md --- cpp/README.md | 79 ++++++++++----------------------------------------- 1 file changed, 15 insertions(+), 64 deletions(-) diff --git a/cpp/README.md b/cpp/README.md index c1c79b592b3..fe9b71620e7 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -1,15 +1,13 @@ -#gRPC C++ Getting started +#gRPC in 3 minutes (C++) -First you need to install gRPC on your system. Follow the instructions here: -[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). - -# gRPC C++ Hello World Tutorial +## Installation -### Install gRPC -Make sure you have installed gRPC on your system. Follow the instructions here: +To install gRPC on your system, follow the instructions here: [https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). -### Get the tutorial source code +## Hello C++ gRPC! + +Here's how to build and run the C++ implementation of the [Hello World](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto) example used in [Getting started](https://github.com/grpc/grpc-common). 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 @@ -26,60 +24,9 @@ Change your current directory to grpc-common/cpp/helloworld $ cd grpc-common/cpp/helloworld/ ``` -### 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. As you saw in the -[overview](#protocolbuffers) above, gRPC does this using [protocol -buffers](https://developers.google.com/protocol-buffers/docs/overview). We -use the protocol buffers interface definition language (IDL) to define our -service methods, and define the parameters and return -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](https://github.com/grpc/grpc-common/blob/master/protos/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 single `HelloReply`. This is the simplest type of RPC you -can specify in gRPC - we'll look at some other types later in this document. - -``` -syntax = "proto3"; - -option java_package = "ex.grpc"; - -package helloworld; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} - -``` - - ### 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. 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. - To generate the client and server side interfaces: ```sh @@ -91,12 +38,16 @@ Which internally invokes the proto-compiler as: $protoc -I ../../protos/ --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin helloworld.proto ``` -### Writing a client +### Client and server implementations + +The client implementation is at [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). + +The server implementation is at [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). -This is an incomplete tutorial. For now the reader should refer to [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). +### Try it! -### Writing a server +###TODO: instructions to run server and client -This is an incomplete tutorial. For now the reader should refer to [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). +## Tutorial -A more detailed tutorial is coming soon. +You can find a more detailed tutorial in [gRPC Basics: C++](https://github.com/grpc/grpc-common/blob/master/cpp/cpptutorial.md) From 613a1f32c2760bb7836dd1b2aafbb2d960189a99 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Mon, 23 Feb 2015 18:18:46 +0000 Subject: [PATCH 87/92] Update README.md --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index df3108d839a..a1a3c4b9733 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,3 @@ -# Please pick your language to proceed: -* [C++](https://github.com/grpc/grpc-common/tree/master/cpp) -* [Java](https://github.com/grpc/grpc-common/tree/master/java) -* [Python](https://github.com/grpc/grpc-common/tree/master/python) -* [Go](https://github.com/grpc/grpc-common/tree/master/go) -* [ruby](https://github.com/grpc/grpc-common/tree/master/ruby) -* [Node.js](https://github.com/grpc/grpc-common/tree/master/node) # Getting started @@ -14,6 +7,15 @@ 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! +## Quick start +You can find quick start guides for each language, including installation instructions and examples here: +* [C++](https://github.com/grpc/grpc-common/tree/master/cpp) +* [Java](https://github.com/grpc/grpc-common/tree/master/java) +* [Python](https://github.com/grpc/grpc-common/tree/master/python) +* [Go](https://github.com/grpc/grpc-common/tree/master/go) +* [ruby](https://github.com/grpc/grpc-common/tree/master/ruby) +* [Node.js](https://github.com/grpc/grpc-common/tree/master/node) + ## What's in this repository? The `grpc-common` repository contains documentation, resources, and examples From 09275f0be4e8c282d2febe3a983fd5632d89cbcc Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 23 Feb 2015 11:08:42 -0800 Subject: [PATCH 88/92] Added route guide example --- node/package.json | 5 +- node/route_guide/route_guide.proto | 120 +++++ node/route_guide/route_guide_client.js | 231 ++++++++++ node/route_guide/route_guide_db.json | 601 +++++++++++++++++++++++++ node/route_guide/route_guide_server.js | 249 ++++++++++ 5 files changed, 1205 insertions(+), 1 deletion(-) create mode 100644 node/route_guide/route_guide.proto create mode 100644 node/route_guide/route_guide_client.js create mode 100644 node/route_guide/route_guide_db.json create mode 100644 node/route_guide/route_guide_server.js diff --git a/node/package.json b/node/package.json index 435654034fa..a669dec8f18 100644 --- a/node/package.json +++ b/node/package.json @@ -2,6 +2,9 @@ "name": "grpc-greeter", "version": "0.1.0", "dependencies": { - "grpc" : "~0.2.0" + "async": "^0.9.0", + "grpc": "~0.2.0", + "minimist": "^1.1.0", + "underscore": "^1.8.2" } } diff --git a/node/route_guide/route_guide.proto b/node/route_guide/route_guide.proto new file mode 100644 index 00000000000..442112823e5 --- /dev/null +++ b/node/route_guide/route_guide.proto @@ -0,0 +1,120 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "io.grpc.examples"; + +package examples; + +// Interface exported by the server. +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} + + // A server-to-client streaming RPC. + // + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} + + // A client-to-server streaming RPC. + // + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} + + // A Bidirectional streaming RPC. + // + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +} + +// Points are represented as latitude-longitude pairs in the E7 representation +// (degrees multiplied by 10**7 and rounded to the nearest integer). +// Latitudes should be in the range +/- 90 degrees and longitude should be in +// the range +/- 180 degrees (inclusive). +message Point { + optional int32 latitude = 1; + optional int32 longitude = 2; +} + +// A latitude-longitude rectangle, represented as two diagonally opposite +// points "lo" and "hi". +message Rectangle { + // One corner of the rectangle. + optional Point lo = 1; + + // The other corner of the rectangle. + optional Point hi = 2; +} + +// A feature names something at a given point. +// +// If a feature could not be named, the name is empty. +message Feature { + // The name of the feature. + optional string name = 1; + + // The point where the feature is detected. + optional Point location = 2; +} + +// A RouteNote is a message sent while at a given point. +message RouteNote { + // The location from which the message is sent. + optional Point location = 1; + + // The message to be sent. + optional string message = 2; +} + +// A RouteSummary is received in response to a RecordRoute rpc. +// +// It contains the number of individual points received, the number of +// detected features, and the total distance covered as the cumulative sum of +// the distance between each point. +message RouteSummary { + // The number of points received. + optional int32 point_count = 1; + + // The number of known features passed while traversing the route. + optional int32 feature_count = 2; + + // The distance covered in metres. + optional int32 distance = 3; + + // The duration of the traversal in seconds. + optional int32 elapsed_time = 4; +} diff --git a/node/route_guide/route_guide_client.js b/node/route_guide/route_guide_client.js new file mode 100644 index 00000000000..60c47a429d6 --- /dev/null +++ b/node/route_guide/route_guide_client.js @@ -0,0 +1,231 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +var async = require('async'); +var fs = require('fs'); +var parseArgs = require('minimist'); +var path = require('path'); +var _ = require('underscore'); +var grpc = require('grpc'); +var examples = grpc.load(__dirname + '/route_guide.proto').examples; +var client = new examples.RouteGuide('localhost:50051'); + +var COORD_FACTOR = 1e7; + +/** + * Run the getFeature demo. Calls getFeature with a point known to have a + * feature and a point known not to have a feature. + * @param {function} callback Called when this demo is complete + */ +function runGetFeature(callback) { + var next = _.after(2, callback); + function featureCallback(error, feature) { + if (error) { + callback(error); + } + if (feature.name === '') { + console.log('Found no feature at ' + + feature.location.latitude/COORD_FACTOR + ', ' + + feature.location.longitude/COORD_FACTOR); + } else { + console.log('Found feature called "' + feature.name + '" at ' + + feature.location.latitude/COORD_FACTOR + ', ' + + feature.location.longitude/COORD_FACTOR); + } + next(); + } + var point1 = { + latitude: 409146138, + longitude: -746188906 + }; + var point2 = { + latitude: 0, + longitude: 0 + }; + client.getFeature(point1, featureCallback); + client.getFeature(point2, featureCallback); +} + +/** + * Run the listFeatures demo. Calls listFeatures with a rectangle containing all + * of the features in the pre-generated database. Prints each response as it + * comes in. + * @param {function} callback Called when this demo is complete + */ +function runListFeatures(callback) { + var rectangle = { + lo: { + latitude: 400000000, + longitude: -750000000 + }, + hi: { + latitude: 420000000, + longitude: -730000000 + } + }; + console.log('Looking for features between 40, -75 and 42, -73'); + var call = client.listFeatures(rectangle); + call.on('data', function(feature) { + console.log('Found feature called "' + feature.name + '" at ' + + feature.location.latitude/COORD_FACTOR + ', ' + + feature.location.longitude/COORD_FACTOR); + }); + call.on('end', callback); +} + +/** + * Run the recordRoute demo. Sends several randomly chosen points from the + * pre-generated feature database with a variable delay in between. Prints the + * statistics when they are sent from the server. + * @param {function} callback Called when this demo is complete + */ +function runRecordRoute(callback) { + var argv = parseArgs(process.argv, { + string: 'db_path' + }); + fs.readFile(path.resolve(argv.db_path), function(err, data) { + if (err) callback(err); + var feature_list = JSON.parse(data); + + var num_points = 10; + var call = client.recordRoute(function(error, stats) { + if (error) { + callback(error); + } + console.log('Finished trip with', stats.point_count, 'points'); + console.log('Passed', stats.feature_count, 'features'); + console.log('Travelled', stats.distance, 'meters'); + console.log('It took', stats.elapsed_time, 'seconds'); + callback(); + }); + /** + * Constructs a function that asynchronously sends the given point and then + * delays sending its callback + * @param {number} lat The latitude to send + * @param {number} lng The longitude to send + * @return {function(function)} The function that sends the point + */ + function pointSender(lat, lng) { + /** + * Sends the point, then calls the callback after a delay + * @param {function} callback Called when complete + */ + return function(callback) { + console.log('Visiting point ' + lat/COORD_FACTOR + ', ' + + lng/COORD_FACTOR); + call.write({ + latitude: lat, + longitude: lng + }); + _.delay(callback, _.random(500, 1500)); + }; + } + var point_senders = []; + for (var i = 0; i < num_points; i++) { + var rand_point = feature_list[_.random(0, feature_list.length - 1)]; + point_senders[i] = pointSender(rand_point.location.latitude, + rand_point.location.longitude); + } + async.series(point_senders, function() { + call.end(); + }); + }); +} + +/** + * Run the routeChat demo. Send some chat messages, and print any chat messages + * that are sent from the server. + * @param {function} callback Called when the demo is complete + */ +function runRouteChat(callback) { + var call = client.routeChat(); + call.on('data', function(note) { + console.log('Got message "' + note.message + '" at ' + + note.location.latitude + ', ' + note.location.longitude); + }); + + call.on('end', callback); + + var notes = [{ + location: { + latitude: 0, + longitude: 0 + }, + message: 'First message' + }, { + location: { + latitude: 0, + longitude: 1 + }, + message: 'Second message' + }, { + location: { + latitude: 1, + longitude: 0 + }, + message: 'Third message' + }, { + location: { + latitude: 0, + longitude: 0 + }, + message: 'Fourth message' + }]; + for (var i = 0; i < notes.length; i++) { + var note = notes[i]; + console.log('Sending message "' + note.message + '" at ' + + note.location.latitude + ', ' + note.location.longitude); + call.write(note); + } + call.end(); +} + +/** + * Run all of the demos in order + */ +function main() { + async.series([ + runGetFeature, + runListFeatures, + runRecordRoute, + runRouteChat + ]); +} + +if (require.main === module) { + main(); +} + +exports.runGetFeature = runGetFeature; + +exports.runListFeatures = runListFeatures; + +exports.runRecordRoute = runRecordRoute; + +exports.runRouteChat = runRouteChat; diff --git a/node/route_guide/route_guide_db.json b/node/route_guide/route_guide_db.json new file mode 100644 index 00000000000..9d6a980ab7d --- /dev/null +++ b/node/route_guide/route_guide_db.json @@ -0,0 +1,601 @@ +[{ + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" +}, { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" +}, { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" +}, { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" +}, { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" +}, { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" +}, { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" +}, { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" +}, { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" +}, { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" +}, { + "location": { + "latitude": 415736605, + "longitude": -742847522 + }, + "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" +}, { + "location": { + "latitude": 413843930, + "longitude": -740501726 + }, + "name": "162 Merrill Road, Highland Mills, NY 10930, USA" +}, { + "location": { + "latitude": 410873075, + "longitude": -744459023 + }, + "name": "Clinton Road, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 412346009, + "longitude": -744026814 + }, + "name": "16 Old Brook Lane, Warwick, NY 10990, USA" +}, { + "location": { + "latitude": 402948455, + "longitude": -747903913 + }, + "name": "3 Drake Lane, Pennington, NJ 08534, USA" +}, { + "location": { + "latitude": 406337092, + "longitude": -740122226 + }, + "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" +}, { + "location": { + "latitude": 406421967, + "longitude": -747727624 + }, + "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" +}, { + "location": { + "latitude": 416318082, + "longitude": -749677716 + }, + "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" +}, { + "location": { + "latitude": 415301720, + "longitude": -748416257 + }, + "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" +}, { + "location": { + "latitude": 402647019, + "longitude": -747071791 + }, + "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" +}, { + "location": { + "latitude": 412567807, + "longitude": -741058078 + }, + "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" +}, { + "location": { + "latitude": 416855156, + "longitude": -744420597 + }, + "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" +}, { + "location": { + "latitude": 404663628, + "longitude": -744820157 + }, + "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" +}, { + "location": { + "latitude": 407113723, + "longitude": -749746483 + }, + "name": "" +}, { + "location": { + "latitude": 402133926, + "longitude": -743613249 + }, + "name": "" +}, { + "location": { + "latitude": 400273442, + "longitude": -741220915 + }, + "name": "" +}, { + "location": { + "latitude": 411236786, + "longitude": -744070769 + }, + "name": "" +}, { + "location": { + "latitude": 411633782, + "longitude": -746784970 + }, + "name": "211-225 Plains Road, Augusta, NJ 07822, USA" +}, { + "location": { + "latitude": 415830701, + "longitude": -742952812 + }, + "name": "" +}, { + "location": { + "latitude": 413447164, + "longitude": -748712898 + }, + "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" +}, { + "location": { + "latitude": 405047245, + "longitude": -749800722 + }, + "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" +}, { + "location": { + "latitude": 418858923, + "longitude": -746156790 + }, + "name": "" +}, { + "location": { + "latitude": 417951888, + "longitude": -748484944 + }, + "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" +}, { + "location": { + "latitude": 407033786, + "longitude": -743977337 + }, + "name": "26 East 3rd Street, New Providence, NJ 07974, USA" +}, { + "location": { + "latitude": 417548014, + "longitude": -740075041 + }, + "name": "" +}, { + "location": { + "latitude": 410395868, + "longitude": -744972325 + }, + "name": "" +}, { + "location": { + "latitude": 404615353, + "longitude": -745129803 + }, + "name": "" +}, { + "location": { + "latitude": 406589790, + "longitude": -743560121 + }, + "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" +}, { + "location": { + "latitude": 414653148, + "longitude": -740477477 + }, + "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" +}, { + "location": { + "latitude": 405957808, + "longitude": -743255336 + }, + "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" +}, { + "location": { + "latitude": 411733589, + "longitude": -741648093 + }, + "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" +}, { + "location": { + "latitude": 412676291, + "longitude": -742606606 + }, + "name": "1270 Lakes Road, Monroe, NY 10950, USA" +}, { + "location": { + "latitude": 409224445, + "longitude": -748286738 + }, + "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" +}, { + "location": { + "latitude": 406523420, + "longitude": -742135517 + }, + "name": "652 Garden Street, Elizabeth, NJ 07202, USA" +}, { + "location": { + "latitude": 401827388, + "longitude": -740294537 + }, + "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" +}, { + "location": { + "latitude": 410564152, + "longitude": -743685054 + }, + "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 408472324, + "longitude": -740726046 + }, + "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" +}, { + "location": { + "latitude": 412452168, + "longitude": -740214052 + }, + "name": "5 White Oak Lane, Stony Point, NY 10980, USA" +}, { + "location": { + "latitude": 409146138, + "longitude": -746188906 + }, + "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" +}, { + "location": { + "latitude": 404701380, + "longitude": -744781745 + }, + "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 409642566, + "longitude": -746017679 + }, + "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" +}, { + "location": { + "latitude": 408031728, + "longitude": -748645385 + }, + "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" +}, { + "location": { + "latitude": 413700272, + "longitude": -742135189 + }, + "name": "367 Prospect Road, Chester, NY 10918, USA" +}, { + "location": { + "latitude": 404310607, + "longitude": -740282632 + }, + "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" +}, { + "location": { + "latitude": 409319800, + "longitude": -746201391 + }, + "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" +}, { + "location": { + "latitude": 406685311, + "longitude": -742108603 + }, + "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" +}, { + "location": { + "latitude": 419018117, + "longitude": -749142781 + }, + "name": "43 Dreher Road, Roscoe, NY 12776, USA" +}, { + "location": { + "latitude": 412856162, + "longitude": -745148837 + }, + "name": "Swan Street, Pine Island, NY 10969, USA" +}, { + "location": { + "latitude": 416560744, + "longitude": -746721964 + }, + "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" +}, { + "location": { + "latitude": 405314270, + "longitude": -749836354 + }, + "name": "" +}, { + "location": { + "latitude": 414219548, + "longitude": -743327440 + }, + "name": "" +}, { + "location": { + "latitude": 415534177, + "longitude": -742900616 + }, + "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" +}, { + "location": { + "latitude": 406898530, + "longitude": -749127080 + }, + "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" +}, { + "location": { + "latitude": 407586880, + "longitude": -741670168 + }, + "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" +}, { + "location": { + "latitude": 400106455, + "longitude": -742870190 + }, + "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" +}, { + "location": { + "latitude": 400066188, + "longitude": -746793294 + }, + "name": "" +}, { + "location": { + "latitude": 418803880, + "longitude": -744102673 + }, + "name": "40 Mountain Road, Napanoch, NY 12458, USA" +}, { + "location": { + "latitude": 414204288, + "longitude": -747895140 + }, + "name": "" +}, { + "location": { + "latitude": 414777405, + "longitude": -740615601 + }, + "name": "" +}, { + "location": { + "latitude": 415464475, + "longitude": -747175374 + }, + "name": "48 North Road, Forestburgh, NY 12777, USA" +}, { + "location": { + "latitude": 404062378, + "longitude": -746376177 + }, + "name": "" +}, { + "location": { + "latitude": 405688272, + "longitude": -749285130 + }, + "name": "" +}, { + "location": { + "latitude": 400342070, + "longitude": -748788996 + }, + "name": "" +}, { + "location": { + "latitude": 401809022, + "longitude": -744157964 + }, + "name": "" +}, { + "location": { + "latitude": 404226644, + "longitude": -740517141 + }, + "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" +}, { + "location": { + "latitude": 410322033, + "longitude": -747871659 + }, + "name": "" +}, { + "location": { + "latitude": 407100674, + "longitude": -747742727 + }, + "name": "" +}, { + "location": { + "latitude": 418811433, + "longitude": -741718005 + }, + "name": "213 Bush Road, Stone Ridge, NY 12484, USA" +}, { + "location": { + "latitude": 415034302, + "longitude": -743850945 + }, + "name": "" +}, { + "location": { + "latitude": 411349992, + "longitude": -743694161 + }, + "name": "" +}, { + "location": { + "latitude": 404839914, + "longitude": -744759616 + }, + "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 414638017, + "longitude": -745957854 + }, + "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" +}, { + "location": { + "latitude": 412127800, + "longitude": -740173578 + }, + "name": "" +}, { + "location": { + "latitude": 401263460, + "longitude": -747964303 + }, + "name": "" +}, { + "location": { + "latitude": 412843391, + "longitude": -749086026 + }, + "name": "" +}, { + "location": { + "latitude": 418512773, + "longitude": -743067823 + }, + "name": "" +}, { + "location": { + "latitude": 404318328, + "longitude": -740835638 + }, + "name": "42-102 Main Street, Belford, NJ 07718, USA" +}, { + "location": { + "latitude": 419020746, + "longitude": -741172328 + }, + "name": "" +}, { + "location": { + "latitude": 404080723, + "longitude": -746119569 + }, + "name": "" +}, { + "location": { + "latitude": 401012643, + "longitude": -744035134 + }, + "name": "" +}, { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" +}, { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" +}, { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" +}, { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" +}, { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" +}, { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" +}, { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" +}, { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" +}, { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" +}, { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" +}] diff --git a/node/route_guide/route_guide_server.js b/node/route_guide/route_guide_server.js new file mode 100644 index 00000000000..5dd84126543 --- /dev/null +++ b/node/route_guide/route_guide_server.js @@ -0,0 +1,249 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +var fs = require('fs'); +var parseArgs = require('minimist'); +var path = require('path'); +var _ = require('underscore'); +var grpc = require('grpc'); +var examples = grpc.load(__dirname + '/route_guide.proto').examples; + +var Server = grpc.buildServer([examples.RouteGuide.service]); + +var COORD_FACTOR = 1e7; + +/** + * For simplicity, a point is a record type that looks like + * {latitude: number, longitude: number}, and a feature is a record type that + * looks like {name: string, location: point}. feature objects with name==='' + * are points with no feature. + */ + +/** + * List of feature objects at points that have been requested so far. + */ +var feature_list = []; + +/** + * Get a feature object at the given point, or creates one if it does not exist. + * @param {point} point The point to check + * @return {feature} The feature object at the point. Note that an empty name + * indicates no feature + */ +function checkFeature(point) { + var feature; + // Check if there is already a feature object for the given point + for (var i = 0; i < feature_list.length; i++) { + feature = feature_list[i]; + if (feature.location.latitude === point.latitude && + feature.location.longitude === point.longitude) { + return feature; + } + } + var name = ''; + feature = { + name: name, + location: point + }; + return feature; +} + +/** + * getFeature request handler. Gets a request with a point, and responds with a + * feature object indicating whether there is a feature at that point. + * @param {EventEmitter} call Call object for the handler to process + * @param {function(Error, feature)} callback Response callback + */ +function getFeature(call, callback) { + callback(null, checkFeature(call.request)); +} + +/** + * listFeatures request handler. Gets a request with two points, and responds + * with a stream of all features in the bounding box defined by those points. + * @param {Writable} call Writable stream for responses with an additional + * request property for the request value. + */ +function listFeatures(call) { + var lo = call.request.lo; + var hi = call.request.hi; + var left = _.min([lo.longitude, hi.longitude]); + var right = _.max([lo.longitude, hi.longitude]); + var top = _.max([lo.latitude, hi.latitude]); + var bottom = _.min([lo.latitude, hi.latitude]); + // For each feature, check if it is in the given bounding box + _.each(feature_list, function(feature) { + if (feature.name === '') { + return; + } + if (feature.location.longitude >= left && + feature.location.longitude <= right && + feature.location.latitude >= bottom && + feature.location.latitude <= top) { + call.write(feature); + } + }); + call.end(); +} + +/** + * Calculate the distance between two points using the "haversine" formula. + * This code was taken from http://www.movable-type.co.uk/scripts/latlong.html. + * @param start The starting point + * @param end The end point + * @return The distance between the points in meters + */ +function getDistance(start, end) { + function toRadians(num) { + return num * Math.PI / 180; + } + var lat1 = start.latitude / COORD_FACTOR; + var lat2 = end.latitude / COORD_FACTOR; + var lon1 = start.longitude / COORD_FACTOR; + var lon2 = end.longitude / COORD_FACTOR; + var R = 6371000; // metres + var φ1 = toRadians(lat1); + var φ2 = toRadians(lat2); + var Δφ = toRadians(lat2-lat1); + var Δλ = toRadians(lon2-lon1); + + var a = Math.sin(Δφ/2) * Math.sin(Δφ/2) + + Math.cos(φ1) * Math.cos(φ2) * + Math.sin(Δλ/2) * Math.sin(Δλ/2); + var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); + + return R * c; +} + +/** + * recordRoute handler. Gets a stream of points, and responds with statistics + * about the "trip": number of points, number of known features visited, total + * distance traveled, and total time spent. + * @param {Readable} call The request point stream. + * @param {function(Error, routeSummary)} callback The callback to pass the + * response to + */ +function recordRoute(call, callback) { + var point_count = 0; + var feature_count = 0; + var distance = 0; + var previous = null; + // Start a timer + var start_time = process.hrtime(); + call.on('data', function(point) { + point_count += 1; + if (checkFeature(point).name !== '') { + feature_count += 1; + } + /* For each point after the first, add the incremental distance from the + * previous point to the total distance value */ + if (previous != null) { + distance += getDistance(previous, point); + } + previous = point; + }); + call.on('end', function() { + callback(null, { + point_count: point_count, + feature_count: feature_count, + // Cast the distance to an integer + distance: distance|0, + // End the timer + elapsed_time: process.hrtime(start_time)[0] + }); + }); +} + +var route_notes = {}; + +/** + * Turn the point into a dictionary key. + * @param {point} point The point to use + * @return {string} The key for an object + */ +function pointKey(point) { + return point.latitude + ' ' + point.longitude; +} + +/** + * routeChat handler. Receives a stream of message/location pairs, and responds + * with a stream of all previous messages at each of those locations. + * @param {Duplex} call The stream for incoming and outgoing messages + */ +function routeChat(call) { + call.on('data', function(note) { + var key = pointKey(note.location); + /* For each note sent, respond with all previous notes that correspond to + * the same point */ + if (route_notes.hasOwnProperty(key)) { + _.each(route_notes[key], function(note) { + call.write(note); + }); + } else { + route_notes[key] = []; + } + // Then add the new note to the list + route_notes[key].push(JSON.parse(JSON.stringify(note))); + }); + call.on('end', function() { + call.end(); + }); +} + +/** + * Get a new server with the handler functions in this file bound to the methods + * it serves. + * @return {Server} The new server object + */ +function getServer() { + return new Server({ + 'examples.RouteGuide' : { + getFeature: getFeature, + listFeatures: listFeatures, + recordRoute: recordRoute, + routeChat: routeChat + } + }); +} + +if (require.main === module) { + // If this is run as a script, start a server on an unused port + var routeServer = getServer(); + routeServer.bind('0.0.0.0:50051'); + var argv = parseArgs(process.argv, { + string: 'db_path' + }); + fs.readFile(path.resolve(argv.db_path), function(err, data) { + if (err) throw err; + feature_list = JSON.parse(data); + routeServer.listen(); + }); +} + +exports.getServer = getServer; From c23768547439d67dc41390635bc824b187738f26 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Tue, 24 Feb 2015 10:18:50 +0000 Subject: [PATCH 89/92] Update README.md Added link to golang/protobuf repo --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a1a3c4b9733..92377b04b25 100644 --- a/README.md +++ b/README.md @@ -66,10 +66,9 @@ While protocol buffers have been available for open source users for some time, our examples use a new flavour of protocol buffers called proto3, which has a slightly simplified syntax, some useful new features, and supports lots more languages. This is currently available as an alpha release in -Java, C++ from [the protocol buffers Github +Java, C++, Java_nano (Android Java), Python, and Ruby from [the protocol buffers Github repo](https://github.com/google/protobuf/releases), as well as a Go language -generator [wherever that is](), with more languages in development. Full -documentation for proto3 is currently in development but you can see +generator from [the golang/protobuf Github repo](https://github.com/golang/protobuf), with more languages in development. Full documentation for proto3 is currently in development, but you can see the major differences from the current default version in the [release notes](https://github.com/google/protobuf/releases). In general, we recommend that you use proto3 with gRPC as it lets you use the From 2eadf58ab63a4ddfa7a4a82a32feda448cfb2e03 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Tue, 24 Feb 2015 10:20:33 +0000 Subject: [PATCH 90/92] Update README.md --- README.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 92377b04b25..acea9289a7a 100644 --- a/README.md +++ b/README.md @@ -71,15 +71,8 @@ repo](https://github.com/google/protobuf/releases), as well as a Go language generator from [the golang/protobuf Github repo](https://github.com/golang/protobuf), with more languages in development. Full documentation for proto3 is currently in development, but you can see the major differences from the current default version in the [release notes](https://github.com/google/protobuf/releases). -In general, we recommend that you use proto3 with gRPC as it lets you use the -full range of gRPC-supported languages, as well as avoiding compatibility -issues with proto2 clients talking to proto3 servers and vice versa. You -can find out more about these potential issues in [where should we put this -info? It's important but not really part of an overview]. If you need to -continue using proto2 for Java, C++, or Python but want -to try gRPC, you can see an example using a proto2 gRPC client and server -[wherever we put it]. - +In general, while you *can* use proto2 (the current default protocol buffers version), we recommend that you use proto3 with gRPC as it lets you use the full range of gRPC-supported languages, as well as avoiding compatibility +issues with proto2 clients talking to proto3 servers and vice versa. ## Hello gRPC! From f3e73a487129c1a971aa7e298a9433c6e60befeb Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 04:09:51 -0800 Subject: [PATCH 91/92] Updates the Node.js README to match the common template --- node/README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/node/README.md b/node/README.md index 57dc83ee3f3..f9df3b0a81d 100644 --- a/node/README.md +++ b/node/README.md @@ -1,17 +1,21 @@ -# gRPC Node.js Helloworld +gRPC in 3 minutes (Node.js) +=========================== -## INSTALLATION REQUIREMENTS +PREREQUISITES +------------- This requires Node 10.x or greater. -## INSTALL +INSTALL +------- - Clone this repository - Follow the instructions in [INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL) to install the gRPC C core. - Run `npm install` to install dependencies - If `grpc` is not found, clone the [gRPC](https://github.com/grpc/grpc) repository and run `npm install path/to/grpc/src/node`. -## USAGE +Try it! +------- - Run the server @@ -27,7 +31,8 @@ This requires Node 10.x or greater. $ nodejs ./greeter_client.js ``` -## NOTE +Note +---- This directory has a copy of `helloworld.proto` because it currently depends on some Protocol Buffer 2.0 syntax that is deprecated in Protocol Buffer 3.0. From 18e24c8cca29d3864f9cf6bc75d6041cec915a85 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Tue, 24 Feb 2015 09:19:31 -0800 Subject: [PATCH 92/92] Create AUTH.md An overview auth document using c++ code exampoles. The code will be translated to other languages in subsequet pull requests. --- AUTH.md | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 AUTH.md diff --git a/AUTH.md b/AUTH.md new file mode 100644 index 00000000000..9850b8b24ef --- /dev/null +++ b/AUTH.md @@ -0,0 +1,88 @@ +#gRPC Authentication support + +gRPC is designed to plug-in a number of authentication mechanisms. We provide an overview +of the various auth mechanisms supported, discuss the API and demonstrate usage through +code examples, and conclude with a discussion of extensibility. + +###SSL/TLS +gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the server, +and encrypt all the data exchanged between the client and the server. Optional +mechanisms are available for clients to provide certificates to accomplish mutual +authentication. + +###OAuth 2.0 +gRPC provides a generic mechanism (described below) to attach metadata to requests +and responses. This mechanism can be used to attach OAuth 2.0 Access Tokens to +RPCs being made at a client. Additional support for acquiring Access Tokens while +accessing Google APIs through gRPC is provided for certain auth flows, demonstrated +through code examples below. + +###API +To reduce complexity and minimize API clutter, gRPC works with a unified concept of +a Credentials object. Users construct gRPC credentials using corresponding bootstrap +credentials (e.g., SSL client certs or Service Account Keys), and use the +credentials while creating a gRPC channel to any server. Depending on the type of +credential supplied, the channel uses the credentials during the initial SSL/TLS +handshake with the server, or uses the credential to generate and attach Access +Tokens to each request being made on the channel. + +###Code Examples + +####SSL/TLS for server authentication and encryption +This is the simplest authentication scenario, where a client just wants to +authenticate the server and encrypt all data. + +``` +SslCredentialsOptions ssl_opts; // Options to override SSL params, empty by default +// Create the credentials object by providing service account key in constructor +std::unique_ptr creds = CredentialsFactory::SslCredentials(ssl_opts); +// Create a channel using the credentials created in the previous step +std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); +// Create a stub on the channel +std::unique_ptr stub(Greeter::NewStub(channel)); +// Make actual RPC calls on the stub. +grpc::Status s = stub->sayHello(&context, *request, response); +``` + +For advanced use cases such as modifying the root CA or using client certs, +the corresponding options can be set in the SslCredentialsOptions parameter +passed to the factory method. + + +###Authenticating with Google + +gRPC applications can use a simple API to create a credential that works in various deployment scenarios. + +``` +std::unique_ptr creds = CredentialsFactory::DefaultGoogleCredentials(); +// Create a channel, stub and make RPC calls (same as in the previous example) +std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); +std::unique_ptr stub(Greeter::NewStub(channel)); +grpc::Status s = stub->sayHello(&context, *request, response); +``` + +This credential works for applications using Service Accounts as well as for +applications running in Google Compute Engine (GCE). In the former case, the +service account’s private keys are expected in file located at [TODO: well +known file fath for service account keys] or in the file named in the environment +variable [TODO: add the env var name here]. The keys are used at run-time to +generate bearer tokens that are attached to each outgoing RPC on the +corresponding channel. + +For applications running in GCE, a default service account and corresponding +OAuth scopes can be configured during VM setup. At run-time, this credential +handles communication with the authentication systems to obtain OAuth2 access +tokens and attaches them to each outgoing RPC on the corresponding channel. +Extending gRPC to support other authentication mechanisms +The gRPC protocol is designed with a general mechanism for sending metadata +associated with RPC. Clients can send metadata at the beginning of an RPC and +servers can send back metadata at the beginning and end of the RPC. This +provides a natural mechanism to support OAuth2 and other authentication +mechanisms that need attach bearer tokens to individual request. + +In the simplest case, there is a single line of code required on the client +to add a specific token as metadata to an RPC and a corresponding access on +the server to retrieve this piece of metadata. The generation of the token +on the client side and its verification at the server can be done separately. + +A deeper integration can be achieved by plugging in a gRPC credentials implementation for any custom authentication mechanism that needs to attach per-request tokens. gRPC internals also allow switching out SSL/TLS with other encryption mechanisms.