aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Lisa Carey <lcarey@google.com>2015-02-20 11:08:03 +0000
committerGravatar Lisa Carey <lcarey@google.com>2015-02-20 11:08:03 +0000
commit237ac97f6b7fec3ac3758b40b4dfd9e7bfaa3d8b (patch)
treea62b62b1feb1740222b3a00f5cfc32409f960f27
parent48dbd9bd6062193c955ee02523d40ed41791287c (diff)
parentb2dee22dd483d9e3da41dab7ce1608e9e2066b49 (diff)
Merge branch 'master' of https://github.com/grpc/grpc-common into testy-master
-rw-r--r--PROTOCOL-HTTP2.md190
-rw-r--r--README.md8
-rw-r--r--cpp/helloworld/Makefile47
-rw-r--r--cpp/helloworld/greeter_client.cc91
-rw-r--r--cpp/helloworld/greeter_server.cc84
-rw-r--r--cpp/helloworld/helloworld.pb.cc640
-rw-r--r--cpp/helloworld/helloworld.pb.h359
-rwxr-xr-xjava/run_greeter_client.sh (renamed from java/run_greetings_client.sh)4
-rwxr-xr-xjava/run_greeter_server.sh (renamed from java/run_greetings_server.sh)4
-rw-r--r--java/src/main/java/ex/grpc/GreeterClient.java (renamed from java/src/main/java/ex/grpc/GreetingsClient.java)14
-rw-r--r--java/src/main/java/ex/grpc/GreeterGrpc.java (renamed from java/src/main/java/ex/grpc/GreetingsGrpc.java)126
-rw-r--r--java/src/main/java/ex/grpc/GreeterImpl.java (renamed from java/src/main/java/ex/grpc/GreetingsImpl.java)4
-rw-r--r--java/src/main/java/ex/grpc/GreeterServer.java (renamed from java/src/main/java/ex/grpc/GreetingsServer.java)8
-rw-r--r--java/src/main/java/ex/grpc/Helloworld.java12
-rw-r--r--java/src/main/proto/helloworld.proto22
-rw-r--r--node/.gitignore3
-rw-r--r--node/README.md33
-rw-r--r--node/greeter_client.js52
-rw-r--r--node/greeter_server.js63
-rw-r--r--node/helloworld.proto (renamed from protos/stock.proto)47
-rw-r--r--node/package.json7
-rw-r--r--protos/README.md10
-rw-r--r--protos/helloworld.proto17
-rw-r--r--protos/math.proto79
-rw-r--r--protos/route_guide.proto120
-rw-r--r--ruby/.gitignore15
-rw-r--r--ruby/Gemfile15
-rw-r--r--ruby/README.md35
-rw-r--r--ruby/greeter.gemspec23
-rwxr-xr-xruby/greeter_client.rb50
-rwxr-xr-xruby/greeter_server.rb60
-rw-r--r--ruby/lib/helloworld.rb18
-rw-r--r--ruby/lib/helloworld_services.rb24
33 files changed, 2044 insertions, 240 deletions
diff --git a/PROTOCOL-HTTP2.md b/PROTOCOL-HTTP2.md
new file mode 100644
index 0000000000..810c6b7e52
--- /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 <a href="http://tools.ietf.org/html/rfc5234">ABNF syntax</a>.
+
+### 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-code-as-ASCII-string>
+* **Status-Message** → “grpc-message” <descriptive text for status as ASCII string>
+
+**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)
+<Delimited Message>
+```
+**Response**
+```
+HEADERS (flags = END_HEADERS)
+:status = 200
+grpc-encoding = gzip
+
+DATA
+<Delimited Message>
+
+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"
+
+
diff --git a/README.md b/README.md
index 43c65b42a1..3a2fb8d7d1 100644
--- a/README.md
+++ b/README.md
@@ -294,6 +294,7 @@ actually implements our GreetingService's required behaviour.
As you can see, the class `GreeterImpl` implements the interface
`GreeterGrpc.Greeter` that we [generated](#generating) from our proto
+[IDL](java/src/main/proto/helloworld.proto) by implementing the method `hello`:
```java
public void hello(Helloworld.HelloRequest req,
@@ -337,10 +338,8 @@ implementation available from the network.
```
-
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
+implementation that we created to a port. Then we start the server running: the server is now ready to receive
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.
@@ -443,8 +442,9 @@ $ ./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 `Greetings` service definition....
+from our `Greeter` service definition....
###TODO: Section on Go client for same server
diff --git a/cpp/helloworld/Makefile b/cpp/helloworld/Makefile
new file mode 100644
index 0000000000..b9579e0c96
--- /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.
+#
+
+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.o greeter_client.o
+ $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@
+
+greeter_server: helloworld.pb.o greeter_server.o
+ $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@
+
+clean:
+ rm -f *.o greeter_client greeter_server
+
diff --git a/cpp/helloworld/greeter_client.cc b/cpp/helloworld/greeter_client.cc
new file mode 100644
index 0000000000..4a51f5eb38
--- /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 <iostream>
+#include <memory>
+#include <string>
+
+#include <grpc/grpc.h>
+#include <grpc++/channel_arguments.h>
+#include <grpc++/channel_interface.h>
+#include <grpc++/client_context.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/status.h>
+#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<ChannelInterface> 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<Greeter::Stub> 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 0000000000..3a2ab60e89
--- /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 <iostream>
+#include <memory>
+#include <string>
+#include <thread>
+
+#include <grpc/grpc.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc++/status.h>
+#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> 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 0000000000..a5b82c5ed5
--- /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 <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+#include <grpc++/async_unary_call.h>
+#include <grpc++/channel_interface.h>
+#include <grpc++/impl/client_unary_call.h>
+#include <grpc++/impl/rpc_method.h>
+#include <grpc++/impl/rpc_service_method.h>
+#include <grpc++/impl/service_type.h>
+#include <grpc++/stream.h>
+// @@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<const HelloRequest*>(
+ &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<const HelloReply*>(
+ &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 0000000000..f49adae84a
--- /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 <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#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 <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/unknown_field_set.h>
+#include <grpc++/impl/internal_stub.h>
+#include <grpc++/impl/service_type.h>
+#include <grpc++/status.h>
+
+namespace grpc {
+class CompletionQueue;
+class ChannelInterface;
+class RpcService;
+class ServerContext;
+template <class OutMessage> class ClientAsyncResponseReader;
+template <class OutMessage> 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<const char*>(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<const char*>(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
diff --git a/java/run_greetings_client.sh b/java/run_greeter_client.sh
index 8155589adf..e86ab4ae89 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
index 248229e129..836abc7f48 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
index 4ae2e7076b..9a4615132d 100644
--- a/java/src/main/java/ex/grpc/GreetingsClient.java
+++ b/java/src/main/java/ex/grpc/GreeterClient.java
@@ -9,17 +9,17 @@ 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 GreetingsGrpc.GreetingsBlockingStub blockingStub;
+ 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();
- 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);
@@ -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/GreetingsGrpc.java b/java/src/main/java/ex/grpc/GreeterGrpc.java
index 97c2f00a1e..080c3dfc43 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<ex.grpc.Helloworld.HelloRequest,
- ex.grpc.Helloworld.HelloReply> 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<GreetingsServiceDescriptor> {
+ public static class GreeterServiceDescriptor extends
+ com.google.net.stubby.stub.AbstractServiceDescriptor<GreeterServiceDescriptor> {
public final com.google.net.stubby.MethodDescriptor<ex.grpc.Helloworld.HelloRequest,
- ex.grpc.Helloworld.HelloReply> 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<java.lang.String, com.google.net.stubby.MethodDescriptor<?, ?>> methodMap) {
- hello = (com.google.net.stubby.MethodDescriptor<ex.grpc.Helloworld.HelloRequest,
+ sayHello = (com.google.net.stubby.MethodDescriptor<ex.grpc.Helloworld.HelloRequest,
ex.grpc.Helloworld.HelloReply>) methodMap.get(
- CONFIG.hello.getName());
+ CONFIG.sayHello.getName());
}
@java.lang.Override
- protected GreetingsServiceDescriptor build(
+ protected GreeterServiceDescriptor build(
java.util.Map<java.lang.String, com.google.net.stubby.MethodDescriptor<?, ?>> methodMap) {
- return new GreetingsServiceDescriptor(methodMap);
+ return new GreeterServiceDescriptor(methodMap);
}
@java.lang.Override
public com.google.common.collect.ImmutableList<com.google.net.stubby.MethodDescriptor<?, ?>> methods() {
return com.google.common.collect.ImmutableList.<com.google.net.stubby.MethodDescriptor<?, ?>>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<ex.grpc.Helloworld.HelloReply> 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<ex.grpc.Helloworld.HelloReply> hello(
+ public com.google.common.util.concurrent.ListenableFuture<ex.grpc.Helloworld.HelloReply> sayHello(
ex.grpc.Helloworld.HelloRequest request);
}
- public static class GreetingsStub extends
- com.google.net.stubby.stub.AbstractStub<GreetingsStub, GreetingsServiceDescriptor>
- implements Greetings {
- private GreetingsStub(com.google.net.stubby.Channel channel,
- GreetingsServiceDescriptor config) {
+ public static class GreeterStub extends
+ com.google.net.stubby.stub.AbstractStub<GreeterStub, GreeterServiceDescriptor>
+ 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<ex.grpc.Helloworld.HelloReply> 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<GreetingsBlockingStub, GreetingsServiceDescriptor>
- implements GreetingsBlockingClient {
- private GreetingsBlockingStub(com.google.net.stubby.Channel channel,
- GreetingsServiceDescriptor config) {
+ public static class GreeterBlockingStub extends
+ com.google.net.stubby.stub.AbstractStub<GreeterBlockingStub, GreeterServiceDescriptor>
+ 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<GreetingsFutureStub, GreetingsServiceDescriptor>
- implements GreetingsFutureClient {
- private GreetingsFutureStub(com.google.net.stubby.Channel channel,
- GreetingsServiceDescriptor config) {
+ public static class GreeterFutureStub extends
+ com.google.net.stubby.stub.AbstractStub<GreeterFutureStub, GreeterServiceDescriptor>
+ 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<ex.grpc.Helloworld.HelloReply> hello(
+ public com.google.common.util.concurrent.ListenableFuture<ex.grpc.Helloworld.HelloReply> 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<ex.grpc.Helloworld.HelloReply> 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
index 005489acaa..825ba8631e 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<Helloworld.HelloReply> responseObserver) {
Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage(
"Hello " + req.getName()).build();
diff --git a/java/src/main/java/ex/grpc/GreetingsServer.java b/java/src/main/java/ex/grpc/GreeterServer.java
index 834ae985a4..bb05680b0a 100644
--- a/java/src/main/java/ex/grpc/GreetingsServer.java
+++ b/java/src/main/java/ex/grpc/GreeterServer.java
@@ -7,16 +7,16 @@ 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;
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);
@@ -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
diff --git a/java/src/main/java/ex/grpc/Helloworld.java b/java/src/main/java/ex/grpc/Helloworld.java
index f72040fa2b..b25a63fca3 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() {
diff --git a/java/src/main/proto/helloworld.proto b/java/src/main/proto/helloworld.proto
deleted file mode 100644
index da5c3a1d85..0000000000
--- 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/node/.gitignore b/node/.gitignore
new file mode 100644
index 0000000000..3d06f5db7b
--- /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 0000000000..57dc83ee3f
--- /dev/null
+++ b/node/README.md
@@ -0,0 +1,33 @@
+# 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 0000000000..ab7050ab21
--- /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 0000000000..6d4183c0ce
--- /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/protos/stock.proto b/node/helloworld.proto
index 49efbf2730..e1f5700725 100644
--- a/protos/stock.proto
+++ b/node/helloworld.proto
@@ -29,43 +29,22 @@
syntax = "proto3";
-package examples;
+option java_package = "ex.grpc";
-// Protocol type definitions
-message StockRequest {
- optional string symbol = 1;
- optional int32 num_trades_to_watch = 2;
-}
+package helloworld;
-message StockReply {
- optional float price = 1;
- optional string symbol = 2;
+// The greeting service definition.
+service Greeter {
+ // Sends a greeting
+ rpc sayHello (HelloRequest) returns (HelloReply) {}
}
-// 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) {
- }
+// The request message containing the user's name.
+message HelloRequest {
+ optional string name = 1;
+}
- // Bidirectional streaming RPC.
- //
- // Gets the most recent traded price of series of trades.
- rpc GetLastTradePriceMultiple(stream StockRequest) returns
- (stream StockReply) {
- }
+// 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 0000000000..435654034f
--- /dev/null
+++ b/node/package.json
@@ -0,0 +1,7 @@
+{
+ "name": "grpc-greeter",
+ "version": "0.1.0",
+ "dependencies": {
+ "grpc" : "~0.2.0"
+ }
+}
diff --git a/protos/README.md b/protos/README.md
index 374d4350ac..48df7c8943 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/helloworld.proto b/protos/helloworld.proto
index aa44b851f4..4781fb4830 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 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 Greetings {
- // Sends a greeting
- rpc hello (HelloRequest) returns (HelloReply) {
- }
+ string message = 1;
}
diff --git a/protos/math.proto b/protos/math.proto
deleted file mode 100644
index 46a33aeee5..0000000000
--- 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/route_guide.proto b/protos/route_guide.proto
new file mode 100644
index 0000000000..7cda80efad
--- /dev/null
+++ b/protos/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 = "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 {
+ 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.
+ Point lo = 1;
+
+ // The other corner of the rectangle.
+ 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.
+ string name = 1;
+
+ // The point where the feature is detected.
+ Point location = 2;
+}
+
+// A RouteNote is a message sent while at a given point.
+message RouteNote {
+ // The location from which the message is sent.
+ Point location = 1;
+
+ // The message to be sent.
+ 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.
+ int32 point_count = 1;
+
+ // The number of known features passed while traversing the route.
+ int32 feature_count = 2;
+
+ // The distance covered in metres.
+ int32 distance = 3;
+
+ // The duration of the traversal in seconds.
+ int32 elapsed_time = 4;
+}
diff --git a/ruby/.gitignore b/ruby/.gitignore
new file mode 100644
index 0000000000..62fcb4fa94
--- /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 0000000000..2d76038e09
--- /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 0000000000..668baf3eb7
--- /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 0000000000..795c84c0f5
--- /dev/null
+++ b/ruby/greeter.gemspec
@@ -0,0 +1,23 @@
+# -*- ruby -*-
+# encoding: utf-8
+
+Gem::Specification.new do |s|
+ 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'
+ s.summary = 'gRPC Ruby overview sample'
+ 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|
+ 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 0000000000..e6cb4bad33
--- /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 0000000000..eb1a6ab454
--- /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 0000000000..82bdd78e2a
--- /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 0000000000..9bd528485a
--- /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