From c58f88392a9d5d221d89676e8fd76e711181d941 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 23 Jan 2015 15:26:48 -0800 Subject: Initial README.md --- README.md | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000..8b7bca010f --- /dev/null +++ b/README.md @@ -0,0 +1,71 @@ +# gRPC Helloworld Tutorial + +A great way to get introduced to gRPC is to work through this tutorial, which +walks you through the construction of simple client and server that introduces +various features of gRPC. + +When you finish the tutorial, you will be able to + +- Create an protobuf schema that defines a simple RPC service +- Create a Java server that implements the schema interface +- Create a Java client that accesses the server +- Create a Go client that accesses the Java server +- Update the service with advanced features like RPC streaming + +# Get Started + +The rest of this page explains how you can set up your local machine for development. +If you just want to read the tutorial, you can go straight to the next step: [Step - 0](Step_0.md) + +# Working with the code + +You can follow along with this tutorial and hack on the code in the comfort of +your own computer. In this way you can get hands-on practice of really writing +gRPC code. + +The tutorial relies on the use of the Git versioning system for source code +management. You don't need to know anything about Git to follow the tutorial +other than how to install and run a few git commands. + +# Install Git + +You can download and install Git from http://git-scm.com/download. Once +installed you should have access to the git command line tool. The main +commands that you will need to use are: + +- git clone ... : clone a remote repository onto your local machine +- git checkout ... : check out a particular branch or a tagged version of the code to hack on + +# Download grpc-helloworld + +Clone the grpc-helloword repository located at GitHub by running the following command: + +``` +git clone https://github.com/google/grpc-helloworld.git +``` + +Change your current directory to grpc-helloworld + +``` +cd grpc-helloworld +``` + +# Install Java 8 + +Java gRPC works on both Java 7 and Java 8. To keep this example simple, will +assume that you've installed Java 8. Instructions for +[installing Java 8](http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html) +are available online. + +# Install Go 1.4 + +Go gRPC requires Go 1.4. It's available for [download](https://golang.org/dl/) and install online. + +# (optional) Install protoc + +gRPC uses the latest version of the protocol buffer compiler, protoc. + +For following this tutorial, the protoc is not strictly necessary, as all the +generated code is checked into the Git repository. If you want to experiment +with generating the code yourself, download and install protoc from its +[Git repo](https://github.com/google/protobuf) -- cgit v1.2.3 From 8536e0767e936895c2f38c5d77d582621bafd22a Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 23 Jan 2015 17:12:39 -0800 Subject: Step-0: define a service --- Step_0.md | 40 ++++++++++++++++++++++++++++++++++++++++ helloworld.proto | 20 ++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 Step_0.md create mode 100644 helloworld.proto diff --git a/Step_0.md b/Step_0.md new file mode 100644 index 0000000000..695fb1a432 --- /dev/null +++ b/Step_0.md @@ -0,0 +1,40 @@ +# Step-0: define a service + +This section presents an example of a very simple service definition that +receives a message from a remote client. The messages contains the users's +name and sends's back a greeting for that person. + +Here it is in full; to be used to generate gRPC code it's defined in it's own +file [helloworld.proto](helloworld.proto). + +``` +syntax = "proto3"; + +package helloworld; + +// The request message containing the user's name. +message HelloRequest { + optional string name = 1; +} + +// The response message containing the greetings +message HelloReply { + optional string message = 1; +} + +// The greeting service definition. +service Greeting { + + // Sends a greeting + rpc hello (HelloRequest) returns (HelloReply) { + } +} + +``` + +The service stanza of the messages is an example of protobuf service IDL +(Interface Defintion Language). Here, it defines a very simple service that +receives a request and returns a response. + +Next in [Step-1](Step-1.md), we'll use protoc to generate code this simple +definition. diff --git a/helloworld.proto b/helloworld.proto new file mode 100644 index 0000000000..a7f5bfbb4d --- /dev/null +++ b/helloworld.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +package helloworld; + +// The request message containing the user's name. +message HelloRequest { + optional string name = 1; +} + +// The response message containing the greetings +message HelloReply { + optional string message = 1; +} + +// The greeting service definition. +service Greeting { + // Sends a greeting + rpc hello (HelloRequest) returns (HelloReply) { + } +} -- cgit v1.2.3 From 5c72361ee17583a4de5d5e4a482e0b74c06acb0c Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 23 Jan 2015 17:15:03 -0800 Subject: Step-0: define a service --- Step_0.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Step_0.md b/Step_0.md index 695fb1a432..2e5483c028 100644 --- a/Step_0.md +++ b/Step_0.md @@ -1,8 +1,8 @@ # Step-0: define a service This section presents an example of a very simple service definition that -receives a message from a remote client. The messages contains the users's -name and sends's back a greeting for that person. +receives a message from a remote client. The message contains the users's +name and sends back a greeting to that person. Here it is in full; to be used to generate gRPC code it's defined in it's own file [helloworld.proto](helloworld.proto). -- cgit v1.2.3 From 33208208fe4f9dde7c2dff2e2db9ce66d7537b60 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 23 Jan 2015 18:25:27 -0800 Subject: Step-0: define a service --- Step_0.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Step_0.md b/Step_0.md index 2e5483c028..3fec8376d1 100644 --- a/Step_0.md +++ b/Step_0.md @@ -1,11 +1,11 @@ # Step-0: define a service -This section presents an example of a very simple service definition that -receives a message from a remote client. The message contains the users's -name and sends back a greeting to that person. +This section presents an example of a simple service definition that receives +a message from a remote client. The message contains the users's name and +sends back a greeting to that person. -Here it is in full; to be used to generate gRPC code it's defined in it's own -file [helloworld.proto](helloworld.proto). +It's shown below in full; it's actually contained in separate file +[helloworld.proto](helloworld.proto). ``` syntax = "proto3"; @@ -32,9 +32,10 @@ service Greeting { ``` -The service stanza of the messages is an example of protobuf service IDL -(Interface Defintion Language). Here, it defines a very simple service that -receives a request and returns a response. +The service stanza of the message is an example of protobuf service IDL +(Interface Defintion Language). Here, it defines a simple service that +receives a request containing a name and returns a response containing a +message. -Next in [Step-1](Step-1.md), we'll use protoc to generate code this simple -definition. +Next, in [Step-1](Step-1.md), we'll use protoc to generate client code from +this IDL. -- cgit v1.2.3 From 448d4fcfb9126a032536ff377dc1dcc5a04ee9db Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Sun, 25 Jan 2015 09:52:57 -0800 Subject: Updates the README.md to make maven a prequisite --- README.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8b7bca010f..a5406ae217 100644 --- a/README.md +++ b/README.md @@ -52,14 +52,22 @@ cd grpc-helloworld # Install Java 8 -Java gRPC works on both Java 7 and Java 8. To keep this example simple, will -assume that you've installed Java 8. Instructions for -[installing Java 8](http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html) -are available online. +Java gRPC is designed to work with both Java 7 and Java 8. For simplicity, +the example assumes that Java 8 is installed. See +[Install Java 8](http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html) +for instructions. + +# Install Maven + +To simplify building and the managing of gRPC's dependencies, the java client +are server are structured as a standard [Maven](http://maven.apache.org/guides/getting-started/) +project. See [Install Maven](http://maven.apache.org/users/index.html) for instructions. + # Install Go 1.4 -Go gRPC requires Go 1.4. It's available for [download](https://golang.org/dl/) and install online. +Go gRPC requires Go 1.4, the latest version of Go. See +[Install Go](https://golang.org/doc/install) for instructions. # (optional) Install protoc -- cgit v1.2.3 From fb52c2abafd7b6202f781472c6841e2ccb8b2028 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Sun, 25 Jan 2015 09:53:43 -0800 Subject: Moves the proto to the location within the maven repo --- helloworld.proto | 20 -------------------- src/main/proto/helloworld.proto | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 20 deletions(-) delete mode 100644 helloworld.proto create mode 100644 src/main/proto/helloworld.proto diff --git a/helloworld.proto b/helloworld.proto deleted file mode 100644 index a7f5bfbb4d..0000000000 --- a/helloworld.proto +++ /dev/null @@ -1,20 +0,0 @@ -syntax = "proto3"; - -package helloworld; - -// The request message containing the user's name. -message HelloRequest { - optional string name = 1; -} - -// The response message containing the greetings -message HelloReply { - optional string message = 1; -} - -// The greeting service definition. -service Greeting { - // Sends a greeting - rpc hello (HelloRequest) returns (HelloReply) { - } -} diff --git a/src/main/proto/helloworld.proto b/src/main/proto/helloworld.proto new file mode 100644 index 0000000000..da5c3a1d85 --- /dev/null +++ b/src/main/proto/helloworld.proto @@ -0,0 +1,22 @@ +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) { + } +} -- cgit v1.2.3 From fc216a9b56b4735c626420717f44dfed07293cd0 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Sun, 25 Jan 2015 09:54:11 -0800 Subject: Adds .gitignore to ignore maven generated files --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..1a49c132b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*~ +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties \ No newline at end of file -- cgit v1.2.3 From d0eb1f903775264fe6dcb83e69a53d0eedbd8f54 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Sun, 25 Jan 2015 09:54:31 -0800 Subject: Adds the maven project file --- pom.xml | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 pom.xml diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000000..da0ee205f7 --- /dev/null +++ b/pom.xml @@ -0,0 +1,105 @@ + + 4.0.0 + + + com.google.net.stubby + stubby-parent + 0.1.0-SNAPSHOT + + + grpc-hello-world + jar + + Hello gRPC World + + + + ${project.groupId} + stubby-core + ${project.version} + + + ${project.groupId} + stubby-netty + ${project.version} + + + ${project.groupId} + stubby-okhttp + ${project.version} + + + ${project.groupId} + stubby-stub + ${project.version} + + + ${project.groupId} + stubby-testing + ${project.version} + + + junit + junit + compile + + + org.mockito + mockito-core + compile + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble-all + package + + single + + + + + + jar-with-dependencies + + + + + + com.internetitem + write-properties-file-maven-plugin + + + bootclasspath + prepare-package + + write-properties-file + + + bootclasspath.properties + ${project.build.directory} + + + bootclasspath + ${argLine.bootcp} + + + jar + ${project.build.directory}/${project.artifactId}-${project.version}-jar-with-dependencies.jar + + + + + + + + + -- cgit v1.2.3 From 783a8613d54eba8f4bfe907a7a863336eee6b2cd Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Sun, 25 Jan 2015 09:58:49 -0800 Subject: Adds: Step_1 - generate the service client --- Step_1.md | 33 ++ src/main/java/ex/grpc/GreetingsGrpc.java | 172 ++++++ src/main/java/ex/grpc/Helloworld.java | 951 +++++++++++++++++++++++++++++++ 3 files changed, 1156 insertions(+) create mode 100644 Step_1.md create mode 100644 src/main/java/ex/grpc/GreetingsGrpc.java create mode 100644 src/main/java/ex/grpc/Helloworld.java diff --git a/Step_1.md b/Step_1.md new file mode 100644 index 0000000000..4ac68aba5d --- /dev/null +++ b/Step_1.md @@ -0,0 +1,33 @@ +# Step-1: Generate a service client. + +In this step, we use protoc to generate the java Stub classes. A Stub is the +name gRPC uses for the code that initiates contact with a gRPC service running +remotely via the internet. + +If you did not install protoc on your system, you can skip this step and move +onto the next one where we examine the generated code. + +First, you'll need to build the protobuf plugin that generates the rpc +classes. `protoc` uses other tools called plugins to add additional features +to generated code. + +The grpc Java Stub classes are created using a grpc java plugin, but first the +plugin must be built and installed. + +To build the plugin: +``` +$ pushd external/grpc_java +$ make java_plugin +$ popd +``` + +To use it to generate the code: +``` +$ mkdir -p src/main/java +$ protoc -I . helloworld.proto --plugin=protoc-gen-grpc=external/grpc_java/bins/opt/java_plugin \ + --grpc_out=src/main/java \ + --java_out=src/main/java +``` + +Next, in [Step-2](Step-2.md), we'll use the generated Stub implementation to +write a client that uses the generated code to make a call to a service. diff --git a/src/main/java/ex/grpc/GreetingsGrpc.java b/src/main/java/ex/grpc/GreetingsGrpc.java new file mode 100644 index 0000000000..97c2f00a1e --- /dev/null +++ b/src/main/java/ex/grpc/GreetingsGrpc.java @@ -0,0 +1,172 @@ +package ex.grpc; + +import static com.google.net.stubby.stub.Calls.createMethodDescriptor; +import static com.google.net.stubby.stub.Calls.asyncUnaryCall; +import static com.google.net.stubby.stub.Calls.asyncServerStreamingCall; +import static com.google.net.stubby.stub.Calls.asyncClientStreamingCall; +import static com.google.net.stubby.stub.Calls.duplexStreamingCall; +import static com.google.net.stubby.stub.Calls.blockingUnaryCall; +import static com.google.net.stubby.stub.Calls.blockingServerStreamingCall; +import static com.google.net.stubby.stub.Calls.unaryFutureCall; +import static com.google.net.stubby.stub.ServerCalls.createMethodDefinition; +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 { + + private static final com.google.net.stubby.stub.Method METHOD_HELLO = + com.google.net.stubby.stub.Method.create( + com.google.net.stubby.MethodType.UNARY, "hello", + 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 GreetingsBlockingStub newBlockingStub( + com.google.net.stubby.Channel channel) { + return new GreetingsBlockingStub(channel, CONFIG); + } + + public static GreetingsFutureStub newFutureStub( + com.google.net.stubby.Channel channel) { + return new GreetingsFutureStub(channel, CONFIG); + } + + public static final GreetingsServiceDescriptor CONFIG = + new GreetingsServiceDescriptor(); + + @javax.annotation.concurrent.Immutable + public static class GreetingsServiceDescriptor extends + com.google.net.stubby.stub.AbstractServiceDescriptor { + public final com.google.net.stubby.MethodDescriptor hello; + + private GreetingsServiceDescriptor() { + hello = createMethodDescriptor( + "helloworld.Greetings", METHOD_HELLO); + } + + private GreetingsServiceDescriptor( + java.util.Map> methodMap) { + hello = (com.google.net.stubby.MethodDescriptor) methodMap.get( + CONFIG.hello.getName()); + } + + @java.lang.Override + protected GreetingsServiceDescriptor build( + java.util.Map> methodMap) { + return new GreetingsServiceDescriptor(methodMap); + } + + @java.lang.Override + public com.google.common.collect.ImmutableList> methods() { + return com.google.common.collect.ImmutableList.>of( + hello); + } + } + + public static interface Greetings { + + public void hello(ex.grpc.Helloworld.HelloRequest request, + com.google.net.stubby.stub.StreamObserver responseObserver); + } + + public static interface GreetingsBlockingClient { + + public ex.grpc.Helloworld.HelloReply hello(ex.grpc.Helloworld.HelloRequest request); + } + + public static interface GreetingsFutureClient { + + public com.google.common.util.concurrent.ListenableFuture hello( + ex.grpc.Helloworld.HelloRequest request); + } + + public static class GreetingsStub extends + com.google.net.stubby.stub.AbstractStub + implements Greetings { + private GreetingsStub(com.google.net.stubby.Channel channel, + GreetingsServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected GreetingsStub build(com.google.net.stubby.Channel channel, + GreetingsServiceDescriptor config) { + return new GreetingsStub(channel, config); + } + + @java.lang.Override + public void hello(ex.grpc.Helloworld.HelloRequest request, + com.google.net.stubby.stub.StreamObserver responseObserver) { + asyncUnaryCall( + channel.newCall(config.hello), request, responseObserver); + } + } + + public static class GreetingsBlockingStub extends + com.google.net.stubby.stub.AbstractStub + implements GreetingsBlockingClient { + private GreetingsBlockingStub(com.google.net.stubby.Channel channel, + GreetingsServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected GreetingsBlockingStub build(com.google.net.stubby.Channel channel, + GreetingsServiceDescriptor config) { + return new GreetingsBlockingStub(channel, config); + } + + @java.lang.Override + public ex.grpc.Helloworld.HelloReply hello(ex.grpc.Helloworld.HelloRequest request) { + return blockingUnaryCall( + channel.newCall(config.hello), request); + } + } + + public static class GreetingsFutureStub extends + com.google.net.stubby.stub.AbstractStub + implements GreetingsFutureClient { + private GreetingsFutureStub(com.google.net.stubby.Channel channel, + GreetingsServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected GreetingsFutureStub build(com.google.net.stubby.Channel channel, + GreetingsServiceDescriptor config) { + return new GreetingsFutureStub(channel, config); + } + + @java.lang.Override + public com.google.common.util.concurrent.ListenableFuture hello( + ex.grpc.Helloworld.HelloRequest request) { + return unaryFutureCall( + channel.newCall(config.hello), request); + } + } + + public static com.google.net.stubby.ServerServiceDefinition bindService( + final Greetings serviceImpl) { + return com.google.net.stubby.ServerServiceDefinition.builder("helloworld.Greetings") + .addMethod(createMethodDefinition( + METHOD_HELLO, + asyncUnaryRequestCall( + new com.google.net.stubby.stub.ServerCalls.UnaryRequestMethod< + ex.grpc.Helloworld.HelloRequest, + ex.grpc.Helloworld.HelloReply>() { + @java.lang.Override + public void invoke( + ex.grpc.Helloworld.HelloRequest request, + com.google.net.stubby.stub.StreamObserver responseObserver) { + serviceImpl.hello(request, responseObserver); + } + }))).build(); + } +} diff --git a/src/main/java/ex/grpc/Helloworld.java b/src/main/java/ex/grpc/Helloworld.java new file mode 100644 index 0000000000..f72040fa2b --- /dev/null +++ b/src/main/java/ex/grpc/Helloworld.java @@ -0,0 +1,951 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: src/main/proto/helloworld.proto + +package ex.grpc; + +public final class Helloworld { + private Helloworld() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + } + public interface HelloRequestOrBuilder extends + // @@protoc_insertion_point(interface_extends:helloworld.HelloRequest) + com.google.protobuf.MessageOrBuilder { + + /** + * optional string name = 1; + */ + java.lang.String getName(); + /** + * optional string name = 1; + */ + com.google.protobuf.ByteString + getNameBytes(); + } + /** + * Protobuf type {@code helloworld.HelloRequest} + * + *
+   * The request message containing the user's name.
+   * 
+ */ + public static final class HelloRequest extends + com.google.protobuf.GeneratedMessage implements + // @@protoc_insertion_point(message_implements:helloworld.HelloRequest) + HelloRequestOrBuilder { + // Use HelloRequest.newBuilder() to construct. + private HelloRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + } + private HelloRequest() { + name_ = ""; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return com.google.protobuf.UnknownFieldSet.getDefaultInstance(); + } + private HelloRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + int mutable_bitField0_ = 0; + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!input.skipField(tag)) { + done = true; + } + break; + } + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + + name_ = bs; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ex.grpc.Helloworld.HelloRequest.class, ex.grpc.Helloworld.HelloRequest.Builder.class); + } + + public static final com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public HelloRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new HelloRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public static final int NAME_FIELD_NUMBER = 1; + private java.lang.Object name_; + /** + * optional string name = 1; + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + /** + * optional string name = 1; + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (!getNameBytes().isEmpty()) { + output.writeBytes(1, getNameBytes()); + } + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (!getNameBytes().isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getNameBytes()); + } + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + public static ex.grpc.Helloworld.HelloRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ex.grpc.Helloworld.HelloRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ex.grpc.Helloworld.HelloRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static ex.grpc.Helloworld.HelloRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static ex.grpc.Helloworld.HelloRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static ex.grpc.Helloworld.HelloRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return new Builder(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(ex.grpc.Helloworld.HelloRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code helloworld.HelloRequest} + * + *
+     * The request message containing the user's name.
+     * 
+ */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder implements + // @@protoc_insertion_point(builder_implements:helloworld.HelloRequest) + ex.grpc.Helloworld.HelloRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ex.grpc.Helloworld.HelloRequest.class, ex.grpc.Helloworld.HelloRequest.Builder.class); + } + + // Construct using ex.grpc.Helloworld.HelloRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + public Builder clear() { + super.clear(); + name_ = ""; + + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_descriptor; + } + + public ex.grpc.Helloworld.HelloRequest getDefaultInstanceForType() { + return ex.grpc.Helloworld.HelloRequest.getDefaultInstance(); + } + + public ex.grpc.Helloworld.HelloRequest build() { + ex.grpc.Helloworld.HelloRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public ex.grpc.Helloworld.HelloRequest buildPartial() { + ex.grpc.Helloworld.HelloRequest result = new ex.grpc.Helloworld.HelloRequest(this); + result.name_ = name_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ex.grpc.Helloworld.HelloRequest) { + return mergeFrom((ex.grpc.Helloworld.HelloRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ex.grpc.Helloworld.HelloRequest other) { + if (other == ex.grpc.Helloworld.HelloRequest.getDefaultInstance()) return this; + if (!other.getName().isEmpty()) { + name_ = other.name_; + onChanged(); + } + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ex.grpc.Helloworld.HelloRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ex.grpc.Helloworld.HelloRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object name_ = ""; + /** + * optional string name = 1; + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string name = 1; + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string name = 1; + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + name_ = value; + onChanged(); + return this; + } + /** + * optional string name = 1; + */ + public Builder clearName() { + + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * optional string name = 1; + */ + public Builder setNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + name_ = value; + onChanged(); + return this; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + + // @@protoc_insertion_point(builder_scope:helloworld.HelloRequest) + } + + // @@protoc_insertion_point(class_scope:helloworld.HelloRequest) + private static final ex.grpc.Helloworld.HelloRequest defaultInstance;static { + defaultInstance = new ex.grpc.Helloworld.HelloRequest(); + } + + public static ex.grpc.Helloworld.HelloRequest getDefaultInstance() { + return defaultInstance; + } + + public ex.grpc.Helloworld.HelloRequest getDefaultInstanceForType() { + return defaultInstance; + } + + } + + public interface HelloReplyOrBuilder extends + // @@protoc_insertion_point(interface_extends:helloworld.HelloReply) + com.google.protobuf.MessageOrBuilder { + + /** + * optional string message = 1; + */ + java.lang.String getMessage(); + /** + * optional string message = 1; + */ + com.google.protobuf.ByteString + getMessageBytes(); + } + /** + * Protobuf type {@code helloworld.HelloReply} + * + *
+   * The response message containing the greetings
+   * 
+ */ + public static final class HelloReply extends + com.google.protobuf.GeneratedMessage implements + // @@protoc_insertion_point(message_implements:helloworld.HelloReply) + HelloReplyOrBuilder { + // Use HelloReply.newBuilder() to construct. + private HelloReply(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + } + private HelloReply() { + message_ = ""; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return com.google.protobuf.UnknownFieldSet.getDefaultInstance(); + } + private HelloReply( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + int mutable_bitField0_ = 0; + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!input.skipField(tag)) { + done = true; + } + break; + } + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + + message_ = bs; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ex.grpc.Helloworld.HelloReply.class, ex.grpc.Helloworld.HelloReply.Builder.class); + } + + public static final com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public HelloReply parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new HelloReply(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public static final int MESSAGE_FIELD_NUMBER = 1; + private java.lang.Object message_; + /** + * optional string message = 1; + */ + public java.lang.String getMessage() { + java.lang.Object ref = message_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + message_ = s; + } + return s; + } + } + /** + * optional string message = 1; + */ + public com.google.protobuf.ByteString + getMessageBytes() { + java.lang.Object ref = message_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + message_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (!getMessageBytes().isEmpty()) { + output.writeBytes(1, getMessageBytes()); + } + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (!getMessageBytes().isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getMessageBytes()); + } + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + public static ex.grpc.Helloworld.HelloReply parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ex.grpc.Helloworld.HelloReply parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloReply parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ex.grpc.Helloworld.HelloReply parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloReply parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static ex.grpc.Helloworld.HelloReply parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloReply parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static ex.grpc.Helloworld.HelloReply parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloReply parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static ex.grpc.Helloworld.HelloReply parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return new Builder(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(ex.grpc.Helloworld.HelloReply prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code helloworld.HelloReply} + * + *
+     * The response message containing the greetings
+     * 
+ */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder implements + // @@protoc_insertion_point(builder_implements:helloworld.HelloReply) + ex.grpc.Helloworld.HelloReplyOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ex.grpc.Helloworld.HelloReply.class, ex.grpc.Helloworld.HelloReply.Builder.class); + } + + // Construct using ex.grpc.Helloworld.HelloReply.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + public Builder clear() { + super.clear(); + message_ = ""; + + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_descriptor; + } + + public ex.grpc.Helloworld.HelloReply getDefaultInstanceForType() { + return ex.grpc.Helloworld.HelloReply.getDefaultInstance(); + } + + public ex.grpc.Helloworld.HelloReply build() { + ex.grpc.Helloworld.HelloReply result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public ex.grpc.Helloworld.HelloReply buildPartial() { + ex.grpc.Helloworld.HelloReply result = new ex.grpc.Helloworld.HelloReply(this); + result.message_ = message_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ex.grpc.Helloworld.HelloReply) { + return mergeFrom((ex.grpc.Helloworld.HelloReply)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ex.grpc.Helloworld.HelloReply other) { + if (other == ex.grpc.Helloworld.HelloReply.getDefaultInstance()) return this; + if (!other.getMessage().isEmpty()) { + message_ = other.message_; + onChanged(); + } + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ex.grpc.Helloworld.HelloReply parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ex.grpc.Helloworld.HelloReply) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object message_ = ""; + /** + * optional string message = 1; + */ + public java.lang.String getMessage() { + java.lang.Object ref = message_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + message_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string message = 1; + */ + public com.google.protobuf.ByteString + getMessageBytes() { + java.lang.Object ref = message_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + message_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string message = 1; + */ + public Builder setMessage( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + message_ = value; + onChanged(); + return this; + } + /** + * optional string message = 1; + */ + public Builder clearMessage() { + + message_ = getDefaultInstance().getMessage(); + onChanged(); + return this; + } + /** + * optional string message = 1; + */ + public Builder setMessageBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + message_ = value; + onChanged(); + return this; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + + // @@protoc_insertion_point(builder_scope:helloworld.HelloReply) + } + + // @@protoc_insertion_point(class_scope:helloworld.HelloReply) + private static final ex.grpc.Helloworld.HelloReply defaultInstance;static { + defaultInstance = new ex.grpc.Helloworld.HelloReply(); + } + + public static ex.grpc.Helloworld.HelloReply getDefaultInstance() { + return defaultInstance; + } + + public ex.grpc.Helloworld.HelloReply getDefaultInstanceForType() { + return defaultInstance; + } + + } + + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_helloworld_HelloRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_helloworld_HelloRequest_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_helloworld_HelloReply_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_helloworld_HelloReply_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + 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" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }, assigner); + internal_static_helloworld_HelloRequest_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_helloworld_HelloRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_helloworld_HelloRequest_descriptor, + new java.lang.String[] { "Name", }); + internal_static_helloworld_HelloReply_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_helloworld_HelloReply_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_helloworld_HelloReply_descriptor, + new java.lang.String[] { "Message", }); + } + + // @@protoc_insertion_point(outer_class_scope) +} -- cgit v1.2.3 From 860ae5a0a27b76133e11bfad8474054d9cfbf26d Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Sun, 25 Jan 2015 10:00:19 -0800 Subject: Adds: Step_2 - adds a command line client app --- Step_2.md | 85 ++++++++++++++++++++++++++++++ src/main/java/ex/grpc/GreetingsClient.java | 55 +++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 Step_2.md create mode 100644 src/main/java/ex/grpc/GreetingsClient.java diff --git a/Step_2.md b/Step_2.md new file mode 100644 index 0000000000..dd134a989c --- /dev/null +++ b/Step_2.md @@ -0,0 +1,85 @@ +# Step-2: Write a service client. + +This step uses the generated code to write a simple client to access the hello +service. The full client is in [GreetingsClient.java](src/main/java/ex/grpc/GreetingsClient.java). + + +## Configuring the service to connect to. + +The client contains uses a Stub to contact the service. The internet address +is configured in the client constructor. gRPC Channel is the abstraction over +transport handling; its constructor accepts the host name and port of the +service. The channel in turn is used to construct the Stub. + + +``` + private final ChannelImpl channel; + private final GreetingGrpc.GreetingBlockingStub blockingStub; + + public HelloClient(String host, int port) { + channel = NettyChannelBuilder.forAddress(host, port) + .negotiationType(NegotiationType.PLAINTEXT) + .build(); + blockingStub = GreetingGrpc.newBlockingStub(channel); + } + +``` + +## Obtaining a greeting + +The greet method uses the stub to contact the service and obtain a greeting. +It: +- constructs a request +- obtains a reply from the stub +- prints out the greeting + + +``` + public void greet(String name) { + logger.debug("Will try to greet " + name + " ..."); + try { + Helloworld.HelloRequest request = Helloworld.HelloRequest.newBuilder().setName(name).build(); + Helloworld.HelloReply reply = blockingStub.hello(request); + logger.info("Greeting: " + reply.getMessage()); + } catch (RuntimeException e) { + logger.log(Level.WARNING, "RPC failed", e); + return; + } + } + +``` + +## Running from the command line + +The main method puts together the example so that it can be run from a command +line. + +``` + /* Access a service running on the local machine on port 50051 */ + HelloClient client = new HelloClient("localhost", 50051); + String user = "world"; + if (args.length > 1) { + user = args[1]; + } + client.greet(user); + +``` + +It can be built as follows. + +``` +$ mvn package +``` + +It can also be run, but doing so now would end up a with a failure as there is +no server available yet. The [next step](Step-3.md), describes how to +implement, build and run a server that supports the service description. + +## Notes + +- the client uses a blocking stub. This means that the RPC call waits for the + server to respond, and will either return a response or raise an exception. + +- gRPC Java has other kinds of stubs that make non-blocking calls to the + server, where the response is returned asynchronously. Usage of these stubs + is a more advanced topic and will be described in later steps. diff --git a/src/main/java/ex/grpc/GreetingsClient.java b/src/main/java/ex/grpc/GreetingsClient.java new file mode 100644 index 0000000000..4ae2e7076b --- /dev/null +++ b/src/main/java/ex/grpc/GreetingsClient.java @@ -0,0 +1,55 @@ +package ex.grpc; + +import com.google.net.stubby.ChannelImpl; +import com.google.net.stubby.stub.StreamObserver; +import com.google.net.stubby.transport.netty.NegotiationType; +import com.google.net.stubby.transport.netty.NettyChannelBuilder; + +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.concurrent.TimeUnit; + +public class GreetingsClient { + private final Logger logger = Logger.getLogger( + GreetingsClient.class.getName()); + private final ChannelImpl channel; + private final GreetingsGrpc.GreetingsBlockingStub blockingStub; + + public GreetingsClient(String host, int port) { + channel = NettyChannelBuilder.forAddress(host, port) + .negotiationType(NegotiationType.PLAINTEXT) + .build(); + blockingStub = GreetingsGrpc.newBlockingStub(channel); + } + + public void shutdown() throws InterruptedException { + channel.shutdown().awaitTerminated(5, TimeUnit.SECONDS); + } + + public void greet(String name) { + try { + logger.fine("Will try to greet " + name + " ..."); + Helloworld.HelloRequest req = + Helloworld.HelloRequest.newBuilder().setName(name).build(); + Helloworld.HelloReply reply = blockingStub.hello(req); + logger.info("Greeting: " + reply.getMessage()); + } catch (RuntimeException e) { + logger.log(Level.WARNING, "RPC failed", e); + return; + } + } + + public static void main(String[] args) throws Exception { + GreetingsClient client = new GreetingsClient("localhost", 50051); + try { + /* Access a service running on the local machine on port 50051 */ + String user = "world"; + if (args.length > 0) { + user = args[0]; /* Use the arg as the name to greet if provided */ + } + client.greet(user); + } finally { + client.shutdown(); + } + } +} -- cgit v1.2.3 From 7131c9798d861a91049519319dd3f93fc4f1cefe Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Sun, 25 Jan 2015 10:02:04 -0800 Subject: Adds: Step_3 - adds a server implementation and command line app --- Step_3.md | 82 ++++++++++++++++++++++++++++++ src/main/java/ex/grpc/GreetingsImpl.java | 16 ++++++ src/main/java/ex/grpc/GreetingsServer.java | 51 +++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 Step_3.md create mode 100644 src/main/java/ex/grpc/GreetingsImpl.java create mode 100644 src/main/java/ex/grpc/GreetingsServer.java diff --git a/Step_3.md b/Step_3.md new file mode 100644 index 0000000000..56d6e7cfd3 --- /dev/null +++ b/Step_3.md @@ -0,0 +1,82 @@ +# Step-3: Implement a server. + +This step extends the generated server skeleton code to write a simple server +that provides the hello service. This in introduces two new classes + +- a service implementation [GreetingsImpl.java](src/main/java/ex/grpc/GreetingsImpl.java). + +- a server that hosts the service implementation and allows to accessed over the network: [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java). + +## Service implementation + +[GreetingsSImpl.java](src/main/java/ex/grpc/GreetingsImpl.java) +implements the behaviour we require of our GreetingService. There are a +number of important features of gRPC being used here: + +``` + public void hello(Helloworld.HelloRequest req, + StreamObserver responseObserver) { + Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( + "Hello " + req.getName()).build(); + responseObserver.onValue(reply); + responseObserver.onCompleted(); + } +``` + +- it provides a class `GreetingsImpl` that implements a generated interface `GreetingsGrpc.Greetings` +- `GreetingsGrpc.Greetings` declares the method `hello` that was declared in the proto [IDL](src/main/proto/helloworld.proto) +- `hello's` signature is typesafe: + hello(Helloworld.HelloRequest req, StreamObserver responseObserver) +- `hello` takes two parameters: + `Helloworld.HelloRequest`: the request + `StreamObserver`: a response observer, an interface to be called with the response value +- to complete the call + - the return value is constructed + - the responseObserver.onValue() is called with the response + - responseObserver.onCompleted() is called to indicate that no more work will done on the RPC. + + +## Server implementation + +[GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java) shows the +other main feature to required to provde gRPC service; how to allow a service +implementation to be accessed from the network. + +``` + private void start() throws Exception { + server = NettyServerBuilder.forPort(port) + .addService(GreetingsGrpc.bindService(new GreetingsImpl())) + .build(); + server.startAsync(); + server.awaitRunning(5, TimeUnit.SECONDS); + } + +``` + +- it provides a class `GreetingsServer` that holds a `ServerImpl` that will run the server +- in the `start` method, `GreetingServer` binds the `GreetingsService` implementation to a port and begins running it +- there is also a `stop` method that takes care of shutting down the service and cleaning up when the program exits + +## Build it + +This is the same as before: our client and server are part of the same maven +package so the same command builds both. + +``` +$ mvn package +``` + +## Try them out + +We've added simple shell scripts to simplifying running the examples. Now +that they are built, you can run the server with. + +``` +$ ./run_greetings_server.sh +``` + +In another termainal window and confirm that it receives a message. + +``` +$ ./run_greetings_client.sh +``` diff --git a/src/main/java/ex/grpc/GreetingsImpl.java b/src/main/java/ex/grpc/GreetingsImpl.java new file mode 100644 index 0000000000..005489acaa --- /dev/null +++ b/src/main/java/ex/grpc/GreetingsImpl.java @@ -0,0 +1,16 @@ +package ex.grpc; + +import com.google.net.stubby.stub.StreamObserver; + +public class GreetingsImpl implements GreetingsGrpc.Greetings { + + @Override + public void hello(Helloworld.HelloRequest req, + StreamObserver responseObserver) { + Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( + "Hello " + req.getName()).build(); + responseObserver.onValue(reply); + responseObserver.onCompleted(); + } + +} diff --git a/src/main/java/ex/grpc/GreetingsServer.java b/src/main/java/ex/grpc/GreetingsServer.java new file mode 100644 index 0000000000..834ae985a4 --- /dev/null +++ b/src/main/java/ex/grpc/GreetingsServer.java @@ -0,0 +1,51 @@ +package ex.grpc; + +import com.google.common.util.concurrent.MoreExecutors; +import com.google.net.stubby.ServerImpl; +import com.google.net.stubby.transport.netty.NettyServerBuilder; + +import java.util.concurrent.TimeUnit; + +/** + * Server that manages startup/shutdown of a {@code Greetings} server. + */ +public class GreetingsServer { + /* 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())) + .build(); + server.startAsync(); + server.awaitRunning(5, TimeUnit.SECONDS); + System.out.println("Server started on port:" + port); + } + + private void stop() throws Exception { + server.stopAsync(); + server.awaitTerminated(); + System.out.println("Server shutting down ..."); + } + + /** + * Main launches the server from the command line. + */ + public static void main(String[] args) throws Exception { + final GreetingsServer server = new GreetingsServer(); + + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + try { + System.out.println("Shutting down"); + server.stop(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + server.start(); + } +} -- cgit v1.2.3 From 737ee5848de1a0aa7c35f34889ff5a810a0d07b8 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Sun, 25 Jan 2015 10:02:30 -0800 Subject: Adds: scripts to simplifying running the client and server --- run_greetings_client.sh | 10 ++++++++++ run_greetings_server.sh | 9 +++++++++ 2 files changed, 19 insertions(+) create mode 100755 run_greetings_client.sh create mode 100755 run_greetings_server.sh diff --git a/run_greetings_client.sh b/run_greetings_client.sh new file mode 100755 index 0000000000..8155589adf --- /dev/null +++ b/run_greetings_client.sh @@ -0,0 +1,10 @@ +#!/bin/bash -e +TARGET='Greetings Client' +TARGET_CLASS='ex.grpc.GreetingsClient' +TARGET_ARGS="$@" + +cd "$(dirname "$0")" +mvn -q -nsu -am package -Dcheckstyle.skip=true -DskipTests +. target/bootclasspath.properties +echo "[INFO] Running: $TARGET ($TARGET_CLASS $TARGET_ARGS)" +exec java "$bootclasspath" -cp "$jar" "$TARGET_CLASS" $TARGET_ARGS diff --git a/run_greetings_server.sh b/run_greetings_server.sh new file mode 100755 index 0000000000..248229e129 --- /dev/null +++ b/run_greetings_server.sh @@ -0,0 +1,9 @@ +#!/bin/bash -e +TARGET='Greetings Server' +TARGET_CLASS='ex.grpc.GreetingsServer' + +cd "$(dirname "$0")" +mvn -q -nsu -am package -Dcheckstyle.skip=true -DskipTests +. target/bootclasspath.properties +echo "[INFO] Running: $TARGET ($TARGET_CLASS)" +exec java "$bootclasspath" -cp "$jar" "$TARGET_CLASS" -- cgit v1.2.3 From a5570a457e513a66771407ebf0b6d7e8abe23a14 Mon Sep 17 00:00:00 2001 From: Jayant Kolhe Date: Fri, 30 Jan 2015 10:19:22 -0800 Subject: Initial commit --- LICENSE | 28 ++++++++++++++++++++++++++++ README.md | 2 ++ 2 files changed, 30 insertions(+) create mode 100644 LICENSE create mode 100644 README.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..05b6a757da --- /dev/null +++ b/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2015, grpc +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 grpc-common 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 HOLDER 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. + diff --git a/README.md b/README.md new file mode 100644 index 0000000000..2b288236bd --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# grpc-common +documents, resources, examples shared across other grpc repositories -- cgit v1.2.3 From 85e9567a201bb23d6e0107cd95dd087817a57eb8 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 30 Jan 2015 10:26:56 -0800 Subject: Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 2b288236bd..a73b7723d8 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ # grpc-common documents, resources, examples shared across other grpc repositories + +# TODO +fill this out -- cgit v1.2.3 From 00e23cfd2a6f70a17ebaafebdd0eaf62533c1fa1 Mon Sep 17 00:00:00 2001 From: Jayant Kolhe Date: Wed, 4 Feb 2015 09:44:55 -0800 Subject: Update Step_0.md --- Step_0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Step_0.md b/Step_0.md index 3fec8376d1..1a2dbcb2fe 100644 --- a/Step_0.md +++ b/Step_0.md @@ -37,5 +37,5 @@ The service stanza of the message is an example of protobuf service IDL receives a request containing a name and returns a response containing a message. -Next, in [Step-1](Step-1.md), we'll use protoc to generate client code from +Next, in [Step_1](Step_1.md), we'll use protoc to generate client code from this IDL. -- cgit v1.2.3 From b9c24a11dd66a89ed9ce4f4ff4c93f22e46ffc1c Mon Sep 17 00:00:00 2001 From: Jayant Kolhe Date: Wed, 4 Feb 2015 09:46:09 -0800 Subject: Update Step_0.md --- Step_0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Step_0.md b/Step_0.md index 1a2dbcb2fe..02a2b04c0e 100644 --- a/Step_0.md +++ b/Step_0.md @@ -37,5 +37,5 @@ The service stanza of the message is an example of protobuf service IDL receives a request containing a name and returns a response containing a message. -Next, in [Step_1](Step_1.md), we'll use protoc to generate client code from +Next, in [Step - 1](Step_1.md), we'll use protoc to generate client code from this IDL. -- cgit v1.2.3 From 15dd5da9f5a1cd6783ae9640ebfe02efbdcfedbc Mon Sep 17 00:00:00 2001 From: Jayant Kolhe Date: Wed, 4 Feb 2015 09:56:29 -0800 Subject: Update Step_1.md --- Step_1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Step_1.md b/Step_1.md index 4ac68aba5d..da85cb4e10 100644 --- a/Step_1.md +++ b/Step_1.md @@ -29,5 +29,5 @@ $ protoc -I . helloworld.proto --plugin=protoc-gen-grpc=external/grpc_java/bins/ --java_out=src/main/java ``` -Next, in [Step-2](Step-2.md), we'll use the generated Stub implementation to +Next, in [Step - 2](Step_2.md), we'll use the generated Stub implementation to write a client that uses the generated code to make a call to a service. -- cgit v1.2.3 From 5a92194fb0c3fb6936b8144f98853f0b9a234a0f Mon Sep 17 00:00:00 2001 From: Jayant Kolhe Date: Wed, 4 Feb 2015 09:57:40 -0800 Subject: Update Step_2.md --- Step_2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Step_2.md b/Step_2.md index dd134a989c..32c578f18a 100644 --- a/Step_2.md +++ b/Step_2.md @@ -72,7 +72,7 @@ $ mvn package ``` It can also be run, but doing so now would end up a with a failure as there is -no server available yet. The [next step](Step-3.md), describes how to +no server available yet. The [next step](Step_3.md), describes how to implement, build and run a server that supports the service description. ## Notes -- cgit v1.2.3 From 99a1fe644087da862af2287c452b38b7fd4f1b9c Mon Sep 17 00:00:00 2001 From: Dan Ciruli Date: Wed, 4 Feb 2015 10:07:45 -0800 Subject: Fixed 2 typos. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9a668f3b1c..c0fc227b29 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# gRPC Helloworld Tutorial +# gRPC Hello World Tutorial ## TODO: move this to the tutorial sub-folder @@ -8,7 +8,7 @@ various features of gRPC. When you finish the tutorial, you will be able to -- Create an protobuf schema that defines a simple RPC service +- Create a protobuf schema that defines a simple RPC service - Create a Java server that implements the schema interface - Create a Java client that accesses the server - Create a Go client that accesses the Java server -- cgit v1.2.3 From cdf7f84d073ef17da2b73de53cdcc0164368e109 Mon Sep 17 00:00:00 2001 From: Mugur Marculescu Date: Wed, 4 Feb 2015 20:14:08 -0800 Subject: Attempt to Fix broken link to helloworld.proto Actually Fix broken link to helloworld.proto --- Step_0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Step_0.md b/Step_0.md index 02a2b04c0e..a346f77e81 100644 --- a/Step_0.md +++ b/Step_0.md @@ -5,7 +5,7 @@ a message from a remote client. The message contains the users's name and sends back a greeting to that person. It's shown below in full; it's actually contained in separate file -[helloworld.proto](helloworld.proto). +[helloworld.proto](src/main/proto/helloworld.proto). ``` syntax = "proto3"; -- cgit v1.2.3 From 5d8c3b264c89fb1598e4cc418e2c0c4c417d5c4b Mon Sep 17 00:00:00 2001 From: Mugur Marculescu Date: Wed, 4 Feb 2015 21:21:37 -0800 Subject: Fixing a couple of typos and grammer issues. --- README.md | 18 +++++++++--------- Step_0.md | 6 +++--- Step_1.md | 4 ++-- Step_2.md | 10 +++++----- Step_3.md | 16 ++++++++-------- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index c0fc227b29..41b79ba883 100644 --- a/README.md +++ b/README.md @@ -3,16 +3,16 @@ ## TODO: move this to the tutorial sub-folder A great way to get introduced to gRPC is to work through this tutorial, which -walks you through the construction of simple client and server that introduces +walks you through the construction of a simple client and server and introduces various features of gRPC. When you finish the tutorial, you will be able to -- Create a protobuf schema that defines a simple RPC service -- Create a Java server that implements the schema interface -- Create a Java client that accesses the server -- Create a Go client that accesses the Java server -- Update the service with advanced features like RPC streaming +- Create a protobuf schema that defines a simple RPC service. +- Create a Java server that implements the schema interface. +- Create a Java client that accesses the server. +- Create a Go client that accesses the Java server. +- Update the service with advanced features like RPC streaming. # Get Started @@ -22,7 +22,7 @@ If you just want to read the tutorial, you can go straight to the next step: [St # Working with the code You can follow along with this tutorial and hack on the code in the comfort of -your own computer. In this way you can get hands-on practice of really writing +your own computer. This way you can get hands-on practice of really writing gRPC code. The tutorial relies on the use of the Git versioning system for source code @@ -61,7 +61,7 @@ for instructions. # Install Maven -To simplify building and the managing of gRPC's dependencies, the java client +To simplify building and the managing of gRPC's dependencies, the Java client are server are structured as a standard [Maven](http://maven.apache.org/guides/getting-started/) project. See [Install Maven](http://maven.apache.org/users/index.html) for instructions. @@ -76,6 +76,6 @@ Go gRPC requires Go 1.4, the latest version of Go. See gRPC uses the latest version of the protocol buffer compiler, protoc. For following this tutorial, the protoc is not strictly necessary, as all the -generated code is checked into the Git repository. If you want to experiment +generated code is checked into the Git repository. If you want to experiment with generating the code yourself, download and install protoc from its [Git repo](https://github.com/google/protobuf) diff --git a/Step_0.md b/Step_0.md index a346f77e81..07c5bc5690 100644 --- a/Step_0.md +++ b/Step_0.md @@ -1,10 +1,10 @@ # Step-0: define a service This section presents an example of a simple service definition that receives -a message from a remote client. The message contains the users's name and +a message from a remote client. The message contains the user's name and sends back a greeting to that person. -It's shown below in full; it's actually contained in separate file +It's shown below in full; it's actually contained in separate file. [helloworld.proto](src/main/proto/helloworld.proto). ``` @@ -33,7 +33,7 @@ service Greeting { ``` The service stanza of the message is an example of protobuf service IDL -(Interface Defintion Language). Here, it defines a simple service that +(Interface Defintion Language). Here, it defines a simple service that receives a request containing a name and returns a response containing a message. diff --git a/Step_1.md b/Step_1.md index da85cb4e10..c7aed326c3 100644 --- a/Step_1.md +++ b/Step_1.md @@ -1,6 +1,6 @@ # Step-1: Generate a service client. -In this step, we use protoc to generate the java Stub classes. A Stub is the +In this step, we use protoc to generate the Java Stub classes. A Stub is the name gRPC uses for the code that initiates contact with a gRPC service running remotely via the internet. @@ -11,7 +11,7 @@ First, you'll need to build the protobuf plugin that generates the rpc classes. `protoc` uses other tools called plugins to add additional features to generated code. -The grpc Java Stub classes are created using a grpc java plugin, but first the +The gRPC Java Stub classes are created using a gRPC Java plugin, but first the plugin must be built and installed. To build the plugin: diff --git a/Step_2.md b/Step_2.md index 32c578f18a..eafe70b692 100644 --- a/Step_2.md +++ b/Step_2.md @@ -1,15 +1,15 @@ # Step-2: Write a service client. This step uses the generated code to write a simple client to access the hello -service. The full client is in [GreetingsClient.java](src/main/java/ex/grpc/GreetingsClient.java). +service. The full client is in [GreetingsClient.java](src/main/java/ex/grpc/GreetingsClient.java). ## Configuring the service to connect to. -The client contains uses a Stub to contact the service. The internet address -is configured in the client constructor. gRPC Channel is the abstraction over +The client contains uses a Stub to contact the service. The internet address +is configured in the client constructor. gRPC Channel is the abstraction over transport handling; its constructor accepts the host name and port of the -service. The channel in turn is used to construct the Stub. +service. The channel in turn is used to construct the Stub. ``` @@ -77,7 +77,7 @@ implement, build and run a server that supports the service description. ## Notes -- the client uses a blocking stub. This means that the RPC call waits for the +- The client uses a blocking stub. This means that the RPC call waits for the server to respond, and will either return a response or raise an exception. - gRPC Java has other kinds of stubs that make non-blocking calls to the diff --git a/Step_3.md b/Step_3.md index 56d6e7cfd3..bba8f0aa3f 100644 --- a/Step_3.md +++ b/Step_3.md @@ -1,16 +1,16 @@ # Step-3: Implement a server. This step extends the generated server skeleton code to write a simple server -that provides the hello service. This in introduces two new classes +that provides the hello service. This introduces two new classes: - a service implementation [GreetingsImpl.java](src/main/java/ex/grpc/GreetingsImpl.java). -- a server that hosts the service implementation and allows to accessed over the network: [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java). +- a server that hosts the service implementation and allows access over the network: [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java). ## Service implementation -[GreetingsSImpl.java](src/main/java/ex/grpc/GreetingsImpl.java) -implements the behaviour we require of our GreetingService. There are a +[GreetingsImpl.java](src/main/java/ex/grpc/GreetingsImpl.java) +implements the behaviour we require of our GreetingService. There are a number of important features of gRPC being used here: ``` @@ -39,7 +39,7 @@ number of important features of gRPC being used here: ## Server implementation [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java) shows the -other main feature to required to provde gRPC service; how to allow a service +other main feature required to provde the gRPC service; how to allow a service implementation to be accessed from the network. ``` @@ -68,14 +68,14 @@ $ mvn package ## Try them out -We've added simple shell scripts to simplifying running the examples. Now -that they are built, you can run the server with. +We've added simple shell scripts to simplifying running the examples. Now +that they are built, you can run the server with: ``` $ ./run_greetings_server.sh ``` -In another termainal window and confirm that it receives a message. +and in another termainal window and confirm that it receives a message. ``` $ ./run_greetings_client.sh -- cgit v1.2.3 From d2828d9b1b0341e068741516fc91702a96844519 Mon Sep 17 00:00:00 2001 From: Mugur Marculescu Date: Wed, 4 Feb 2015 21:50:56 -0800 Subject: Another grammar fix. --- Step_3.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Step_3.md b/Step_3.md index bba8f0aa3f..d2d7f4788d 100644 --- a/Step_3.md +++ b/Step_3.md @@ -75,7 +75,7 @@ that they are built, you can run the server with: $ ./run_greetings_server.sh ``` -and in another termainal window and confirm that it receives a message. +and in another termainal window confirm that it receives a message. ``` $ ./run_greetings_client.sh -- cgit v1.2.3 From 8c92a90a4a3bdd0bd5ec37b7f9ad412cd0cd7f1f Mon Sep 17 00:00:00 2001 From: Mugur Marculescu Date: Wed, 4 Feb 2015 21:52:45 -0800 Subject: Another typo fix. --- Step_3.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Step_3.md b/Step_3.md index d2d7f4788d..7b03cdf585 100644 --- a/Step_3.md +++ b/Step_3.md @@ -75,7 +75,7 @@ that they are built, you can run the server with: $ ./run_greetings_server.sh ``` -and in another termainal window confirm that it receives a message. +and in another terminal window confirm that it receives a message. ``` $ ./run_greetings_client.sh -- cgit v1.2.3 From a14935fceeaa9111579a65e85929b9a171debe43 Mon Sep 17 00:00:00 2001 From: Mugur Marculescu Date: Thu, 5 Feb 2015 16:14:17 -0800 Subject: Another typo. --- Step_0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Step_0.md b/Step_0.md index 07c5bc5690..d0745b0dd1 100644 --- a/Step_0.md +++ b/Step_0.md @@ -33,7 +33,7 @@ service Greeting { ``` The service stanza of the message is an example of protobuf service IDL -(Interface Defintion Language). Here, it defines a simple service that +(Interface Definition Language). Here, it defines a simple service that receives a request containing a name and returns a response containing a message. -- cgit v1.2.3 From 8f505f74e420a5fe52cf084a55117f5c73e11774 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 5 Feb 2015 17:34:47 -0800 Subject: Adds the common protos along with a README.md --- protos/README.md | 12 ++++++++ protos/helloworld.proto | 51 +++++++++++++++++++++++++++++++ protos/math.proto | 79 +++++++++++++++++++++++++++++++++++++++++++++++++ protos/stock.proto | 71 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 213 insertions(+) create mode 100644 protos/README.md create mode 100644 protos/helloworld.proto create mode 100644 protos/math.proto create mode 100644 protos/stock.proto diff --git a/protos/README.md b/protos/README.md new file mode 100644 index 0000000000..29639a68f4 --- /dev/null +++ b/protos/README.md @@ -0,0 +1,12 @@ +# Example protos + +## Contents + +- helloworld.proto + A very simple example used in the overview. + +- stock.proto + A detailed example that's described in detail in the tutorial. + +- math.proto + Another detailed example for further reference. diff --git a/protos/helloworld.proto b/protos/helloworld.proto new file mode 100644 index 0000000000..aa44b851f4 --- /dev/null +++ b/protos/helloworld.proto @@ -0,0 +1,51 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "ex.grpc"; + +package helloworld; + +// The request message containing the user's name. +message HelloRequest { + optional string name = 1; +} + +// The response message containing the greetings +message HelloReply { + optional string message = 1; +} + +// The greeting service definition. +service Greetings { + // Sends a greeting + rpc hello (HelloRequest) returns (HelloReply) { + } +} diff --git a/protos/math.proto b/protos/math.proto new file mode 100644 index 0000000000..46a33aeee5 --- /dev/null +++ b/protos/math.proto @@ -0,0 +1,79 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package math; + +message DivArgs { + optional int64 dividend = 1; + optional int64 divisor = 2; +} + +message DivReply { + optional int64 quotient = 1; + optional int64 remainder = 2; +} + +message FibArgs { + optional int64 limit = 1; +} + +message Num { + optional int64 num = 1; +} + +message FibReply { + optional int64 count = 1; +} + +service Math { + // Div divides args.dividend by args.divisor and returns the quotient and + // remainder. + rpc Div (DivArgs) returns (DivReply) { + } + + // DivMany accepts an arbitrary number of division args from the client stream + // and sends back the results in the reply stream. The stream continues until + // the client closes its end; the server does the same after sending all the + // replies. The stream ends immediately if either end aborts. + rpc DivMany (stream DivArgs) returns (stream DivReply) { + } + + // Fib generates numbers in the Fibonacci sequence. If args.limit > 0, Fib + // generates up to limit numbers; otherwise it continues until the call is + // canceled. + rpc Fib (FibArgs) returns (stream Num) { + } + + // Sum sums a stream of numbers, returning the final result once the stream + // is closed. + rpc Sum (stream Num) returns (Num) { + } +} diff --git a/protos/stock.proto b/protos/stock.proto new file mode 100644 index 0000000000..dcb677e473 --- /dev/null +++ b/protos/stock.proto @@ -0,0 +1,71 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package examples; + +// Protocol type definitions +message StockRequest { + optional string symbol = 1; + optional int32 num_trades_to_watch = 2; +}; + +message StockReply { + optional float price = 1; + optional string symbol = 2; +}; + +// Interface exported by the server +service Stock { + // A simple blocking RPC. + // + // Obtains the last traded price for the given Stock. + rpc GetLastTradePrice(StockRequest) returns (StockReply) { + }; + + // A Unidirectional server-to-client streaming RPC. + // + // Streams future prices for a given symbol. + rpc WatchFutureTrades(StockRequest) returns (stream StockReply) { + }; + + // A Unidirectional client-to-server streaming RPC. + // + // Gets the highest traded price for a series of symbols + rpc GetHighestTradePrice(stream StockRequest) returns (StockReply) { + }; + + // Bidirectional streaming RPC. + // + // Gets the most recent traded price of series of trades. + rpc GetLastTradePriceMultiple(stream StockRequest) returns + (stream StockReply) { + }; +}; -- cgit v1.2.3 From bb9e6f4e7ce17d5a06e10a487e65ed6a1473155a Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 6 Feb 2015 12:56:33 -0800 Subject: removed superfluous semi-colons --- protos/stock.proto | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/protos/stock.proto b/protos/stock.proto index dcb677e473..49efbf2730 100644 --- a/protos/stock.proto +++ b/protos/stock.proto @@ -35,12 +35,12 @@ package examples; message StockRequest { optional string symbol = 1; optional int32 num_trades_to_watch = 2; -}; +} message StockReply { optional float price = 1; optional string symbol = 2; -}; +} // Interface exported by the server service Stock { @@ -48,24 +48,24 @@ service Stock { // // Obtains the last traded price for the given Stock. rpc GetLastTradePrice(StockRequest) returns (StockReply) { - }; + } // A Unidirectional server-to-client streaming RPC. // // Streams future prices for a given symbol. rpc WatchFutureTrades(StockRequest) returns (stream StockReply) { - }; + } // A Unidirectional client-to-server streaming RPC. // // Gets the highest traded price for a series of symbols rpc GetHighestTradePrice(stream StockRequest) returns (StockReply) { - }; + } // Bidirectional streaming RPC. // // Gets the most recent traded price of series of trades. rpc GetLastTradePriceMultiple(stream StockRequest) returns (stream StockReply) { - }; -}; + } +} -- cgit v1.2.3 From aa7afd63a8611c1e64de21d54da0eeb86a0c8360 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 6 Feb 2015 13:09:20 -0800 Subject: Moves java overview project to a subdirectory --- java/pom.xml | 105 +++ java/run_greetings_client.sh | 10 + java/run_greetings_server.sh | 9 + java/src/main/java/ex/grpc/GreetingsClient.java | 55 ++ java/src/main/java/ex/grpc/GreetingsGrpc.java | 172 +++++ java/src/main/java/ex/grpc/GreetingsImpl.java | 16 + java/src/main/java/ex/grpc/GreetingsServer.java | 51 ++ java/src/main/java/ex/grpc/Helloworld.java | 951 ++++++++++++++++++++++++ java/src/main/proto/helloworld.proto | 22 + pom.xml | 105 --- run_greetings_client.sh | 10 - run_greetings_server.sh | 9 - src/main/java/ex/grpc/GreetingsClient.java | 55 -- src/main/java/ex/grpc/GreetingsGrpc.java | 172 ----- src/main/java/ex/grpc/GreetingsImpl.java | 16 - src/main/java/ex/grpc/GreetingsServer.java | 51 -- src/main/java/ex/grpc/Helloworld.java | 951 ------------------------ src/main/proto/helloworld.proto | 22 - 18 files changed, 1391 insertions(+), 1391 deletions(-) create mode 100644 java/pom.xml create mode 100755 java/run_greetings_client.sh create mode 100755 java/run_greetings_server.sh create mode 100644 java/src/main/java/ex/grpc/GreetingsClient.java create mode 100644 java/src/main/java/ex/grpc/GreetingsGrpc.java create mode 100644 java/src/main/java/ex/grpc/GreetingsImpl.java create mode 100644 java/src/main/java/ex/grpc/GreetingsServer.java create mode 100644 java/src/main/java/ex/grpc/Helloworld.java create mode 100644 java/src/main/proto/helloworld.proto delete mode 100644 pom.xml delete mode 100755 run_greetings_client.sh delete mode 100755 run_greetings_server.sh delete mode 100644 src/main/java/ex/grpc/GreetingsClient.java delete mode 100644 src/main/java/ex/grpc/GreetingsGrpc.java delete mode 100644 src/main/java/ex/grpc/GreetingsImpl.java delete mode 100644 src/main/java/ex/grpc/GreetingsServer.java delete mode 100644 src/main/java/ex/grpc/Helloworld.java delete mode 100644 src/main/proto/helloworld.proto diff --git a/java/pom.xml b/java/pom.xml new file mode 100644 index 0000000000..da0ee205f7 --- /dev/null +++ b/java/pom.xml @@ -0,0 +1,105 @@ + + 4.0.0 + + + com.google.net.stubby + stubby-parent + 0.1.0-SNAPSHOT + + + grpc-hello-world + jar + + Hello gRPC World + + + + ${project.groupId} + stubby-core + ${project.version} + + + ${project.groupId} + stubby-netty + ${project.version} + + + ${project.groupId} + stubby-okhttp + ${project.version} + + + ${project.groupId} + stubby-stub + ${project.version} + + + ${project.groupId} + stubby-testing + ${project.version} + + + junit + junit + compile + + + org.mockito + mockito-core + compile + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble-all + package + + single + + + + + + jar-with-dependencies + + + + + + com.internetitem + write-properties-file-maven-plugin + + + bootclasspath + prepare-package + + write-properties-file + + + bootclasspath.properties + ${project.build.directory} + + + bootclasspath + ${argLine.bootcp} + + + jar + ${project.build.directory}/${project.artifactId}-${project.version}-jar-with-dependencies.jar + + + + + + + + + diff --git a/java/run_greetings_client.sh b/java/run_greetings_client.sh new file mode 100755 index 0000000000..8155589adf --- /dev/null +++ b/java/run_greetings_client.sh @@ -0,0 +1,10 @@ +#!/bin/bash -e +TARGET='Greetings Client' +TARGET_CLASS='ex.grpc.GreetingsClient' +TARGET_ARGS="$@" + +cd "$(dirname "$0")" +mvn -q -nsu -am package -Dcheckstyle.skip=true -DskipTests +. target/bootclasspath.properties +echo "[INFO] Running: $TARGET ($TARGET_CLASS $TARGET_ARGS)" +exec java "$bootclasspath" -cp "$jar" "$TARGET_CLASS" $TARGET_ARGS diff --git a/java/run_greetings_server.sh b/java/run_greetings_server.sh new file mode 100755 index 0000000000..248229e129 --- /dev/null +++ b/java/run_greetings_server.sh @@ -0,0 +1,9 @@ +#!/bin/bash -e +TARGET='Greetings Server' +TARGET_CLASS='ex.grpc.GreetingsServer' + +cd "$(dirname "$0")" +mvn -q -nsu -am package -Dcheckstyle.skip=true -DskipTests +. target/bootclasspath.properties +echo "[INFO] Running: $TARGET ($TARGET_CLASS)" +exec java "$bootclasspath" -cp "$jar" "$TARGET_CLASS" diff --git a/java/src/main/java/ex/grpc/GreetingsClient.java b/java/src/main/java/ex/grpc/GreetingsClient.java new file mode 100644 index 0000000000..4ae2e7076b --- /dev/null +++ b/java/src/main/java/ex/grpc/GreetingsClient.java @@ -0,0 +1,55 @@ +package ex.grpc; + +import com.google.net.stubby.ChannelImpl; +import com.google.net.stubby.stub.StreamObserver; +import com.google.net.stubby.transport.netty.NegotiationType; +import com.google.net.stubby.transport.netty.NettyChannelBuilder; + +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.concurrent.TimeUnit; + +public class GreetingsClient { + private final Logger logger = Logger.getLogger( + GreetingsClient.class.getName()); + private final ChannelImpl channel; + private final GreetingsGrpc.GreetingsBlockingStub blockingStub; + + public GreetingsClient(String host, int port) { + channel = NettyChannelBuilder.forAddress(host, port) + .negotiationType(NegotiationType.PLAINTEXT) + .build(); + blockingStub = GreetingsGrpc.newBlockingStub(channel); + } + + public void shutdown() throws InterruptedException { + channel.shutdown().awaitTerminated(5, TimeUnit.SECONDS); + } + + public void greet(String name) { + try { + logger.fine("Will try to greet " + name + " ..."); + Helloworld.HelloRequest req = + Helloworld.HelloRequest.newBuilder().setName(name).build(); + Helloworld.HelloReply reply = blockingStub.hello(req); + logger.info("Greeting: " + reply.getMessage()); + } catch (RuntimeException e) { + logger.log(Level.WARNING, "RPC failed", e); + return; + } + } + + public static void main(String[] args) throws Exception { + GreetingsClient client = new GreetingsClient("localhost", 50051); + try { + /* Access a service running on the local machine on port 50051 */ + String user = "world"; + if (args.length > 0) { + user = args[0]; /* Use the arg as the name to greet if provided */ + } + client.greet(user); + } finally { + client.shutdown(); + } + } +} diff --git a/java/src/main/java/ex/grpc/GreetingsGrpc.java b/java/src/main/java/ex/grpc/GreetingsGrpc.java new file mode 100644 index 0000000000..97c2f00a1e --- /dev/null +++ b/java/src/main/java/ex/grpc/GreetingsGrpc.java @@ -0,0 +1,172 @@ +package ex.grpc; + +import static com.google.net.stubby.stub.Calls.createMethodDescriptor; +import static com.google.net.stubby.stub.Calls.asyncUnaryCall; +import static com.google.net.stubby.stub.Calls.asyncServerStreamingCall; +import static com.google.net.stubby.stub.Calls.asyncClientStreamingCall; +import static com.google.net.stubby.stub.Calls.duplexStreamingCall; +import static com.google.net.stubby.stub.Calls.blockingUnaryCall; +import static com.google.net.stubby.stub.Calls.blockingServerStreamingCall; +import static com.google.net.stubby.stub.Calls.unaryFutureCall; +import static com.google.net.stubby.stub.ServerCalls.createMethodDefinition; +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 { + + private static final com.google.net.stubby.stub.Method METHOD_HELLO = + com.google.net.stubby.stub.Method.create( + com.google.net.stubby.MethodType.UNARY, "hello", + 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 GreetingsBlockingStub newBlockingStub( + com.google.net.stubby.Channel channel) { + return new GreetingsBlockingStub(channel, CONFIG); + } + + public static GreetingsFutureStub newFutureStub( + com.google.net.stubby.Channel channel) { + return new GreetingsFutureStub(channel, CONFIG); + } + + public static final GreetingsServiceDescriptor CONFIG = + new GreetingsServiceDescriptor(); + + @javax.annotation.concurrent.Immutable + public static class GreetingsServiceDescriptor extends + com.google.net.stubby.stub.AbstractServiceDescriptor { + public final com.google.net.stubby.MethodDescriptor hello; + + private GreetingsServiceDescriptor() { + hello = createMethodDescriptor( + "helloworld.Greetings", METHOD_HELLO); + } + + private GreetingsServiceDescriptor( + java.util.Map> methodMap) { + hello = (com.google.net.stubby.MethodDescriptor) methodMap.get( + CONFIG.hello.getName()); + } + + @java.lang.Override + protected GreetingsServiceDescriptor build( + java.util.Map> methodMap) { + return new GreetingsServiceDescriptor(methodMap); + } + + @java.lang.Override + public com.google.common.collect.ImmutableList> methods() { + return com.google.common.collect.ImmutableList.>of( + hello); + } + } + + public static interface Greetings { + + public void hello(ex.grpc.Helloworld.HelloRequest request, + com.google.net.stubby.stub.StreamObserver responseObserver); + } + + public static interface GreetingsBlockingClient { + + public ex.grpc.Helloworld.HelloReply hello(ex.grpc.Helloworld.HelloRequest request); + } + + public static interface GreetingsFutureClient { + + public com.google.common.util.concurrent.ListenableFuture hello( + ex.grpc.Helloworld.HelloRequest request); + } + + public static class GreetingsStub extends + com.google.net.stubby.stub.AbstractStub + implements Greetings { + private GreetingsStub(com.google.net.stubby.Channel channel, + GreetingsServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected GreetingsStub build(com.google.net.stubby.Channel channel, + GreetingsServiceDescriptor config) { + return new GreetingsStub(channel, config); + } + + @java.lang.Override + public void hello(ex.grpc.Helloworld.HelloRequest request, + com.google.net.stubby.stub.StreamObserver responseObserver) { + asyncUnaryCall( + channel.newCall(config.hello), request, responseObserver); + } + } + + public static class GreetingsBlockingStub extends + com.google.net.stubby.stub.AbstractStub + implements GreetingsBlockingClient { + private GreetingsBlockingStub(com.google.net.stubby.Channel channel, + GreetingsServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected GreetingsBlockingStub build(com.google.net.stubby.Channel channel, + GreetingsServiceDescriptor config) { + return new GreetingsBlockingStub(channel, config); + } + + @java.lang.Override + public ex.grpc.Helloworld.HelloReply hello(ex.grpc.Helloworld.HelloRequest request) { + return blockingUnaryCall( + channel.newCall(config.hello), request); + } + } + + public static class GreetingsFutureStub extends + com.google.net.stubby.stub.AbstractStub + implements GreetingsFutureClient { + private GreetingsFutureStub(com.google.net.stubby.Channel channel, + GreetingsServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected GreetingsFutureStub build(com.google.net.stubby.Channel channel, + GreetingsServiceDescriptor config) { + return new GreetingsFutureStub(channel, config); + } + + @java.lang.Override + public com.google.common.util.concurrent.ListenableFuture hello( + ex.grpc.Helloworld.HelloRequest request) { + return unaryFutureCall( + channel.newCall(config.hello), request); + } + } + + public static com.google.net.stubby.ServerServiceDefinition bindService( + final Greetings serviceImpl) { + return com.google.net.stubby.ServerServiceDefinition.builder("helloworld.Greetings") + .addMethod(createMethodDefinition( + METHOD_HELLO, + asyncUnaryRequestCall( + new com.google.net.stubby.stub.ServerCalls.UnaryRequestMethod< + ex.grpc.Helloworld.HelloRequest, + ex.grpc.Helloworld.HelloReply>() { + @java.lang.Override + public void invoke( + ex.grpc.Helloworld.HelloRequest request, + com.google.net.stubby.stub.StreamObserver responseObserver) { + serviceImpl.hello(request, responseObserver); + } + }))).build(); + } +} diff --git a/java/src/main/java/ex/grpc/GreetingsImpl.java b/java/src/main/java/ex/grpc/GreetingsImpl.java new file mode 100644 index 0000000000..005489acaa --- /dev/null +++ b/java/src/main/java/ex/grpc/GreetingsImpl.java @@ -0,0 +1,16 @@ +package ex.grpc; + +import com.google.net.stubby.stub.StreamObserver; + +public class GreetingsImpl implements GreetingsGrpc.Greetings { + + @Override + public void hello(Helloworld.HelloRequest req, + StreamObserver responseObserver) { + Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( + "Hello " + req.getName()).build(); + responseObserver.onValue(reply); + responseObserver.onCompleted(); + } + +} diff --git a/java/src/main/java/ex/grpc/GreetingsServer.java b/java/src/main/java/ex/grpc/GreetingsServer.java new file mode 100644 index 0000000000..834ae985a4 --- /dev/null +++ b/java/src/main/java/ex/grpc/GreetingsServer.java @@ -0,0 +1,51 @@ +package ex.grpc; + +import com.google.common.util.concurrent.MoreExecutors; +import com.google.net.stubby.ServerImpl; +import com.google.net.stubby.transport.netty.NettyServerBuilder; + +import java.util.concurrent.TimeUnit; + +/** + * Server that manages startup/shutdown of a {@code Greetings} server. + */ +public class GreetingsServer { + /* 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())) + .build(); + server.startAsync(); + server.awaitRunning(5, TimeUnit.SECONDS); + System.out.println("Server started on port:" + port); + } + + private void stop() throws Exception { + server.stopAsync(); + server.awaitTerminated(); + System.out.println("Server shutting down ..."); + } + + /** + * Main launches the server from the command line. + */ + public static void main(String[] args) throws Exception { + final GreetingsServer server = new GreetingsServer(); + + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + try { + System.out.println("Shutting down"); + server.stop(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + server.start(); + } +} diff --git a/java/src/main/java/ex/grpc/Helloworld.java b/java/src/main/java/ex/grpc/Helloworld.java new file mode 100644 index 0000000000..f72040fa2b --- /dev/null +++ b/java/src/main/java/ex/grpc/Helloworld.java @@ -0,0 +1,951 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: src/main/proto/helloworld.proto + +package ex.grpc; + +public final class Helloworld { + private Helloworld() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + } + public interface HelloRequestOrBuilder extends + // @@protoc_insertion_point(interface_extends:helloworld.HelloRequest) + com.google.protobuf.MessageOrBuilder { + + /** + * optional string name = 1; + */ + java.lang.String getName(); + /** + * optional string name = 1; + */ + com.google.protobuf.ByteString + getNameBytes(); + } + /** + * Protobuf type {@code helloworld.HelloRequest} + * + *
+   * The request message containing the user's name.
+   * 
+ */ + public static final class HelloRequest extends + com.google.protobuf.GeneratedMessage implements + // @@protoc_insertion_point(message_implements:helloworld.HelloRequest) + HelloRequestOrBuilder { + // Use HelloRequest.newBuilder() to construct. + private HelloRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + } + private HelloRequest() { + name_ = ""; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return com.google.protobuf.UnknownFieldSet.getDefaultInstance(); + } + private HelloRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + int mutable_bitField0_ = 0; + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!input.skipField(tag)) { + done = true; + } + break; + } + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + + name_ = bs; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ex.grpc.Helloworld.HelloRequest.class, ex.grpc.Helloworld.HelloRequest.Builder.class); + } + + public static final com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public HelloRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new HelloRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public static final int NAME_FIELD_NUMBER = 1; + private java.lang.Object name_; + /** + * optional string name = 1; + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + /** + * optional string name = 1; + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (!getNameBytes().isEmpty()) { + output.writeBytes(1, getNameBytes()); + } + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (!getNameBytes().isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getNameBytes()); + } + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + public static ex.grpc.Helloworld.HelloRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ex.grpc.Helloworld.HelloRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ex.grpc.Helloworld.HelloRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static ex.grpc.Helloworld.HelloRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static ex.grpc.Helloworld.HelloRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static ex.grpc.Helloworld.HelloRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return new Builder(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(ex.grpc.Helloworld.HelloRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code helloworld.HelloRequest} + * + *
+     * The request message containing the user's name.
+     * 
+ */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder implements + // @@protoc_insertion_point(builder_implements:helloworld.HelloRequest) + ex.grpc.Helloworld.HelloRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ex.grpc.Helloworld.HelloRequest.class, ex.grpc.Helloworld.HelloRequest.Builder.class); + } + + // Construct using ex.grpc.Helloworld.HelloRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + public Builder clear() { + super.clear(); + name_ = ""; + + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_descriptor; + } + + public ex.grpc.Helloworld.HelloRequest getDefaultInstanceForType() { + return ex.grpc.Helloworld.HelloRequest.getDefaultInstance(); + } + + public ex.grpc.Helloworld.HelloRequest build() { + ex.grpc.Helloworld.HelloRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public ex.grpc.Helloworld.HelloRequest buildPartial() { + ex.grpc.Helloworld.HelloRequest result = new ex.grpc.Helloworld.HelloRequest(this); + result.name_ = name_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ex.grpc.Helloworld.HelloRequest) { + return mergeFrom((ex.grpc.Helloworld.HelloRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ex.grpc.Helloworld.HelloRequest other) { + if (other == ex.grpc.Helloworld.HelloRequest.getDefaultInstance()) return this; + if (!other.getName().isEmpty()) { + name_ = other.name_; + onChanged(); + } + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ex.grpc.Helloworld.HelloRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ex.grpc.Helloworld.HelloRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object name_ = ""; + /** + * optional string name = 1; + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string name = 1; + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string name = 1; + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + name_ = value; + onChanged(); + return this; + } + /** + * optional string name = 1; + */ + public Builder clearName() { + + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * optional string name = 1; + */ + public Builder setNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + name_ = value; + onChanged(); + return this; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + + // @@protoc_insertion_point(builder_scope:helloworld.HelloRequest) + } + + // @@protoc_insertion_point(class_scope:helloworld.HelloRequest) + private static final ex.grpc.Helloworld.HelloRequest defaultInstance;static { + defaultInstance = new ex.grpc.Helloworld.HelloRequest(); + } + + public static ex.grpc.Helloworld.HelloRequest getDefaultInstance() { + return defaultInstance; + } + + public ex.grpc.Helloworld.HelloRequest getDefaultInstanceForType() { + return defaultInstance; + } + + } + + public interface HelloReplyOrBuilder extends + // @@protoc_insertion_point(interface_extends:helloworld.HelloReply) + com.google.protobuf.MessageOrBuilder { + + /** + * optional string message = 1; + */ + java.lang.String getMessage(); + /** + * optional string message = 1; + */ + com.google.protobuf.ByteString + getMessageBytes(); + } + /** + * Protobuf type {@code helloworld.HelloReply} + * + *
+   * The response message containing the greetings
+   * 
+ */ + public static final class HelloReply extends + com.google.protobuf.GeneratedMessage implements + // @@protoc_insertion_point(message_implements:helloworld.HelloReply) + HelloReplyOrBuilder { + // Use HelloReply.newBuilder() to construct. + private HelloReply(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + } + private HelloReply() { + message_ = ""; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return com.google.protobuf.UnknownFieldSet.getDefaultInstance(); + } + private HelloReply( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + int mutable_bitField0_ = 0; + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!input.skipField(tag)) { + done = true; + } + break; + } + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + + message_ = bs; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ex.grpc.Helloworld.HelloReply.class, ex.grpc.Helloworld.HelloReply.Builder.class); + } + + public static final com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public HelloReply parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new HelloReply(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public static final int MESSAGE_FIELD_NUMBER = 1; + private java.lang.Object message_; + /** + * optional string message = 1; + */ + public java.lang.String getMessage() { + java.lang.Object ref = message_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + message_ = s; + } + return s; + } + } + /** + * optional string message = 1; + */ + public com.google.protobuf.ByteString + getMessageBytes() { + java.lang.Object ref = message_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + message_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (!getMessageBytes().isEmpty()) { + output.writeBytes(1, getMessageBytes()); + } + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (!getMessageBytes().isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getMessageBytes()); + } + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + public static ex.grpc.Helloworld.HelloReply parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ex.grpc.Helloworld.HelloReply parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloReply parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ex.grpc.Helloworld.HelloReply parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloReply parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static ex.grpc.Helloworld.HelloReply parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloReply parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static ex.grpc.Helloworld.HelloReply parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static ex.grpc.Helloworld.HelloReply parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static ex.grpc.Helloworld.HelloReply parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return new Builder(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(ex.grpc.Helloworld.HelloReply prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code helloworld.HelloReply} + * + *
+     * The response message containing the greetings
+     * 
+ */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder implements + // @@protoc_insertion_point(builder_implements:helloworld.HelloReply) + ex.grpc.Helloworld.HelloReplyOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ex.grpc.Helloworld.HelloReply.class, ex.grpc.Helloworld.HelloReply.Builder.class); + } + + // Construct using ex.grpc.Helloworld.HelloReply.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + public Builder clear() { + super.clear(); + message_ = ""; + + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_descriptor; + } + + public ex.grpc.Helloworld.HelloReply getDefaultInstanceForType() { + return ex.grpc.Helloworld.HelloReply.getDefaultInstance(); + } + + public ex.grpc.Helloworld.HelloReply build() { + ex.grpc.Helloworld.HelloReply result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public ex.grpc.Helloworld.HelloReply buildPartial() { + ex.grpc.Helloworld.HelloReply result = new ex.grpc.Helloworld.HelloReply(this); + result.message_ = message_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ex.grpc.Helloworld.HelloReply) { + return mergeFrom((ex.grpc.Helloworld.HelloReply)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ex.grpc.Helloworld.HelloReply other) { + if (other == ex.grpc.Helloworld.HelloReply.getDefaultInstance()) return this; + if (!other.getMessage().isEmpty()) { + message_ = other.message_; + onChanged(); + } + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ex.grpc.Helloworld.HelloReply parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ex.grpc.Helloworld.HelloReply) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object message_ = ""; + /** + * optional string message = 1; + */ + public java.lang.String getMessage() { + java.lang.Object ref = message_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + message_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string message = 1; + */ + public com.google.protobuf.ByteString + getMessageBytes() { + java.lang.Object ref = message_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + message_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string message = 1; + */ + public Builder setMessage( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + message_ = value; + onChanged(); + return this; + } + /** + * optional string message = 1; + */ + public Builder clearMessage() { + + message_ = getDefaultInstance().getMessage(); + onChanged(); + return this; + } + /** + * optional string message = 1; + */ + public Builder setMessageBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + message_ = value; + onChanged(); + return this; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + + // @@protoc_insertion_point(builder_scope:helloworld.HelloReply) + } + + // @@protoc_insertion_point(class_scope:helloworld.HelloReply) + private static final ex.grpc.Helloworld.HelloReply defaultInstance;static { + defaultInstance = new ex.grpc.Helloworld.HelloReply(); + } + + public static ex.grpc.Helloworld.HelloReply getDefaultInstance() { + return defaultInstance; + } + + public ex.grpc.Helloworld.HelloReply getDefaultInstanceForType() { + return defaultInstance; + } + + } + + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_helloworld_HelloRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_helloworld_HelloRequest_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_helloworld_HelloReply_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_helloworld_HelloReply_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + 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" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }, assigner); + internal_static_helloworld_HelloRequest_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_helloworld_HelloRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_helloworld_HelloRequest_descriptor, + new java.lang.String[] { "Name", }); + internal_static_helloworld_HelloReply_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_helloworld_HelloReply_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_helloworld_HelloReply_descriptor, + new java.lang.String[] { "Message", }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/java/src/main/proto/helloworld.proto b/java/src/main/proto/helloworld.proto new file mode 100644 index 0000000000..da5c3a1d85 --- /dev/null +++ b/java/src/main/proto/helloworld.proto @@ -0,0 +1,22 @@ +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/pom.xml b/pom.xml deleted file mode 100644 index da0ee205f7..0000000000 --- a/pom.xml +++ /dev/null @@ -1,105 +0,0 @@ - - 4.0.0 - - - com.google.net.stubby - stubby-parent - 0.1.0-SNAPSHOT - - - grpc-hello-world - jar - - Hello gRPC World - - - - ${project.groupId} - stubby-core - ${project.version} - - - ${project.groupId} - stubby-netty - ${project.version} - - - ${project.groupId} - stubby-okhttp - ${project.version} - - - ${project.groupId} - stubby-stub - ${project.version} - - - ${project.groupId} - stubby-testing - ${project.version} - - - junit - junit - compile - - - org.mockito - mockito-core - compile - - - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - assemble-all - package - - single - - - - - - jar-with-dependencies - - - - - - com.internetitem - write-properties-file-maven-plugin - - - bootclasspath - prepare-package - - write-properties-file - - - bootclasspath.properties - ${project.build.directory} - - - bootclasspath - ${argLine.bootcp} - - - jar - ${project.build.directory}/${project.artifactId}-${project.version}-jar-with-dependencies.jar - - - - - - - - - diff --git a/run_greetings_client.sh b/run_greetings_client.sh deleted file mode 100755 index 8155589adf..0000000000 --- a/run_greetings_client.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -e -TARGET='Greetings Client' -TARGET_CLASS='ex.grpc.GreetingsClient' -TARGET_ARGS="$@" - -cd "$(dirname "$0")" -mvn -q -nsu -am package -Dcheckstyle.skip=true -DskipTests -. target/bootclasspath.properties -echo "[INFO] Running: $TARGET ($TARGET_CLASS $TARGET_ARGS)" -exec java "$bootclasspath" -cp "$jar" "$TARGET_CLASS" $TARGET_ARGS diff --git a/run_greetings_server.sh b/run_greetings_server.sh deleted file mode 100755 index 248229e129..0000000000 --- a/run_greetings_server.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -e -TARGET='Greetings Server' -TARGET_CLASS='ex.grpc.GreetingsServer' - -cd "$(dirname "$0")" -mvn -q -nsu -am package -Dcheckstyle.skip=true -DskipTests -. target/bootclasspath.properties -echo "[INFO] Running: $TARGET ($TARGET_CLASS)" -exec java "$bootclasspath" -cp "$jar" "$TARGET_CLASS" diff --git a/src/main/java/ex/grpc/GreetingsClient.java b/src/main/java/ex/grpc/GreetingsClient.java deleted file mode 100644 index 4ae2e7076b..0000000000 --- a/src/main/java/ex/grpc/GreetingsClient.java +++ /dev/null @@ -1,55 +0,0 @@ -package ex.grpc; - -import com.google.net.stubby.ChannelImpl; -import com.google.net.stubby.stub.StreamObserver; -import com.google.net.stubby.transport.netty.NegotiationType; -import com.google.net.stubby.transport.netty.NettyChannelBuilder; - -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.concurrent.TimeUnit; - -public class GreetingsClient { - private final Logger logger = Logger.getLogger( - GreetingsClient.class.getName()); - private final ChannelImpl channel; - private final GreetingsGrpc.GreetingsBlockingStub blockingStub; - - public GreetingsClient(String host, int port) { - channel = NettyChannelBuilder.forAddress(host, port) - .negotiationType(NegotiationType.PLAINTEXT) - .build(); - blockingStub = GreetingsGrpc.newBlockingStub(channel); - } - - public void shutdown() throws InterruptedException { - channel.shutdown().awaitTerminated(5, TimeUnit.SECONDS); - } - - public void greet(String name) { - try { - logger.fine("Will try to greet " + name + " ..."); - Helloworld.HelloRequest req = - Helloworld.HelloRequest.newBuilder().setName(name).build(); - Helloworld.HelloReply reply = blockingStub.hello(req); - logger.info("Greeting: " + reply.getMessage()); - } catch (RuntimeException e) { - logger.log(Level.WARNING, "RPC failed", e); - return; - } - } - - public static void main(String[] args) throws Exception { - GreetingsClient client = new GreetingsClient("localhost", 50051); - try { - /* Access a service running on the local machine on port 50051 */ - String user = "world"; - if (args.length > 0) { - user = args[0]; /* Use the arg as the name to greet if provided */ - } - client.greet(user); - } finally { - client.shutdown(); - } - } -} diff --git a/src/main/java/ex/grpc/GreetingsGrpc.java b/src/main/java/ex/grpc/GreetingsGrpc.java deleted file mode 100644 index 97c2f00a1e..0000000000 --- a/src/main/java/ex/grpc/GreetingsGrpc.java +++ /dev/null @@ -1,172 +0,0 @@ -package ex.grpc; - -import static com.google.net.stubby.stub.Calls.createMethodDescriptor; -import static com.google.net.stubby.stub.Calls.asyncUnaryCall; -import static com.google.net.stubby.stub.Calls.asyncServerStreamingCall; -import static com.google.net.stubby.stub.Calls.asyncClientStreamingCall; -import static com.google.net.stubby.stub.Calls.duplexStreamingCall; -import static com.google.net.stubby.stub.Calls.blockingUnaryCall; -import static com.google.net.stubby.stub.Calls.blockingServerStreamingCall; -import static com.google.net.stubby.stub.Calls.unaryFutureCall; -import static com.google.net.stubby.stub.ServerCalls.createMethodDefinition; -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 { - - private static final com.google.net.stubby.stub.Method METHOD_HELLO = - com.google.net.stubby.stub.Method.create( - com.google.net.stubby.MethodType.UNARY, "hello", - 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 GreetingsBlockingStub newBlockingStub( - com.google.net.stubby.Channel channel) { - return new GreetingsBlockingStub(channel, CONFIG); - } - - public static GreetingsFutureStub newFutureStub( - com.google.net.stubby.Channel channel) { - return new GreetingsFutureStub(channel, CONFIG); - } - - public static final GreetingsServiceDescriptor CONFIG = - new GreetingsServiceDescriptor(); - - @javax.annotation.concurrent.Immutable - public static class GreetingsServiceDescriptor extends - com.google.net.stubby.stub.AbstractServiceDescriptor { - public final com.google.net.stubby.MethodDescriptor hello; - - private GreetingsServiceDescriptor() { - hello = createMethodDescriptor( - "helloworld.Greetings", METHOD_HELLO); - } - - private GreetingsServiceDescriptor( - java.util.Map> methodMap) { - hello = (com.google.net.stubby.MethodDescriptor) methodMap.get( - CONFIG.hello.getName()); - } - - @java.lang.Override - protected GreetingsServiceDescriptor build( - java.util.Map> methodMap) { - return new GreetingsServiceDescriptor(methodMap); - } - - @java.lang.Override - public com.google.common.collect.ImmutableList> methods() { - return com.google.common.collect.ImmutableList.>of( - hello); - } - } - - public static interface Greetings { - - public void hello(ex.grpc.Helloworld.HelloRequest request, - com.google.net.stubby.stub.StreamObserver responseObserver); - } - - public static interface GreetingsBlockingClient { - - public ex.grpc.Helloworld.HelloReply hello(ex.grpc.Helloworld.HelloRequest request); - } - - public static interface GreetingsFutureClient { - - public com.google.common.util.concurrent.ListenableFuture hello( - ex.grpc.Helloworld.HelloRequest request); - } - - public static class GreetingsStub extends - com.google.net.stubby.stub.AbstractStub - implements Greetings { - private GreetingsStub(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { - super(channel, config); - } - - @java.lang.Override - protected GreetingsStub build(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { - return new GreetingsStub(channel, config); - } - - @java.lang.Override - public void hello(ex.grpc.Helloworld.HelloRequest request, - com.google.net.stubby.stub.StreamObserver responseObserver) { - asyncUnaryCall( - channel.newCall(config.hello), request, responseObserver); - } - } - - public static class GreetingsBlockingStub extends - com.google.net.stubby.stub.AbstractStub - implements GreetingsBlockingClient { - private GreetingsBlockingStub(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { - super(channel, config); - } - - @java.lang.Override - protected GreetingsBlockingStub build(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { - return new GreetingsBlockingStub(channel, config); - } - - @java.lang.Override - public ex.grpc.Helloworld.HelloReply hello(ex.grpc.Helloworld.HelloRequest request) { - return blockingUnaryCall( - channel.newCall(config.hello), request); - } - } - - public static class GreetingsFutureStub extends - com.google.net.stubby.stub.AbstractStub - implements GreetingsFutureClient { - private GreetingsFutureStub(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { - super(channel, config); - } - - @java.lang.Override - protected GreetingsFutureStub build(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { - return new GreetingsFutureStub(channel, config); - } - - @java.lang.Override - public com.google.common.util.concurrent.ListenableFuture hello( - ex.grpc.Helloworld.HelloRequest request) { - return unaryFutureCall( - channel.newCall(config.hello), request); - } - } - - public static com.google.net.stubby.ServerServiceDefinition bindService( - final Greetings serviceImpl) { - return com.google.net.stubby.ServerServiceDefinition.builder("helloworld.Greetings") - .addMethod(createMethodDefinition( - METHOD_HELLO, - asyncUnaryRequestCall( - new com.google.net.stubby.stub.ServerCalls.UnaryRequestMethod< - ex.grpc.Helloworld.HelloRequest, - ex.grpc.Helloworld.HelloReply>() { - @java.lang.Override - public void invoke( - ex.grpc.Helloworld.HelloRequest request, - com.google.net.stubby.stub.StreamObserver responseObserver) { - serviceImpl.hello(request, responseObserver); - } - }))).build(); - } -} diff --git a/src/main/java/ex/grpc/GreetingsImpl.java b/src/main/java/ex/grpc/GreetingsImpl.java deleted file mode 100644 index 005489acaa..0000000000 --- a/src/main/java/ex/grpc/GreetingsImpl.java +++ /dev/null @@ -1,16 +0,0 @@ -package ex.grpc; - -import com.google.net.stubby.stub.StreamObserver; - -public class GreetingsImpl implements GreetingsGrpc.Greetings { - - @Override - public void hello(Helloworld.HelloRequest req, - StreamObserver responseObserver) { - Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( - "Hello " + req.getName()).build(); - responseObserver.onValue(reply); - responseObserver.onCompleted(); - } - -} diff --git a/src/main/java/ex/grpc/GreetingsServer.java b/src/main/java/ex/grpc/GreetingsServer.java deleted file mode 100644 index 834ae985a4..0000000000 --- a/src/main/java/ex/grpc/GreetingsServer.java +++ /dev/null @@ -1,51 +0,0 @@ -package ex.grpc; - -import com.google.common.util.concurrent.MoreExecutors; -import com.google.net.stubby.ServerImpl; -import com.google.net.stubby.transport.netty.NettyServerBuilder; - -import java.util.concurrent.TimeUnit; - -/** - * Server that manages startup/shutdown of a {@code Greetings} server. - */ -public class GreetingsServer { - /* 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())) - .build(); - server.startAsync(); - server.awaitRunning(5, TimeUnit.SECONDS); - System.out.println("Server started on port:" + port); - } - - private void stop() throws Exception { - server.stopAsync(); - server.awaitTerminated(); - System.out.println("Server shutting down ..."); - } - - /** - * Main launches the server from the command line. - */ - public static void main(String[] args) throws Exception { - final GreetingsServer server = new GreetingsServer(); - - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - try { - System.out.println("Shutting down"); - server.stop(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - server.start(); - } -} diff --git a/src/main/java/ex/grpc/Helloworld.java b/src/main/java/ex/grpc/Helloworld.java deleted file mode 100644 index f72040fa2b..0000000000 --- a/src/main/java/ex/grpc/Helloworld.java +++ /dev/null @@ -1,951 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: src/main/proto/helloworld.proto - -package ex.grpc; - -public final class Helloworld { - private Helloworld() {} - public static void registerAllExtensions( - com.google.protobuf.ExtensionRegistry registry) { - } - public interface HelloRequestOrBuilder extends - // @@protoc_insertion_point(interface_extends:helloworld.HelloRequest) - com.google.protobuf.MessageOrBuilder { - - /** - * optional string name = 1; - */ - java.lang.String getName(); - /** - * optional string name = 1; - */ - com.google.protobuf.ByteString - getNameBytes(); - } - /** - * Protobuf type {@code helloworld.HelloRequest} - * - *
-   * The request message containing the user's name.
-   * 
- */ - public static final class HelloRequest extends - com.google.protobuf.GeneratedMessage implements - // @@protoc_insertion_point(message_implements:helloworld.HelloRequest) - HelloRequestOrBuilder { - // Use HelloRequest.newBuilder() to construct. - private HelloRequest(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - } - private HelloRequest() { - name_ = ""; - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return com.google.protobuf.UnknownFieldSet.getDefaultInstance(); - } - private HelloRequest( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - int mutable_bitField0_ = 0; - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!input.skipField(tag)) { - done = true; - } - break; - } - case 10: { - com.google.protobuf.ByteString bs = input.readBytes(); - - name_ = bs; - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ex.grpc.Helloworld.HelloRequest.class, ex.grpc.Helloworld.HelloRequest.Builder.class); - } - - public static final com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public HelloRequest parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new HelloRequest(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - public static final int NAME_FIELD_NUMBER = 1; - private java.lang.Object name_; - /** - * optional string name = 1; - */ - public java.lang.String getName() { - java.lang.Object ref = name_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - name_ = s; - } - return s; - } - } - /** - * optional string name = 1; - */ - public com.google.protobuf.ByteString - getNameBytes() { - java.lang.Object ref = name_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - name_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (!getNameBytes().isEmpty()) { - output.writeBytes(1, getNameBytes()); - } - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (!getNameBytes().isEmpty()) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, getNameBytes()); - } - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - public static ex.grpc.Helloworld.HelloRequest parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ex.grpc.Helloworld.HelloRequest parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloRequest parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ex.grpc.Helloworld.HelloRequest parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloRequest parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static ex.grpc.Helloworld.HelloRequest parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloRequest parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static ex.grpc.Helloworld.HelloRequest parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloRequest parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static ex.grpc.Helloworld.HelloRequest parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return new Builder(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(ex.grpc.Helloworld.HelloRequest prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code helloworld.HelloRequest} - * - *
-     * The request message containing the user's name.
-     * 
- */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder implements - // @@protoc_insertion_point(builder_implements:helloworld.HelloRequest) - ex.grpc.Helloworld.HelloRequestOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ex.grpc.Helloworld.HelloRequest.class, ex.grpc.Helloworld.HelloRequest.Builder.class); - } - - // Construct using ex.grpc.Helloworld.HelloRequest.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - } - } - public Builder clear() { - super.clear(); - name_ = ""; - - return this; - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_descriptor; - } - - public ex.grpc.Helloworld.HelloRequest getDefaultInstanceForType() { - return ex.grpc.Helloworld.HelloRequest.getDefaultInstance(); - } - - public ex.grpc.Helloworld.HelloRequest build() { - ex.grpc.Helloworld.HelloRequest result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public ex.grpc.Helloworld.HelloRequest buildPartial() { - ex.grpc.Helloworld.HelloRequest result = new ex.grpc.Helloworld.HelloRequest(this); - result.name_ = name_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ex.grpc.Helloworld.HelloRequest) { - return mergeFrom((ex.grpc.Helloworld.HelloRequest)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(ex.grpc.Helloworld.HelloRequest other) { - if (other == ex.grpc.Helloworld.HelloRequest.getDefaultInstance()) return this; - if (!other.getName().isEmpty()) { - name_ = other.name_; - onChanged(); - } - onChanged(); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - ex.grpc.Helloworld.HelloRequest parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ex.grpc.Helloworld.HelloRequest) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - - private java.lang.Object name_ = ""; - /** - * optional string name = 1; - */ - public java.lang.String getName() { - java.lang.Object ref = name_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - name_ = s; - } - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string name = 1; - */ - public com.google.protobuf.ByteString - getNameBytes() { - java.lang.Object ref = name_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - name_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string name = 1; - */ - public Builder setName( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - - name_ = value; - onChanged(); - return this; - } - /** - * optional string name = 1; - */ - public Builder clearName() { - - name_ = getDefaultInstance().getName(); - onChanged(); - return this; - } - /** - * optional string name = 1; - */ - public Builder setNameBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - - name_ = value; - onChanged(); - return this; - } - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return this; - } - - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return this; - } - - - // @@protoc_insertion_point(builder_scope:helloworld.HelloRequest) - } - - // @@protoc_insertion_point(class_scope:helloworld.HelloRequest) - private static final ex.grpc.Helloworld.HelloRequest defaultInstance;static { - defaultInstance = new ex.grpc.Helloworld.HelloRequest(); - } - - public static ex.grpc.Helloworld.HelloRequest getDefaultInstance() { - return defaultInstance; - } - - public ex.grpc.Helloworld.HelloRequest getDefaultInstanceForType() { - return defaultInstance; - } - - } - - public interface HelloReplyOrBuilder extends - // @@protoc_insertion_point(interface_extends:helloworld.HelloReply) - com.google.protobuf.MessageOrBuilder { - - /** - * optional string message = 1; - */ - java.lang.String getMessage(); - /** - * optional string message = 1; - */ - com.google.protobuf.ByteString - getMessageBytes(); - } - /** - * Protobuf type {@code helloworld.HelloReply} - * - *
-   * The response message containing the greetings
-   * 
- */ - public static final class HelloReply extends - com.google.protobuf.GeneratedMessage implements - // @@protoc_insertion_point(message_implements:helloworld.HelloReply) - HelloReplyOrBuilder { - // Use HelloReply.newBuilder() to construct. - private HelloReply(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - } - private HelloReply() { - message_ = ""; - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return com.google.protobuf.UnknownFieldSet.getDefaultInstance(); - } - private HelloReply( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - int mutable_bitField0_ = 0; - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!input.skipField(tag)) { - done = true; - } - break; - } - case 10: { - com.google.protobuf.ByteString bs = input.readBytes(); - - message_ = bs; - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ex.grpc.Helloworld.HelloReply.class, ex.grpc.Helloworld.HelloReply.Builder.class); - } - - public static final com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public HelloReply parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new HelloReply(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - public static final int MESSAGE_FIELD_NUMBER = 1; - private java.lang.Object message_; - /** - * optional string message = 1; - */ - public java.lang.String getMessage() { - java.lang.Object ref = message_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - message_ = s; - } - return s; - } - } - /** - * optional string message = 1; - */ - public com.google.protobuf.ByteString - getMessageBytes() { - java.lang.Object ref = message_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - message_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (!getMessageBytes().isEmpty()) { - output.writeBytes(1, getMessageBytes()); - } - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (!getMessageBytes().isEmpty()) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, getMessageBytes()); - } - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - public static ex.grpc.Helloworld.HelloReply parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ex.grpc.Helloworld.HelloReply parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloReply parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ex.grpc.Helloworld.HelloReply parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloReply parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static ex.grpc.Helloworld.HelloReply parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloReply parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static ex.grpc.Helloworld.HelloReply parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloReply parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static ex.grpc.Helloworld.HelloReply parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return new Builder(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(ex.grpc.Helloworld.HelloReply prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code helloworld.HelloReply} - * - *
-     * The response message containing the greetings
-     * 
- */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder implements - // @@protoc_insertion_point(builder_implements:helloworld.HelloReply) - ex.grpc.Helloworld.HelloReplyOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ex.grpc.Helloworld.HelloReply.class, ex.grpc.Helloworld.HelloReply.Builder.class); - } - - // Construct using ex.grpc.Helloworld.HelloReply.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - } - } - public Builder clear() { - super.clear(); - message_ = ""; - - return this; - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_descriptor; - } - - public ex.grpc.Helloworld.HelloReply getDefaultInstanceForType() { - return ex.grpc.Helloworld.HelloReply.getDefaultInstance(); - } - - public ex.grpc.Helloworld.HelloReply build() { - ex.grpc.Helloworld.HelloReply result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public ex.grpc.Helloworld.HelloReply buildPartial() { - ex.grpc.Helloworld.HelloReply result = new ex.grpc.Helloworld.HelloReply(this); - result.message_ = message_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ex.grpc.Helloworld.HelloReply) { - return mergeFrom((ex.grpc.Helloworld.HelloReply)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(ex.grpc.Helloworld.HelloReply other) { - if (other == ex.grpc.Helloworld.HelloReply.getDefaultInstance()) return this; - if (!other.getMessage().isEmpty()) { - message_ = other.message_; - onChanged(); - } - onChanged(); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - ex.grpc.Helloworld.HelloReply parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ex.grpc.Helloworld.HelloReply) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - - private java.lang.Object message_ = ""; - /** - * optional string message = 1; - */ - public java.lang.String getMessage() { - java.lang.Object ref = message_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - message_ = s; - } - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string message = 1; - */ - public com.google.protobuf.ByteString - getMessageBytes() { - java.lang.Object ref = message_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - message_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string message = 1; - */ - public Builder setMessage( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - - message_ = value; - onChanged(); - return this; - } - /** - * optional string message = 1; - */ - public Builder clearMessage() { - - message_ = getDefaultInstance().getMessage(); - onChanged(); - return this; - } - /** - * optional string message = 1; - */ - public Builder setMessageBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - - message_ = value; - onChanged(); - return this; - } - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return this; - } - - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return this; - } - - - // @@protoc_insertion_point(builder_scope:helloworld.HelloReply) - } - - // @@protoc_insertion_point(class_scope:helloworld.HelloReply) - private static final ex.grpc.Helloworld.HelloReply defaultInstance;static { - defaultInstance = new ex.grpc.Helloworld.HelloReply(); - } - - public static ex.grpc.Helloworld.HelloReply getDefaultInstance() { - return defaultInstance; - } - - public ex.grpc.Helloworld.HelloReply getDefaultInstanceForType() { - return defaultInstance; - } - - } - - private static final com.google.protobuf.Descriptors.Descriptor - internal_static_helloworld_HelloRequest_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_helloworld_HelloRequest_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor - internal_static_helloworld_HelloReply_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_helloworld_HelloReply_fieldAccessorTable; - - public static com.google.protobuf.Descriptors.FileDescriptor - getDescriptor() { - return descriptor; - } - private static com.google.protobuf.Descriptors.FileDescriptor - 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" - }; - com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = - new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { - public com.google.protobuf.ExtensionRegistry assignDescriptors( - com.google.protobuf.Descriptors.FileDescriptor root) { - descriptor = root; - return null; - } - }; - com.google.protobuf.Descriptors.FileDescriptor - .internalBuildGeneratedFileFrom(descriptorData, - new com.google.protobuf.Descriptors.FileDescriptor[] { - }, assigner); - internal_static_helloworld_HelloRequest_descriptor = - getDescriptor().getMessageTypes().get(0); - internal_static_helloworld_HelloRequest_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_helloworld_HelloRequest_descriptor, - new java.lang.String[] { "Name", }); - internal_static_helloworld_HelloReply_descriptor = - getDescriptor().getMessageTypes().get(1); - internal_static_helloworld_HelloReply_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_helloworld_HelloReply_descriptor, - new java.lang.String[] { "Message", }); - } - - // @@protoc_insertion_point(outer_class_scope) -} diff --git a/src/main/proto/helloworld.proto b/src/main/proto/helloworld.proto deleted file mode 100644 index da5c3a1d85..0000000000 --- a/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) { - } -} -- cgit v1.2.3 From c509d3545531f1424335123670c9bcf9ca5ba934 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 6 Feb 2015 13:21:36 -0800 Subject: Updates the references to the moved java source files. - Also specifies the what type of source is being rendered in the syntax-highlighted sections --- Step_1.md | 9 ++++----- Step_2.md | 2 +- Step_3.md | 23 ++++++++++++----------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Step_1.md b/Step_1.md index c7aed326c3..1e9ca2b2a5 100644 --- a/Step_1.md +++ b/Step_1.md @@ -15,18 +15,17 @@ The gRPC Java Stub classes are created using a gRPC Java plugin, but first the plugin must be built and installed. To build the plugin: -``` +```sh $ pushd external/grpc_java $ make java_plugin $ popd ``` To use it to generate the code: -``` -$ mkdir -p src/main/java +```sh $ protoc -I . helloworld.proto --plugin=protoc-gen-grpc=external/grpc_java/bins/opt/java_plugin \ - --grpc_out=src/main/java \ - --java_out=src/main/java + --grpc_out=java/src/main/java \ + --java_out=java/src/main/java ``` Next, in [Step - 2](Step_2.md), we'll use the generated Stub implementation to diff --git a/Step_2.md b/Step_2.md index eafe70b692..d2e1ae48b0 100644 --- a/Step_2.md +++ b/Step_2.md @@ -1,7 +1,7 @@ # Step-2: Write a service client. This step uses the generated code to write a simple client to access the hello -service. The full client is in [GreetingsClient.java](src/main/java/ex/grpc/GreetingsClient.java). +service. The full client is in [GreetingsClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). ## Configuring the service to connect to. diff --git a/Step_3.md b/Step_3.md index 7b03cdf585..9eb1009d2e 100644 --- a/Step_3.md +++ b/Step_3.md @@ -3,17 +3,17 @@ This step extends the generated server skeleton code to write a simple server that provides the hello service. This introduces two new classes: -- a service implementation [GreetingsImpl.java](src/main/java/ex/grpc/GreetingsImpl.java). +- a service implementation [GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java). -- a server that hosts the service implementation and allows access over the network: [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java). +- a server that hosts the service implementation and allows access over the network: [GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java). ## Service implementation -[GreetingsImpl.java](src/main/java/ex/grpc/GreetingsImpl.java) +[GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java) implements the behaviour we require of our GreetingService. There are a number of important features of gRPC being used here: -``` +```java public void hello(Helloworld.HelloRequest req, StreamObserver responseObserver) { Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( @@ -24,7 +24,7 @@ number of important features of gRPC being used here: ``` - it provides a class `GreetingsImpl` that implements a generated interface `GreetingsGrpc.Greetings` -- `GreetingsGrpc.Greetings` declares the method `hello` that was declared in the proto [IDL](src/main/proto/helloworld.proto) +- `GreetingsGrpc.Greetings` declares the method `hello` that was declared in the proto [IDL](java/src/main/proto/helloworld.proto) - `hello's` signature is typesafe: hello(Helloworld.HelloRequest req, StreamObserver responseObserver) - `hello` takes two parameters: @@ -38,11 +38,11 @@ number of important features of gRPC being used here: ## Server implementation -[GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java) shows the +[GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) shows the other main feature required to provde the gRPC service; how to allow a service implementation to be accessed from the network. -``` +```java private void start() throws Exception { server = NettyServerBuilder.forPort(port) .addService(GreetingsGrpc.bindService(new GreetingsImpl())) @@ -62,7 +62,8 @@ implementation to be accessed from the network. This is the same as before: our client and server are part of the same maven package so the same command builds both. -``` +```sh +$ cd java $ mvn package ``` @@ -71,12 +72,12 @@ $ mvn package We've added simple shell scripts to simplifying running the examples. Now that they are built, you can run the server with: -``` +```sh $ ./run_greetings_server.sh ``` and in another terminal window confirm that it receives a message. -``` -$ ./run_greetings_client.sh +```sh +$ ./java/run_greetings_client.sh ``` -- cgit v1.2.3 From f751995e86eacf7a475f7fb7ee52d2e45ab0b599 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 6 Feb 2015 13:59:50 -0800 Subject: Update README.md --- protos/README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/protos/README.md b/protos/README.md index 29639a68f4..374d4350ac 100644 --- a/protos/README.md +++ b/protos/README.md @@ -3,10 +3,8 @@ ## Contents - helloworld.proto - A very simple example used in the overview. - + - A very simple example used in the overview. - stock.proto - A detailed example that's described in detail in the tutorial. - + - A detailed example that's described in detail in the tutorial. - math.proto - Another detailed example for further reference. + - Another detailed example for further reference. -- cgit v1.2.3 From cf6360377c9d42f66b8940f6006c503f276907da Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 9 Feb 2015 17:14:14 +0000 Subject: First commit of consolidated overview/README --- README.md | 275 +++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 237 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 41b79ba883..fbd35ebad9 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,64 @@ -# gRPC Hello World Tutorial +# Getting started ## TODO: move this to the tutorial sub-folder -A great way to get introduced to gRPC is to work through this tutorial, which -walks you through the construction of a simple client and server and introduces -various features of gRPC. +Welcome to the developer documentation for gRPC, a language-neutral, +platform-neutral remote procedure call (RPC) system developed at Google that +helps you build connected systems. -When you finish the tutorial, you will be able to +This document introduces you to gRPC with a quick overview and a simple +Hello World example. More documentation is coming soon! -- Create a protobuf schema that defines a simple RPC service. -- Create a Java server that implements the schema interface. -- Create a Java client that accesses the server. -- Create a Go client that accesses the Java server. -- Update the service with advanced features like RPC streaming. +## What is gRPC? + +## TODO: basic conceptual intro (anything more in-depth will go in gRPC Concepts doc) + +## Hello gRPC! -# Get Started +Now that you know a bit more about gRPC, the easiest way to see how it +works is to look at a simple example. Our Hello World walks you through the +construction of a simple gRPC client-server application, showing you how to: + +- Create a protobuf schema that defines a simple RPC service with a single +Hello World method. +- Create a Java server that implements the schema interface. +- Create a Java client that accesses the Java server. +- Create a Go client that accesses the same Java server. +- Update the service with more advanced features like RPC streaming. -The rest of this page explains how you can set up your local machine for development. -If you just want to read the tutorial, you can go straight to the next step: [Step - 0](Step_0.md) +The complete code for the example is available in [wherever we put it]. You can +work along with the example and hack on the code in the comfort of your own +computer, giving you hands-on practice of really writing +gRPC code. We use the Git versioning system for source code management: +however, you don't need to know anything about Git to follow along other +than how to install and run a few git commands. -# Working with the code +This is an introductory example rather than a comprehensive tutorial, so +don't worry if you're not a Go or +Java developer - complete tutorials and reference documentation for all gRPC +languages are coming soon. -You can follow along with this tutorial and hack on the code in the comfort of -your own computer. This way you can get hands-on practice of really writing -gRPC code. +### Setup -The tutorial relies on the use of the Git versioning system for source code -management. You don't need to know anything about Git to follow the tutorial -other than how to install and run a few git commands. +The rest of this page explains how to set up your local machine to work with +the example code. +If you just want to read the example, you can go straight to the next step: +[Step - 0](Step_0.md) -# Install Git +#### Install Git You can download and install Git from http://git-scm.com/download. Once installed you should have access to the git command line tool. The main commands that you will need to use are: - git clone ... : clone a remote repository onto your local machine -- git checkout ... : check out a particular branch or a tagged version of the code to hack on +- git checkout ... : check out a particular branch or a tagged version of +the code to hack on -# Download grpc-helloworld +#### Download grpc-helloworld -Clone the grpc-helloword repository located at GitHub by running the following command: +Clone the grpc-helloword repository located at GitHub by running the +following command: ``` git clone https://github.com/google/grpc-helloworld.git @@ -52,30 +70,211 @@ Change your current directory to grpc-helloworld cd grpc-helloworld ``` -# Install Java 8 +#### Install Java 8 -Java gRPC is designed to work with both Java 7 and Java 8. For simplicity, -the example assumes that Java 8 is installed. See -[Install Java 8](http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html) -for instructions. +Java gRPC is designed to work with both Java 7 and Java 8 - our example uses +Java 8. See +[Install Java +8](http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html) +for instructions if you need to install Java 8. -# Install Maven +#### Install Maven -To simplify building and the managing of gRPC's dependencies, the Java client -are server are structured as a standard [Maven](http://maven.apache.org/guides/getting-started/) -project. See [Install Maven](http://maven.apache.org/users/index.html) for instructions. +To simplify building and managing gRPC's dependencies, the Java client +and server are structured as a standard +[Maven](http://maven.apache.org/guides/getting-started/) +project. See [Install Maven](http://maven.apache.org/users/index.html) +for instructions. -# Install Go 1.4 +#### Install Go 1.4 Go gRPC requires Go 1.4, the latest version of Go. See [Install Go](https://golang.org/doc/install) for instructions. -# (optional) Install protoc +#### (optional) Install protoc -gRPC uses the latest version of the protocol buffer compiler, protoc. +gRPC uses the latest version of the [protocol +buffer](https://developers.google.com/protocol-buffers/docs/overview) +compiler, protoc. -For following this tutorial, the protoc is not strictly necessary, as all the -generated code is checked into the Git repository. If you want to experiment +Having protoc installed isn't strictly necessary to follow along with this +example, as all the +generated code is checked into the Git repository. However, if you want +to experiment with generating the code yourself, download and install protoc from its [Git repo](https://github.com/google/protobuf) + +### Defining a service + +The first step in creating our example is to define a *service*: an RPC +service specifies the methods that can be called remotely with their parameters +and return types. In gRPC, we use the protocol buffers interface definition +language (IDL) to define our service methods, and the parameters and return +types are defined as protocol buffer message types. Both the client and the +server use interface code generated from the service definition. If you're not +familiar with protocol buffers, you can find out more in the [Protocol Buffers +Developer Guide](https://developers.google.com/protocol-buffers/docs/overview). + +Here's our example service definition, defined using protocol buffers IDL in +[helloworld.proto](src/main/proto/helloworld.proto). The `Greeting` service +has one method, `hello`, that lets the server receive a single `HelloRequest` +message from the remote client containing the user's name, then send back +a greeting in a `HelloReply`. + +``` +syntax = "proto3"; + +package helloworld; + +// The request message containing the user's name. +message HelloRequest { + optional string name = 1; +} + +// The response message containing the greetings +message HelloReply { + optional string message = 1; +} + +// The greeting service definition. +service Greeting { + + // Sends a greeting + rpc hello (HelloRequest) returns (HelloReply) { + } +} + +``` + +### Generating gRPC code + +Once we've defined our service, we use the protocol buffer compiler +`protoc` to generate the special client and server code we need to create +our application - right now we're going to generate Java code, though you +can generate gRPC code in any gRPC-supported language (as you'll see later +in this example). The generated code contains both stub code for clients to +use and an abstract interface for servers to implement, both with the method +defined in our `Greeting` service. A stub is code that initiates contact +with a gRPC service running remotely via the internet. [can probably define +this up in "what is gRPC"?] + +(If you didn't install `protoc` on your system and are working along with +the example, you can skip this step and move +onto the next one where we examine the generated code.) + +As this is our first time using gRPC, we need to build the protobuf plugin that generates our RPC +classes. By default `protoc` just generates code for reading and writing +protocol buffers, so you need to use plugins to add additional features +to generated code. As we're creating Java code, we use the gRPC Java plugin. + +To build the plugin: + +``` +$ pushd external/grpc_java +$ make java_plugin +$ popd +``` + +To use it to generate the code: + +``` +$ mkdir -p src/main/java +$ protoc -I . helloworld.proto +--plugin=protoc-gen-grpc=external/grpc_java/bins/opt/java_plugin \ + --grpc_out=src/main/java \ + --java_out=src/main/java +``` + +This generates the following Java classes + +### Writing a client + +Now let's write some code! Client-side gRPC is pretty simple, so we'll start there - we'll look at how to implement a gRPC server later. In this step, we'll use the generated code to write a simple client that can access the `Greetings` service. You can see the complete client code in [GreetingsClient.java](src/main/java/ex/grpc/GreetingsClient.java). + +Note that we're not going to go into much detail about how to implement a client - we'll leave that for the tutorial. + +#### Connecting to the service + +. The internet address +is configured in the client constructor. gRPC Channel is the abstraction over +transport handling; its constructor accepts the host name and port of the +service. The channel in turn is used to construct the Stub. + + +``` + private final ChannelImpl channel; + private final GreetingGrpc.GreetingBlockingStub blockingStub; + + public HelloClient(String host, int port) { + channel = NettyChannelBuilder.forAddress(host, port) + .negotiationType(NegotiationType.PLAINTEXT) + .build(); + blockingStub = GreetingGrpc.newBlockingStub(channel); + } + +``` + +#### Obtaining a greeting + +The greet method uses the stub to contact the service and obtain a greeting. +It: +- constructs a request +- obtains a reply from the stub +- prints out the greeting + + +``` + public void greet(String name) { + logger.debug("Will try to greet " + name + " ..."); + try { + Helloworld.HelloRequest request = Helloworld.HelloRequest.newBuilder().setName(name).build(); + Helloworld.HelloReply reply = blockingStub.hello(request); + logger.info("Greeting: " + reply.getMessage()); + } catch (RuntimeException e) { + logger.log(Level.WARNING, "RPC failed", e); + return; + } + } + +``` + +#### Running from the command line + +The main method puts together the example so that it can be run from a command +line. + +``` + /* Access a service running on the local machine on port 50051 */ + HelloClient client = new HelloClient("localhost", 50051); + String user = "world"; + if (args.length > 1) { + user = args[1]; + } + client.greet(user); + +``` + +It can be built as follows. + +``` +$ mvn package +``` + +It can also be run, but doing so now would end up a with a failure as there is +no server available yet. The [next step](Step_3.md), describes how to +implement, build and run a server that supports the service description. + +#### Notes + +- The client uses a blocking stub. This means that the RPC call waits for the + server to respond, and will either return a response or raise an exception. + +- gRPC Java has other kinds of stubs that make non-blocking calls to the + server, where the response is returned asynchronously. Usage of these stubs + is a more advanced topic and will be described in later steps. + + +We haven't looked at implementing a server yet, but + + -- cgit v1.2.3 From ad011166baf7eb1359a5db25d3933e2ec940b1db Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 9 Feb 2015 17:30:37 +0000 Subject: Minor restructure --- README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fbd35ebad9..d7ecba7566 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,7 @@ languages are coming soon. The rest of this page explains how to set up your local machine to work with the example code. -If you just want to read the example, you can go straight to the next step: -[Step - 0](Step_0.md) +If you just want to read the example, you can go straight to the next step. #### Install Git @@ -188,11 +187,18 @@ $ protoc -I . helloworld.proto This generates the following Java classes +### Writing a server + +Now let's write some code! First we'll create the `Greetings` server. + +Note that we're not going to go into a lot of detail about how to create a server in this section More detailed information will be in the tutorial for your chosen language (coming soon). + + ### Writing a client -Now let's write some code! Client-side gRPC is pretty simple, so we'll start there - we'll look at how to implement a gRPC server later. In this step, we'll use the generated code to write a simple client that can access the `Greetings` service. You can see the complete client code in [GreetingsClient.java](src/main/java/ex/grpc/GreetingsClient.java). +Client-side gRPC is pretty simple. In this step, we'll use the generated code to write a simple client that can access the `Greetings` server we created in the previous section. You can see the complete client code in [GreetingsClient.java](src/main/java/ex/grpc/GreetingsClient.java). -Note that we're not going to go into much detail about how to implement a client - we'll leave that for the tutorial. +Again, we're not going to go into much detail about how to implement a client - we'll leave that for the tutorial. #### Connecting to the service -- cgit v1.2.3 From c57778bdba28d6db3bf08f30cc0350f3d0b36812 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Tue, 10 Feb 2015 16:38:10 +0000 Subject: Added server and client steps. Still a bit rough round the edges.... --- README.md | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 122 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index d7ecba7566..3a2f3c8555 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,7 @@ ## TODO: move this to the tutorial sub-folder Welcome to the developer documentation for gRPC, a language-neutral, -platform-neutral remote procedure call (RPC) system developed at Google that -helps you build connected systems. +platform-neutral remote procedure call (RPC) system developed at Google. This document introduces you to gRPC with a quick overview and a simple Hello World example. More documentation is coming soon! @@ -13,6 +12,7 @@ Hello World example. More documentation is coming soon! ## TODO: basic conceptual intro (anything more in-depth will go in gRPC Concepts doc) + ## Hello gRPC! Now that you know a bit more about gRPC, the easiest way to see how it @@ -38,11 +38,12 @@ don't worry if you're not a Go or Java developer - complete tutorials and reference documentation for all gRPC languages are coming soon. + ### Setup The rest of this page explains how to set up your local machine to work with the example code. -If you just want to read the example, you can go straight to the next step. +If you just want to read the example, you can go straight to the [next step](#servicedef). #### Install Git @@ -54,19 +55,19 @@ commands that you will need to use are: - git checkout ... : check out a particular branch or a tagged version of the code to hack on -#### Download grpc-helloworld +#### Get the source code -Clone the grpc-helloword repository located at GitHub by running the +The example code for this and our other examples lives in the `grpc-common` GitHub repository. Clone this repository to your local machine by running the following command: ``` -git clone https://github.com/google/grpc-helloworld.git +git clone https://github.com/google/grpc-common.git ``` -Change your current directory to grpc-helloworld +Change your current directory to grpc-common/java ``` -cd grpc-helloworld +cd grpc-common/java ``` #### Install Java 8 @@ -104,6 +105,7 @@ to experiment with generating the code yourself, download and install protoc from its [Git repo](https://github.com/google/protobuf) + ### Defining a service The first step in creating our example is to define a *service*: an RPC @@ -116,7 +118,7 @@ familiar with protocol buffers, you can find out more in the [Protocol Buffers Developer Guide](https://developers.google.com/protocol-buffers/docs/overview). Here's our example service definition, defined using protocol buffers IDL in -[helloworld.proto](src/main/proto/helloworld.proto). The `Greeting` service +[helloworld.proto](java/src/main/proto/helloworld.proto) _should we link to the version in the Java subdirectory or the one in the common protos directory?_. The `Greeting` service has one method, `hello`, that lets the server receive a single `HelloRequest` message from the remote client containing the user's name, then send back a greeting in a `HelloReply`. @@ -124,6 +126,8 @@ a greeting in a `HelloReply`. ``` syntax = "proto3"; +option java_package = "ex.grpc"; + package helloworld; // The request message containing the user's name. @@ -146,6 +150,7 @@ service Greeting { ``` + ### Generating gRPC code Once we've defined our service, we use the protocol buffer compiler @@ -185,15 +190,103 @@ $ protoc -I . helloworld.proto --java_out=src/main/java ``` -This generates the following Java classes +This generates the following classes, which contain all the generated code we need to create our example: + +- [`Helloworld.java`](java/src/main/java/ex/grpc/Helloworld.java), which has all the protocol buffer code to populate, serialize, and retrieve our `HelloRequest` and `HelloReply` message types +- [`GreetingsGrpc.java`](java/src/main/java/ex/grpc/GreetingsGrpc.java), which contains (along with some other useful code): + - an interface for `Greetings` servers to implement + +``` + public static interface Greetings { + + public void hello(ex.grpc.Helloworld.HelloRequest request, + com.google.net.stubby.stub.StreamObserver responseObserver); + } +``` + + - _stub_ classes that clients can use to talk to a `Greetings` server. + +``` +public static class GreetingsStub extends + com.google.net.stubby.stub.AbstractStub + implements Greetings { + ... + } +``` + +_Does gRPC output multiple Java classes per proto by default?_ + ### Writing a server -Now let's write some code! First we'll create the `Greetings` server. +Now let's write some code! First we'll create a server application to implement our service. Note that we're not going to go into a lot of detail about how to create a server in this section More detailed information will be in the tutorial for your chosen language (coming soon). + +Our server application has two classes: + +- a simple service implementation [GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java). + +- a server that hosts the service implementation and allows access over the network: [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java). + +## Service implementation + +[GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java) +implements the behaviour we require of our GreetingService. There are a +number of important features of gRPC being used here: + +``` + public void hello(Helloworld.HelloRequest req, + StreamObserver responseObserver) { + Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( + "Hello " + req.getName()).build(); + responseObserver.onValue(reply); + responseObserver.onCompleted(); + } +``` + +- it provides a class `GreetingsImpl` that implements a generated interface `GreetingsGrpc.Greetings` +- `GreetingsGrpc.Greetings` declares the method `hello` that was declared in the proto [IDL](src/main/proto/helloworld.proto) +- `hello's` signature is typesafe: + hello(Helloworld.HelloRequest req, StreamObserver responseObserver) +- `hello` takes two parameters: + `Helloworld.HelloRequest`: the request + `StreamObserver`: a response observer, an interface to be called with the response value +- to complete the call + - the return value is constructed + - the responseObserver.onValue() is called with the response + - responseObserver.onCompleted() is called to indicate that no more work will done on the RPC. + -Note that we're not going to go into a lot of detail about how to create a server in this section More detailed information will be in the tutorial for your chosen language (coming soon). +## Server implementation +[GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java) shows the +other main feature required to provde the gRPC service; how to allow a service +implementation to be accessed from the network. +``` + private void start() throws Exception { + server = NettyServerBuilder.forPort(port) + .addService(GreetingsGrpc.bindService(new GreetingsImpl())) + .build(); + server.startAsync(); + server.awaitRunning(5, TimeUnit.SECONDS); + } + +``` + +- it provides a class `GreetingsServer` that holds a `ServerImpl` that will run the server +- in the `start` method, `GreetingServer` binds the `GreetingsService` implementation to a port and begins running it +- there is also a `stop` method that takes care of shutting down the service and cleaning up when the program exits + +## Build it + +This is the same as before: our client and server are part of the same maven +package so the same command builds both. + +``` +$ mvn package +``` + + ### Writing a client Client-side gRPC is pretty simple. In this step, we'll use the generated code to write a simple client that can access the `Greetings` server we created in the previous section. You can see the complete client code in [GreetingsClient.java](src/main/java/ex/grpc/GreetingsClient.java). @@ -267,10 +360,6 @@ It can be built as follows. $ mvn package ``` -It can also be run, but doing so now would end up a with a failure as there is -no server available yet. The [next step](Step_3.md), describes how to -implement, build and run a server that supports the service description. - #### Notes - The client uses a blocking stub. This means that the RPC call waits for the @@ -280,7 +369,23 @@ implement, build and run a server that supports the service description. server, where the response is returned asynchronously. Usage of these stubs is a more advanced topic and will be described in later steps. + +### Try it out! + +We've added simple shell scripts to simplifying running the examples. Now +that they are built, you can run the server with: + +``` +$ ./run_greetings_server.sh +``` + +and in another terminal window confirm that it receives a message. + +``` +$ ./run_greetings_client.sh +``` + + -We haven't looked at implementing a server yet, but -- cgit v1.2.3 From 4a8df2ae35d5864c30d09bd72376dece749c3ff1 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Tue, 10 Feb 2015 16:46:20 +0000 Subject: Delete Step_0.md Remove separate step now everything's been moved into the main doc --- Step_0.md | 41 ----------------------------------------- 1 file changed, 41 deletions(-) delete mode 100644 Step_0.md diff --git a/Step_0.md b/Step_0.md deleted file mode 100644 index d0745b0dd1..0000000000 --- a/Step_0.md +++ /dev/null @@ -1,41 +0,0 @@ -# Step-0: define a service - -This section presents an example of a simple service definition that receives -a message from a remote client. The message contains the user's name and -sends back a greeting to that person. - -It's shown below in full; it's actually contained in separate file. -[helloworld.proto](src/main/proto/helloworld.proto). - -``` -syntax = "proto3"; - -package helloworld; - -// The request message containing the user's name. -message HelloRequest { - optional string name = 1; -} - -// The response message containing the greetings -message HelloReply { - optional string message = 1; -} - -// The greeting service definition. -service Greeting { - - // Sends a greeting - rpc hello (HelloRequest) returns (HelloReply) { - } -} - -``` - -The service stanza of the message is an example of protobuf service IDL -(Interface Definition Language). Here, it defines a simple service that -receives a request containing a name and returns a response containing a -message. - -Next, in [Step - 1](Step_1.md), we'll use protoc to generate client code from -this IDL. -- cgit v1.2.3 From baa905deefac19dcd32b2ccedcc53e41b077825a Mon Sep 17 00:00:00 2001 From: LisaFC Date: Tue, 10 Feb 2015 16:46:45 +0000 Subject: Delete Step_1.md Remove separate step now that all the content has been moved into the main doc --- Step_1.md | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 Step_1.md diff --git a/Step_1.md b/Step_1.md deleted file mode 100644 index c7aed326c3..0000000000 --- a/Step_1.md +++ /dev/null @@ -1,33 +0,0 @@ -# Step-1: Generate a service client. - -In this step, we use protoc to generate the Java Stub classes. A Stub is the -name gRPC uses for the code that initiates contact with a gRPC service running -remotely via the internet. - -If you did not install protoc on your system, you can skip this step and move -onto the next one where we examine the generated code. - -First, you'll need to build the protobuf plugin that generates the rpc -classes. `protoc` uses other tools called plugins to add additional features -to generated code. - -The gRPC Java Stub classes are created using a gRPC Java plugin, but first the -plugin must be built and installed. - -To build the plugin: -``` -$ pushd external/grpc_java -$ make java_plugin -$ popd -``` - -To use it to generate the code: -``` -$ mkdir -p src/main/java -$ protoc -I . helloworld.proto --plugin=protoc-gen-grpc=external/grpc_java/bins/opt/java_plugin \ - --grpc_out=src/main/java \ - --java_out=src/main/java -``` - -Next, in [Step - 2](Step_2.md), we'll use the generated Stub implementation to -write a client that uses the generated code to make a call to a service. -- cgit v1.2.3 From b8d33683de3fa51b45c285b35030e0568420f299 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Tue, 10 Feb 2015 16:47:00 +0000 Subject: Delete Step_2.md Remove separate step now that all the content has been moved into the main doc --- Step_2.md | 85 --------------------------------------------------------------- 1 file changed, 85 deletions(-) delete mode 100644 Step_2.md diff --git a/Step_2.md b/Step_2.md deleted file mode 100644 index eafe70b692..0000000000 --- a/Step_2.md +++ /dev/null @@ -1,85 +0,0 @@ -# Step-2: Write a service client. - -This step uses the generated code to write a simple client to access the hello -service. The full client is in [GreetingsClient.java](src/main/java/ex/grpc/GreetingsClient.java). - - -## Configuring the service to connect to. - -The client contains uses a Stub to contact the service. The internet address -is configured in the client constructor. gRPC Channel is the abstraction over -transport handling; its constructor accepts the host name and port of the -service. The channel in turn is used to construct the Stub. - - -``` - private final ChannelImpl channel; - private final GreetingGrpc.GreetingBlockingStub blockingStub; - - public HelloClient(String host, int port) { - channel = NettyChannelBuilder.forAddress(host, port) - .negotiationType(NegotiationType.PLAINTEXT) - .build(); - blockingStub = GreetingGrpc.newBlockingStub(channel); - } - -``` - -## Obtaining a greeting - -The greet method uses the stub to contact the service and obtain a greeting. -It: -- constructs a request -- obtains a reply from the stub -- prints out the greeting - - -``` - public void greet(String name) { - logger.debug("Will try to greet " + name + " ..."); - try { - Helloworld.HelloRequest request = Helloworld.HelloRequest.newBuilder().setName(name).build(); - Helloworld.HelloReply reply = blockingStub.hello(request); - logger.info("Greeting: " + reply.getMessage()); - } catch (RuntimeException e) { - logger.log(Level.WARNING, "RPC failed", e); - return; - } - } - -``` - -## Running from the command line - -The main method puts together the example so that it can be run from a command -line. - -``` - /* Access a service running on the local machine on port 50051 */ - HelloClient client = new HelloClient("localhost", 50051); - String user = "world"; - if (args.length > 1) { - user = args[1]; - } - client.greet(user); - -``` - -It can be built as follows. - -``` -$ mvn package -``` - -It can also be run, but doing so now would end up a with a failure as there is -no server available yet. The [next step](Step_3.md), describes how to -implement, build and run a server that supports the service description. - -## Notes - -- The client uses a blocking stub. This means that the RPC call waits for the - server to respond, and will either return a response or raise an exception. - -- gRPC Java has other kinds of stubs that make non-blocking calls to the - server, where the response is returned asynchronously. Usage of these stubs - is a more advanced topic and will be described in later steps. -- cgit v1.2.3 From a60ad9e4221046b3444789d67873186cd1dd2103 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Tue, 10 Feb 2015 16:47:10 +0000 Subject: Delete Step_3.md Remove separate step now that all the content has been moved into the main doc --- Step_3.md | 82 --------------------------------------------------------------- 1 file changed, 82 deletions(-) delete mode 100644 Step_3.md diff --git a/Step_3.md b/Step_3.md deleted file mode 100644 index 7b03cdf585..0000000000 --- a/Step_3.md +++ /dev/null @@ -1,82 +0,0 @@ -# Step-3: Implement a server. - -This step extends the generated server skeleton code to write a simple server -that provides the hello service. This introduces two new classes: - -- a service implementation [GreetingsImpl.java](src/main/java/ex/grpc/GreetingsImpl.java). - -- a server that hosts the service implementation and allows access over the network: [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java). - -## Service implementation - -[GreetingsImpl.java](src/main/java/ex/grpc/GreetingsImpl.java) -implements the behaviour we require of our GreetingService. There are a -number of important features of gRPC being used here: - -``` - public void hello(Helloworld.HelloRequest req, - StreamObserver responseObserver) { - Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( - "Hello " + req.getName()).build(); - responseObserver.onValue(reply); - responseObserver.onCompleted(); - } -``` - -- it provides a class `GreetingsImpl` that implements a generated interface `GreetingsGrpc.Greetings` -- `GreetingsGrpc.Greetings` declares the method `hello` that was declared in the proto [IDL](src/main/proto/helloworld.proto) -- `hello's` signature is typesafe: - hello(Helloworld.HelloRequest req, StreamObserver responseObserver) -- `hello` takes two parameters: - `Helloworld.HelloRequest`: the request - `StreamObserver`: a response observer, an interface to be called with the response value -- to complete the call - - the return value is constructed - - the responseObserver.onValue() is called with the response - - responseObserver.onCompleted() is called to indicate that no more work will done on the RPC. - - -## Server implementation - -[GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java) shows the -other main feature required to provde the gRPC service; how to allow a service -implementation to be accessed from the network. - -``` - private void start() throws Exception { - server = NettyServerBuilder.forPort(port) - .addService(GreetingsGrpc.bindService(new GreetingsImpl())) - .build(); - server.startAsync(); - server.awaitRunning(5, TimeUnit.SECONDS); - } - -``` - -- it provides a class `GreetingsServer` that holds a `ServerImpl` that will run the server -- in the `start` method, `GreetingServer` binds the `GreetingsService` implementation to a port and begins running it -- there is also a `stop` method that takes care of shutting down the service and cleaning up when the program exits - -## Build it - -This is the same as before: our client and server are part of the same maven -package so the same command builds both. - -``` -$ mvn package -``` - -## Try them out - -We've added simple shell scripts to simplifying running the examples. Now -that they are built, you can run the server with: - -``` -$ ./run_greetings_server.sh -``` - -and in another terminal window confirm that it receives a message. - -``` -$ ./run_greetings_client.sh -``` -- cgit v1.2.3 From 874bff090a0231940e0c60e6520f80d3834b91f3 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Tue, 10 Feb 2015 16:47:41 +0000 Subject: Minor formatting tweaks --- README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3a2f3c8555..61ff9a5e97 100644 --- a/README.md +++ b/README.md @@ -227,7 +227,7 @@ Our server application has two classes: - a server that hosts the service implementation and allows access over the network: [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java). -## Service implementation +#### Service implementation [GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java) implements the behaviour we require of our GreetingService. There are a @@ -256,7 +256,7 @@ number of important features of gRPC being used here: - responseObserver.onCompleted() is called to indicate that no more work will done on the RPC. -## Server implementation +#### Server implementation [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java) shows the other main feature required to provde the gRPC service; how to allow a service @@ -277,15 +277,16 @@ implementation to be accessed from the network. - in the `start` method, `GreetingServer` binds the `GreetingsService` implementation to a port and begins running it - there is also a `stop` method that takes care of shutting down the service and cleaning up when the program exits -## Build it +#### Build it -This is the same as before: our client and server are part of the same maven -package so the same command builds both. +Once we've implemented everything, we use Maven to build the server: ``` $ mvn package ``` +We'll look at using a client to access the server in the next section. + ### Writing a client @@ -354,7 +355,10 @@ line. ``` -It can be built as follows. +#### Build the client + +This is the same as before: our client and server are part of the same maven +package so the same command builds both. ``` $ mvn package -- cgit v1.2.3 From d7e29f4b313faa71acd2cee5f46ca9fc380e9c3d Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Wed, 11 Feb 2015 13:14:16 +0000 Subject: Implementing Tim's edits --- README.md | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 61ff9a5e97..c7c896db61 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Hello World method. - Create a Go client that accesses the same Java server. - Update the service with more advanced features like RPC streaming. -The complete code for the example is available in [wherever we put it]. You can +The complete code for the example is available in the `grpc-common` GitHub repository. You can work along with the example and hack on the code in the comfort of your own computer, giving you hands-on practice of really writing gRPC code. We use the Git versioning system for source code management: @@ -174,7 +174,7 @@ to generated code. As we're creating Java code, we use the gRPC Java plugin. To build the plugin: -``` +```sh $ pushd external/grpc_java $ make java_plugin $ popd @@ -182,7 +182,7 @@ $ popd To use it to generate the code: -``` +```sh $ mkdir -p src/main/java $ protoc -I . helloworld.proto --plugin=protoc-gen-grpc=external/grpc_java/bins/opt/java_plugin \ @@ -194,27 +194,25 @@ This generates the following classes, which contain all the generated code we ne - [`Helloworld.java`](java/src/main/java/ex/grpc/Helloworld.java), which has all the protocol buffer code to populate, serialize, and retrieve our `HelloRequest` and `HelloReply` message types - [`GreetingsGrpc.java`](java/src/main/java/ex/grpc/GreetingsGrpc.java), which contains (along with some other useful code): - - an interface for `Greetings` servers to implement + - an interface for `Greetings` servers to implement -``` + ```java public static interface Greetings { public void hello(ex.grpc.Helloworld.HelloRequest request, com.google.net.stubby.stub.StreamObserver responseObserver); } -``` + ``` - - _stub_ classes that clients can use to talk to a `Greetings` server. + - _stub_ classes that clients can use to talk to a `Greetings` server. -``` + ```java public static class GreetingsStub extends com.google.net.stubby.stub.AbstractStub implements Greetings { ... } -``` - -_Does gRPC output multiple Java classes per proto by default?_ + ``` ### Writing a server @@ -233,7 +231,7 @@ Our server application has two classes: implements the behaviour we require of our GreetingService. There are a number of important features of gRPC being used here: -``` +```java public void hello(Helloworld.HelloRequest req, StreamObserver responseObserver) { Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( @@ -262,7 +260,7 @@ number of important features of gRPC being used here: other main feature required to provde the gRPC service; how to allow a service implementation to be accessed from the network. -``` +```java private void start() throws Exception { server = NettyServerBuilder.forPort(port) .addService(GreetingsGrpc.bindService(new GreetingsImpl())) @@ -302,7 +300,7 @@ transport handling; its constructor accepts the host name and port of the service. The channel in turn is used to construct the Stub. -``` +```java private final ChannelImpl channel; private final GreetingGrpc.GreetingBlockingStub blockingStub; @@ -324,7 +322,7 @@ It: - prints out the greeting -``` +```java public void greet(String name) { logger.debug("Will try to greet " + name + " ..."); try { @@ -344,7 +342,7 @@ It: The main method puts together the example so that it can be run from a command line. -``` +```java /* Access a service running on the local machine on port 50051 */ HelloClient client = new HelloClient("localhost", 50051); String user = "world"; @@ -379,13 +377,13 @@ $ mvn package We've added simple shell scripts to simplifying running the examples. Now that they are built, you can run the server with: -``` +```sh $ ./run_greetings_server.sh ``` and in another terminal window confirm that it receives a message. -``` +```sh $ ./run_greetings_client.sh ``` -- cgit v1.2.3 From 8e9a709d47fcf79379cb04fa0d98a03f5915f8b4 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Thu, 12 Feb 2015 17:48:42 +0000 Subject: More tidying up of example... --- README.md | 70 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index c7c896db61..bd0738447a 100644 --- a/README.md +++ b/README.md @@ -118,10 +118,11 @@ familiar with protocol buffers, you can find out more in the [Protocol Buffers Developer Guide](https://developers.google.com/protocol-buffers/docs/overview). Here's our example service definition, defined using protocol buffers IDL in -[helloworld.proto](java/src/main/proto/helloworld.proto) _should we link to the version in the Java subdirectory or the one in the common protos directory?_. The `Greeting` service +[helloworld.proto](java/src/main/proto/helloworld.proto). The `Greeting` service has one method, `hello`, that lets the server receive a single `HelloRequest` message from the remote client containing the user's name, then send back -a greeting in a `HelloReply`. +a greeting in a single `HelloReply`. This is the simplest type of RPC you +can specify in gRPC - we'll look at some other types later in this document. ``` syntax = "proto3"; @@ -167,7 +168,8 @@ this up in "what is gRPC"?] the example, you can skip this step and move onto the next one where we examine the generated code.) -As this is our first time using gRPC, we need to build the protobuf plugin that generates our RPC +As this is our first time using gRPC, we need to build the protobuf plugin +that generates our RPC classes. By default `protoc` just generates code for reading and writing protocol buffers, so you need to use plugins to add additional features to generated code. As we're creating Java code, we use the gRPC Java plugin. @@ -190,17 +192,22 @@ $ protoc -I . helloworld.proto --java_out=src/main/java ``` -This generates the following classes, which contain all the generated code we need to create our example: +This generates the following classes, which contain all the generated code +we need to create our example: -- [`Helloworld.java`](java/src/main/java/ex/grpc/Helloworld.java), which has all the protocol buffer code to populate, serialize, and retrieve our `HelloRequest` and `HelloReply` message types -- [`GreetingsGrpc.java`](java/src/main/java/ex/grpc/GreetingsGrpc.java), which contains (along with some other useful code): +- [`Helloworld.java`](java/src/main/java/ex/grpc/Helloworld.java), which +has all the protocol buffer code to populate, serialize, and retrieve our +`HelloRequest` and `HelloReply` message types +- [`GreetingsGrpc.java`](java/src/main/java/ex/grpc/GreetingsGrpc.java), +which contains (along with some other useful code): - an interface for `Greetings` servers to implement ```java public static interface Greetings { public void hello(ex.grpc.Helloworld.HelloRequest request, - com.google.net.stubby.stub.StreamObserver responseObserver); + com.google.net.stubby.stub.StreamObserver + responseObserver); } ``` @@ -208,7 +215,8 @@ This generates the following classes, which contain all the generated code we ne ```java public static class GreetingsStub extends - com.google.net.stubby.stub.AbstractStub + com.google.net.stubby.stub.AbstractStub implements Greetings { ... } @@ -217,48 +225,58 @@ public static class GreetingsStub extends ### Writing a server -Now let's write some code! First we'll create a server application to implement our service. Note that we're not going to go into a lot of detail about how to create a server in this section More detailed information will be in the tutorial for your chosen language (coming soon). +Now let's write some code! First we'll create a server application to implement +our service. Note that we're not going to go into a lot of detail about how +to create a server in this section More detailed information will be in the +tutorial for your chosen language (coming soon). Our server application has two classes: -- a simple service implementation [GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java). +- a simple service implementation +[GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java). -- a server that hosts the service implementation and allows access over the network: [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java). +- a server that hosts the service implementation and allows access over the +network: [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java). #### Service implementation [GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java) -implements the behaviour we require of our GreetingService. There are a -number of important features of gRPC being used here: +actually implements our GreetingService's required behaviour. + +As you can see, the class `GreetingsImpl` implements the interface +`GreetingsGrpc.Greetings` that we [generated](#generating) from our proto +[IDL](src/main/proto/helloworld.proto) by implementing the method `hello`: ```java public void hello(Helloworld.HelloRequest req, StreamObserver responseObserver) { - Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( + Helloworld.HelloReply reply = + Helloworld.HelloReply.newBuilder().setMessage( "Hello " + req.getName()).build(); responseObserver.onValue(reply); responseObserver.onCompleted(); } ``` - -- it provides a class `GreetingsImpl` that implements a generated interface `GreetingsGrpc.Greetings` -- `GreetingsGrpc.Greetings` declares the method `hello` that was declared in the proto [IDL](src/main/proto/helloworld.proto) - `hello's` signature is typesafe: - hello(Helloworld.HelloRequest req, StreamObserver responseObserver) + `hello(Helloworld.HelloRequest req, StreamObserver + responseObserver)` - `hello` takes two parameters: - `Helloworld.HelloRequest`: the request - `StreamObserver`: a response observer, an interface to be called with the response value -- to complete the call - - the return value is constructed - - the responseObserver.onValue() is called with the response - - responseObserver.onCompleted() is called to indicate that no more work will done on the RPC. + -`Helloworld.HelloRequest`: the request + -`StreamObserver`: a response observer, which is + a special interface for the server to call with its response +To return our response to the client and complete the call: +1. We construct and populate a `HelloReply` response object with our exciting +message, as specified in our interface definition. +2. We call `responseObserver.onValue()` with the `HelloReply` that we want to send back to the client. +3. Finally, we call `responseObserver.onCompleted()` to indicate that we're +finished dealing with this RPC. #### Server implementation [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java) shows the -other main feature required to provde the gRPC service; how to allow a service -implementation to be accessed from the network. +other main feature required to provde the gRPC service; making the service +implementation available from the network. ```java private void start() throws Exception { -- cgit v1.2.3 From 2fdb96388faa6ef94fd768ba921dcf0a3ffe9a39 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Thu, 12 Feb 2015 17:51:13 +0000 Subject: Style tweaks --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bd0738447a..89e8d2942c 100644 --- a/README.md +++ b/README.md @@ -264,11 +264,12 @@ As you can see, the class `GreetingsImpl` implements the interface -`Helloworld.HelloRequest`: the request -`StreamObserver`: a response observer, which is a special interface for the server to call with its response + To return our response to the client and complete the call: -1. We construct and populate a `HelloReply` response object with our exciting + 1. We construct and populate a `HelloReply` response object with our exciting message, as specified in our interface definition. -2. We call `responseObserver.onValue()` with the `HelloReply` that we want to send back to the client. -3. Finally, we call `responseObserver.onCompleted()` to indicate that we're + 2. We call `responseObserver.onValue()` with the `HelloReply` that we want to send back to the client. + 3. Finally, we call `responseObserver.onCompleted()` to indicate that we're finished dealing with this RPC. -- cgit v1.2.3 From 034eb2e8097262ee9a6a543f47ab9baa15a92b92 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 11:05:25 +0000 Subject: Markdown, I hate you. --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 89e8d2942c..cc0ce4943f 100644 --- a/README.md +++ b/README.md @@ -213,14 +213,14 @@ which contains (along with some other useful code): - _stub_ classes that clients can use to talk to a `Greetings` server. - ```java +```java public static class GreetingsStub extends com.google.net.stubby.stub.AbstractStub implements Greetings { ... } - ``` +``` ### Writing a server @@ -266,6 +266,7 @@ As you can see, the class `GreetingsImpl` implements the interface a special interface for the server to call with its response To return our response to the client and complete the call: + 1. We construct and populate a `HelloReply` response object with our exciting message, as specified in our interface definition. 2. We call `responseObserver.onValue()` with the `HelloReply` that we want to send back to the client. -- cgit v1.2.3 From 31d143ce0745b485b315c56c1715dc46fe060a5e Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 11:07:16 +0000 Subject: AAAAAAARRRGHHHHH --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index cc0ce4943f..16304f65eb 100644 --- a/README.md +++ b/README.md @@ -213,14 +213,14 @@ which contains (along with some other useful code): - _stub_ classes that clients can use to talk to a `Greetings` server. -```java + ```java public static class GreetingsStub extends com.google.net.stubby.stub.AbstractStub implements Greetings { ... } -``` + ``` ### Writing a server @@ -267,10 +267,10 @@ As you can see, the class `GreetingsImpl` implements the interface To return our response to the client and complete the call: - 1. We construct and populate a `HelloReply` response object with our exciting +1. We construct and populate a `HelloReply` response object with our exciting message, as specified in our interface definition. - 2. We call `responseObserver.onValue()` with the `HelloReply` that we want to send back to the client. - 3. Finally, we call `responseObserver.onCompleted()` to indicate that we're +2. We call `responseObserver.onValue()` with the `HelloReply` that we want to send back to the client. +3. Finally, we call `responseObserver.onCompleted()` to indicate that we're finished dealing with this RPC. -- cgit v1.2.3 From 0af588a9cf75fd5769bb3bca5a978a3463f80668 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 15:42:03 +0000 Subject: More tidying up of existing text --- README.md | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 16304f65eb..8f6fd5cc6d 100644 --- a/README.md +++ b/README.md @@ -211,7 +211,7 @@ which contains (along with some other useful code): } ``` - - _stub_ classes that clients can use to talk to a `Greetings` server. + - _stub_ classes that clients can use to talk to a `Greetings` server. As you can see, they also implement the `Greetings` interface. ```java public static class GreetingsStub extends @@ -236,7 +236,7 @@ Our server application has two classes: [GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java). - a server that hosts the service implementation and allows access over the -network: [GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java). +network: [GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java). #### Service implementation @@ -245,7 +245,7 @@ actually implements our GreetingService's required behaviour. As you can see, the class `GreetingsImpl` implements the interface `GreetingsGrpc.Greetings` that we [generated](#generating) from our proto -[IDL](src/main/proto/helloworld.proto) by implementing the method `hello`: +[IDL](java/src/main/proto/helloworld.proto) by implementing the method `hello`: ```java public void hello(Helloworld.HelloRequest req, @@ -276,11 +276,13 @@ finished dealing with this RPC. #### Server implementation -[GreetingsServer.java](src/main/java/ex/grpc/GreetingsServer.java) shows the -other main feature required to provde the gRPC service; making the service +[GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) shows the +other main feature required to provide a gRPC service; making the service implementation available from the network. ```java + private ServerImpl server; + ... private void start() throws Exception { server = NettyServerBuilder.forPort(port) .addService(GreetingsGrpc.bindService(new GreetingsImpl())) @@ -291,9 +293,9 @@ implementation available from the network. ``` -- it provides a class `GreetingsServer` that holds a `ServerImpl` that will run the server -- in the `start` method, `GreetingServer` binds the `GreetingsService` implementation to a port and begins running it -- there is also a `stop` method that takes care of shutting down the service and cleaning up when the program exits +The `GreetingsServer` class has a `ServerImpl` member that actually runs the server. To create an appropriate `ServerImpl`, we use a special `ServerBuilder` class (in this case a `NettyServerBuilder`) in the `GreetingsServer`'s `start` method, binding the `GreetingsService` implementation that we created to a port. Then we start the server running: the server is now ready to receive requests from `Greetings` service clients on our specified port. We'll cover how all this works in a bit more detail in our language-specific documentation. + +`GreetingsServer` also has a `stop` method that takes care of shutting down the service and cleaning up when the program exits. #### Build it @@ -308,16 +310,16 @@ We'll look at using a client to access the server in the next section. ### Writing a client -Client-side gRPC is pretty simple. In this step, we'll use the generated code to write a simple client that can access the `Greetings` server we created in the previous section. You can see the complete client code in [GreetingsClient.java](src/main/java/ex/grpc/GreetingsClient.java). +Client-side gRPC is pretty simple. In this step, we'll use the generated code to write a simple client that can access the `Greetings` server we created in the [previous section](#server). You can see the complete client code in [GreetingsClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). Again, we're not going to go into much detail about how to implement a client - we'll leave that for the tutorial. #### Connecting to the service -. The internet address -is configured in the client constructor. gRPC Channel is the abstraction over +First let's look at how we connect to the `Greetings` server. The internet address +is configured in the client constructor. gRPC `Channel` provides the abstraction layer over transport handling; its constructor accepts the host name and port of the -service. The channel in turn is used to construct the Stub. +service. The channel in turn is used to construct the stub instance. ```java @@ -335,11 +337,11 @@ service. The channel in turn is used to construct the Stub. #### Obtaining a greeting -The greet method uses the stub to contact the service and obtain a greeting. -It: -- constructs a request -- obtains a reply from the stub -- prints out the greeting +The `greet()` method uses the stub to contact the service and obtain a greeting. +In the method we: +- construct and fill in a `HelloRequest` to send to the stub +- get a reply from the stub +- print out the greeting ```java @@ -375,7 +377,7 @@ line. #### Build the client -This is the same as before: our client and server are part of the same maven +This is the same as building the server: our client and server are part of the same maven package so the same command builds both. ``` @@ -407,6 +409,10 @@ and in another terminal window confirm that it receives a message. $ ./run_greetings_client.sh ``` +### Adding another client + +###TODO: Section on Go client for same server + -- cgit v1.2.3 From 26e6d380abce8fd667597acb0c7f785e33beac79 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 15:45:10 +0000 Subject: Bit of tidying up... --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8f6fd5cc6d..72a8de9eb0 100644 --- a/README.md +++ b/README.md @@ -338,10 +338,10 @@ service. The channel in turn is used to construct the stub instance. #### Obtaining a greeting The `greet()` method uses the stub to contact the service and obtain a greeting. -In the method we: -- construct and fill in a `HelloRequest` to send to the stub -- get a reply from the stub -- print out the greeting +To do this: + +1. We construct and fill in a `HelloRequest` to send to the stub. +2. We call the RPC with our request and get a `HelloReply` from the stub, from which we can get our greeting. ```java -- cgit v1.2.3 From 27da19feb43157260195732a8f63a5bc3545475b Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 15:58:20 +0000 Subject: Bit more tidying up --- README.md | 57 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 72a8de9eb0..e3719357ea 100644 --- a/README.md +++ b/README.md @@ -276,8 +276,8 @@ finished dealing with this RPC. #### Server implementation -[GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) shows the -other main feature required to provide a gRPC service; making the service +[GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) +shows the other main feature required to provide a gRPC service; making the service implementation available from the network. ```java @@ -293,9 +293,16 @@ implementation available from the network. ``` -The `GreetingsServer` class has a `ServerImpl` member that actually runs the server. To create an appropriate `ServerImpl`, we use a special `ServerBuilder` class (in this case a `NettyServerBuilder`) in the `GreetingsServer`'s `start` method, binding the `GreetingsService` implementation that we created to a port. Then we start the server running: the server is now ready to receive requests from `Greetings` service clients on our specified port. We'll cover how all this works in a bit more detail in our language-specific documentation. +The `GreetingsServer` class has a `ServerImpl` member that actually runs the +server. To create an appropriate `ServerImpl`, we use a special `ServerBuilder` +class (in this case a `NettyServerBuilder`) in the `GreetingsServer`'s `start` +method, binding the `GreetingsService` implementation that we created to a +port. Then we start the server running: the server is now ready to receive +requests from `Greetings` service clients on our specified port. We'll cover +how all this works in a bit more detail in our language-specific documentation. -`GreetingsServer` also has a `stop` method that takes care of shutting down the service and cleaning up when the program exits. +`GreetingsServer` also has a `stop` method that takes care of shutting down +the service and cleaning up when the program exits. #### Build it @@ -310,14 +317,20 @@ We'll look at using a client to access the server in the next section. ### Writing a client -Client-side gRPC is pretty simple. In this step, we'll use the generated code to write a simple client that can access the `Greetings` server we created in the [previous section](#server). You can see the complete client code in [GreetingsClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). +Client-side gRPC is pretty simple. In this step, we'll use the generated code +to write a simple client that can access the `Greetings` server we created +in the [previous section](#server). You can see the complete client code in +[GreetingsClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). -Again, we're not going to go into much detail about how to implement a client - we'll leave that for the tutorial. +Again, we're not going to go into much detail about how to implement a client +- we'll leave that for the tutorial. #### Connecting to the service -First let's look at how we connect to the `Greetings` server. The internet address -is configured in the client constructor. gRPC `Channel` provides the abstraction layer over +First let's look at how we connect to the `Greetings` server. The internet +address +is configured in the client constructor. gRPC `Channel` provides the +abstraction layer over transport handling; its constructor accepts the host name and port of the service. The channel in turn is used to construct the stub instance. @@ -335,20 +348,28 @@ service. The channel in turn is used to construct the stub instance. ``` +In this case, we create a blocking stub. This means that the RPC call waits +for the server to respond, and will either return a response or raise an +exception. gRPC Java has other kinds of stubs that make non-blocking calls +to the server, where the response is returned asynchronously. + #### Obtaining a greeting -The `greet()` method uses the stub to contact the service and obtain a greeting. +The `greet()` method uses the stub to contact the service and obtain +a greeting. To do this: 1. We construct and fill in a `HelloRequest` to send to the stub. -2. We call the RPC with our request and get a `HelloReply` from the stub, from which we can get our greeting. +2. We call the RPC with our request and get a `HelloReply` from the stub, +from which we can get our greeting. ```java public void greet(String name) { logger.debug("Will try to greet " + name + " ..."); try { - Helloworld.HelloRequest request = Helloworld.HelloRequest.newBuilder().setName(name).build(); + Helloworld.HelloRequest request = + Helloworld.HelloRequest.newBuilder().setName(name).build(); Helloworld.HelloReply reply = blockingStub.hello(request); logger.info("Greeting: " + reply.getMessage()); } catch (RuntimeException e) { @@ -377,22 +398,14 @@ line. #### Build the client -This is the same as building the server: our client and server are part of the same maven +This is the same as building the server: our client and server are part of +the same maven package so the same command builds both. ``` $ mvn package ``` -#### Notes - -- The client uses a blocking stub. This means that the RPC call waits for the - server to respond, and will either return a response or raise an exception. - -- gRPC Java has other kinds of stubs that make non-blocking calls to the - server, where the response is returned asynchronously. Usage of these stubs - is a more advanced topic and will be described in later steps. - ### Try it out! @@ -409,7 +422,7 @@ and in another terminal window confirm that it receives a message. $ ./run_greetings_client.sh ``` -### Adding another client +### Adding another client ###TODO: Section on Go client for same server -- cgit v1.2.3 From 461780145938e452e113f4eb951c3a28ff69b214 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 16:38:49 +0000 Subject: Starting intro --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index e3719357ea..592e1663f7 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,33 @@ Hello World example. More documentation is coming soon! ## What is gRPC? +gRPC is It enables communication between clients and servers using any combination of gRPC's supported languages, helping you to build distributed applications and services. + +In gRPC, like + +### Plays well with Protocol Buffers + +While gRPC’s architecture allows it to be extended for use with other +data formats such as JSON, by default it uses protocol buffers, Google’s +mature open source mechanism for serializing structured data. As you'll +see in our example below, you define gRPC interfaces using proto files and +protocol buffer messages, letting you take advantage of protocol buffers’ +efficient serialization, simple IDL, and easy interface updating. You +can find out lots more about protocol buffers in the [Protocol Buffers +documentation](https://developers.google.com/protocol-buffers/docs/overview). + +Note that our examples use a new flavour of protocol buffers called proto3, +which has a slightly simplified syntax, some useful new features, and supports +lots more languages. This is currently available as an alpha release in +[languages] from [wherever it's going], with more languages in development. In +general, we recommend that you use proto3 with gRPC as it lets you use the +full range of gRPC-supported languages, as well as avoiding any compatibility +issues with proto2 clients talking to proto3 servers and vice versa. + +If you need to continue using proto2 for Java, C++, or Python but want +to try gRPC, you can see an example using a proto2 gRPC client and server +[wherever we put it]. + ## TODO: basic conceptual intro (anything more in-depth will go in gRPC Concepts doc) -- cgit v1.2.3 From bdcda72cec23554d5ef1dd5695de9e97e8bb3235 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 16:40:23 +0000 Subject: Fixed typo --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 592e1663f7..413f5008a2 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,9 @@ Hello World example. More documentation is coming soon! ## What is gRPC? -gRPC is It enables communication between clients and servers using any combination of gRPC's supported languages, helping you to build distributed applications and services. +gRPC enables communication between clients and servers using any combination of gRPC's supported languages, helping you to build distributed applications and services. -In gRPC, like +In gRPC, like other RPC systems... ### Plays well with Protocol Buffers @@ -46,7 +46,7 @@ Now that you know a bit more about gRPC, the easiest way to see how it works is to look at a simple example. Our Hello World walks you through the construction of a simple gRPC client-server application, showing you how to: -- Create a protobuf schema that defines a simple RPC service with a single +- Create a protocol buffers schema that defines a simple RPC service with a single Hello World method. - Create a Java server that implements the schema interface. - Create a Java client that accesses the Java server. -- cgit v1.2.3 From 907119eafd930085c8067e7bdaabbe294cef9605 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 13 Feb 2015 16:52:03 +0000 Subject: Intro tweaks --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 413f5008a2..2d3a3a8f5b 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,7 @@ Hello World example. More documentation is coming soon! ## What is gRPC? -gRPC enables communication between clients and servers using any combination of gRPC's supported languages, helping you to build distributed applications and services. - -In gRPC, like other RPC systems... +In gRPC, like other RPC systems, a *client* application can directly call methods on a *server* application on a different machine as if it was a local object, making it easier for you to create distributed applications and services. gRPC clients and servers can run and talk to each other in a variety of environments - from servers inside Google to your own desktop - and can be written in any of gRPC's supported languages. So, for example, you can easily create a gRPC server in Java with clients in Go, Python, or Ruby. ### Plays well with Protocol Buffers @@ -68,9 +66,8 @@ languages are coming soon. ### Setup -The rest of this page explains how to set up your local machine to work with -the example code. -If you just want to read the example, you can go straight to the [next step](#servicedef). +This section explains how to set up your local machine to work with +the example code. If you just want to read the example, you can go straight to the [next step](#servicedef). #### Install Git -- cgit v1.2.3 From e82f310a440c75e5234c4aa6b0028ec5b550d8df Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Tue, 17 Feb 2015 16:27:51 +0000 Subject: Added a simple overview/protocol buffers information --- README.md | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 2d3a3a8f5b..a1575392e0 100644 --- a/README.md +++ b/README.md @@ -10,32 +10,34 @@ Hello World example. More documentation is coming soon! ## What is gRPC? -In gRPC, like other RPC systems, a *client* application can directly call methods on a *server* application on a different machine as if it was a local object, making it easier for you to create distributed applications and services. gRPC clients and servers can run and talk to each other in a variety of environments - from servers inside Google to your own desktop - and can be written in any of gRPC's supported languages. So, for example, you can easily create a gRPC server in Java with clients in Go, Python, or Ruby. +In gRPC, like other RPC systems, a *client* application can directly call methods on a *server* application on a different machine as if it was a local object, making it easier for you to create distributed applications and services. As in many RPC systems, gRPC is based around the idea of defining a *service*, specifying the methods that can be called remotely with their parameters and return types. On the server side, the server implements this interface and runs a gRPC server to handle client calls. On the client side, the client has a *stub* that provides exactly the same methods as the server. -### Plays well with Protocol Buffers +##TODO: diagram? + +gRPC clients and servers can run and talk to each other in a variety of environments - from servers inside Google to your own desktop - and can be written in any of gRPC's [supported languages](link to list). So, for example, you can easily create a gRPC server in Java with clients in Go, Python, or Ruby. In addition, the latest Google APIs will have gRPC versions of their interfaces, letting you easily build Google functionality into your applications. + + +### Working with protocol buffers While gRPC’s architecture allows it to be extended for use with other -data formats such as JSON, by default it uses protocol buffers, Google’s +data formats such as JSON, by default it uses *protocol buffers*, Google’s mature open source mechanism for serializing structured data. As you'll -see in our example below, you define gRPC interfaces using proto files and -protocol buffer messages, letting you take advantage of protocol buffers’ -efficient serialization, simple IDL, and easy interface updating. You -can find out lots more about protocol buffers in the [Protocol Buffers -documentation](https://developers.google.com/protocol-buffers/docs/overview). +see in our example below, you define gRPC services using *proto files*, with method parameters and return types specified as protocol buffer message types. You +can find out lots more about protocol buffers in the [Protocol Buffers documentation](https://developers.google.com/protocol-buffers/docs/overview). + +#### Protocol buffer versions -Note that our examples use a new flavour of protocol buffers called proto3, +While protocol buffers have been available for open source users for some time, our examples use a new flavour of protocol buffers called proto3, which has a slightly simplified syntax, some useful new features, and supports lots more languages. This is currently available as an alpha release in -[languages] from [wherever it's going], with more languages in development. In -general, we recommend that you use proto3 with gRPC as it lets you use the -full range of gRPC-supported languages, as well as avoiding any compatibility -issues with proto2 clients talking to proto3 servers and vice versa. +[languages] from [wherever it's going], with more languages in development. -If you need to continue using proto2 for Java, C++, or Python but want +In general, we recommend that you use proto3 with gRPC as it lets you use the +full range of gRPC-supported languages, as well as avoiding compatibility +issues with proto2 clients talking to proto3 servers and vice versa. You can find out more about these potential issues in [where should we put this info? It's important but not really part of an overview]. If you need to continue using proto2 for Java, C++, or Python but want to try gRPC, you can see an example using a proto2 gRPC client and server [wherever we put it]. -## TODO: basic conceptual intro (anything more in-depth will go in gRPC Concepts doc) ## Hello gRPC! @@ -46,9 +48,9 @@ construction of a simple gRPC client-server application, showing you how to: - Create a protocol buffers schema that defines a simple RPC service with a single Hello World method. -- Create a Java server that implements the schema interface. +- Create a Java server that implements thid interface. - Create a Java client that accesses the Java server. -- Create a Go client that accesses the same Java server. +- Create a [probably need a different language now] client that accesses the same Java server. - Update the service with more advanced features like RPC streaming. The complete code for the example is available in the `grpc-common` GitHub repository. You can @@ -134,12 +136,9 @@ with generating the code yourself, download and install protoc from its The first step in creating our example is to define a *service*: an RPC service specifies the methods that can be called remotely with their parameters -and return types. In gRPC, we use the protocol buffers interface definition -language (IDL) to define our service methods, and the parameters and return -types are defined as protocol buffer message types. Both the client and the -server use interface code generated from the service definition. If you're not -familiar with protocol buffers, you can find out more in the [Protocol Buffers -Developer Guide](https://developers.google.com/protocol-buffers/docs/overview). +and return types. As you saw in the [overview](#protocolbuffers) above, gRPC does this using [protocol buffers]((https://developers.google.com/protocol-buffers/docs/overview). We use the protocol buffers interface definition language (IDL) to define our service methods, and define the parameters and return +types as protocol buffer message types. Both the client and the +server use interface code generated from the service definition. Here's our example service definition, defined using protocol buffers IDL in [helloworld.proto](java/src/main/proto/helloworld.proto). The `Greeting` service -- cgit v1.2.3 From e416242fe1fcf43c95496c10da28a0131d102457 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Tue, 17 Feb 2015 16:30:13 +0000 Subject: Tidy formatting --- README.md | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a1575392e0..1820becdf0 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,24 @@ Hello World example. More documentation is coming soon! ## What is gRPC? -In gRPC, like other RPC systems, a *client* application can directly call methods on a *server* application on a different machine as if it was a local object, making it easier for you to create distributed applications and services. As in many RPC systems, gRPC is based around the idea of defining a *service*, specifying the methods that can be called remotely with their parameters and return types. On the server side, the server implements this interface and runs a gRPC server to handle client calls. On the client side, the client has a *stub* that provides exactly the same methods as the server. +In gRPC, like other RPC systems, a *client* application can directly call +methods on a *server* application on a different machine as if it was a +local object, making it easier for you to create distributed applications and +services. As in many RPC systems, gRPC is based around the idea of defining +a *service*, specifying the methods that can be called remotely with their +parameters and return types. On the server side, the server implements this +interface and runs a gRPC server to handle client calls. On the client side, +the client has a *stub* that provides exactly the same methods as the server. ##TODO: diagram? -gRPC clients and servers can run and talk to each other in a variety of environments - from servers inside Google to your own desktop - and can be written in any of gRPC's [supported languages](link to list). So, for example, you can easily create a gRPC server in Java with clients in Go, Python, or Ruby. In addition, the latest Google APIs will have gRPC versions of their interfaces, letting you easily build Google functionality into your applications. +gRPC clients and servers can run and talk to each other in a variety of +environments - from servers inside Google to your own desktop - and can +be written in any of gRPC's [supported languages](link to list). So, for +example, you can easily create a gRPC server in Java with clients in Go, +Python, or Ruby. In addition, the latest Google APIs will have gRPC versions +of their interfaces, letting you easily build Google functionality into +your applications. ### Working with protocol buffers @@ -22,19 +35,26 @@ gRPC clients and servers can run and talk to each other in a variety of environm While gRPC’s architecture allows it to be extended for use with other data formats such as JSON, by default it uses *protocol buffers*, Google’s mature open source mechanism for serializing structured data. As you'll -see in our example below, you define gRPC services using *proto files*, with method parameters and return types specified as protocol buffer message types. You -can find out lots more about protocol buffers in the [Protocol Buffers documentation](https://developers.google.com/protocol-buffers/docs/overview). +see in our example below, you define gRPC services using *proto files*, +with method parameters and return types specified as protocol buffer message +types. You +can find out lots more about protocol buffers in the [Protocol Buffers +documentation](https://developers.google.com/protocol-buffers/docs/overview). #### Protocol buffer versions -While protocol buffers have been available for open source users for some time, our examples use a new flavour of protocol buffers called proto3, +While protocol buffers have been available for open source users for some +time, our examples use a new flavour of protocol buffers called proto3, which has a slightly simplified syntax, some useful new features, and supports lots more languages. This is currently available as an alpha release in [languages] from [wherever it's going], with more languages in development. In general, we recommend that you use proto3 with gRPC as it lets you use the full range of gRPC-supported languages, as well as avoiding compatibility -issues with proto2 clients talking to proto3 servers and vice versa. You can find out more about these potential issues in [where should we put this info? It's important but not really part of an overview]. If you need to continue using proto2 for Java, C++, or Python but want +issues with proto2 clients talking to proto3 servers and vice versa. You +can find out more about these potential issues in [where should we put this +info? It's important but not really part of an overview]. If you need to +continue using proto2 for Java, C++, or Python but want to try gRPC, you can see an example using a proto2 gRPC client and server [wherever we put it]. @@ -83,9 +103,11 @@ the code to hack on #### Get the source code -The example code for this and our other examples lives in the `grpc-common` GitHub repository. Clone this repository to your local machine by running the +The example code for this and our other examples lives in the `grpc-common` +GitHub repository. Clone this repository to your local machine by running the following command: + ``` git clone https://github.com/google/grpc-common.git ``` @@ -136,13 +158,17 @@ with generating the code yourself, download and install protoc from its The first step in creating our example is to define a *service*: an RPC service specifies the methods that can be called remotely with their parameters -and return types. As you saw in the [overview](#protocolbuffers) above, gRPC does this using [protocol buffers]((https://developers.google.com/protocol-buffers/docs/overview). We use the protocol buffers interface definition language (IDL) to define our service methods, and define the parameters and return +and return types. As you saw in the +[overview](#protocolbuffers) above, gRPC does this using [protocol +buffers]((https://developers.google.com/protocol-buffers/docs/overview). We +use the protocol buffers interface definition language (IDL) to define our +service methods, and define the parameters and return types as protocol buffer message types. Both the client and the server use interface code generated from the service definition. Here's our example service definition, defined using protocol buffers IDL in -[helloworld.proto](java/src/main/proto/helloworld.proto). The `Greeting` service -has one method, `hello`, that lets the server receive a single `HelloRequest` +[helloworld.proto](java/src/main/proto/helloworld.proto). The `Greeting` +service has one method, `hello`, that lets the server receive a single `HelloRequest` message from the remote client containing the user's name, then send back a greeting in a single `HelloReply`. This is the simplest type of RPC you can specify in gRPC - we'll look at some other types later in this document. -- cgit v1.2.3 From b789acd2d2ce0d94064527c2890db4887140616f Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Tue, 17 Feb 2015 16:41:45 +0000 Subject: Fixed typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1820becdf0..fdbd1f0de0 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,7 @@ The first step in creating our example is to define a *service*: an RPC service specifies the methods that can be called remotely with their parameters and return types. As you saw in the [overview](#protocolbuffers) above, gRPC does this using [protocol -buffers]((https://developers.google.com/protocol-buffers/docs/overview). We +buffers](https://developers.google.com/protocol-buffers/docs/overview). We use the protocol buffers interface definition language (IDL) to define our service methods, and define the parameters and return types as protocol buffer message types. Both the client and the -- cgit v1.2.3 From 23307f261c68a9b1f85892720f697d44df1fc06d Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 04:12:18 -0800 Subject: Adds a route guide sample proto --- protos/route_guide.proto | 124 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 protos/route_guide.proto diff --git a/protos/route_guide.proto b/protos/route_guide.proto new file mode 100644 index 0000000000..0850239d01 --- /dev/null +++ b/protos/route_guide.proto @@ -0,0 +1,124 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "ex.grpc"; + +package examples; + +// Points are represented as latitude-longitude pairs in the E7 representation +// (degrees multiplied by 10**7 and rounded to the nearest integer). +// Latitudes should be in the range +/- 90 degrees and longitude should be in +// the range +/- 180 degrees (inclusive). +message Point { + optional int32 latitude = 1; + optional int32 longitude = 2; +} + +// A latitude-longitude rectangle, represented as two diagonally opposite +// points "lo" and "hi". +message Rectangle { + // One corner of the rectangle. + optional Point lo = 1; + + // The other corner of the rectangle. + optional Point hi = 2; +} + +// A feature names something at a given point. +// +// If a feature could not be named, the name value is blank. +message Feature { + // The name of the feature. + optional string name = 1; + + // The point where the feature is detected. + optional Point location = 2; +} + +// A RouteNote is a message sent while at a given point. +message RouteNote { + // The location at from which the message is sent. + optional Point location = 1; + + // The message to be sent + optional string message = 2; +} + +// Route summary is the message received in response to a RecordRoute rpc. +// +// It details the number of individual points received, the number of detected +// features and the total distance covered as the cumulative sum of the +// distance between each point. +message RouteSummary { + // The number of points received. + optional int32 point_count = 1; + + // The number of known features passed while traversing the route. + optional int32 feature_count = 2; + + // The distance covered in metres. + optional int32 distance = 3; + + // The duration of the traversal in seconds. + optional int32 elapsed_time = 4; +} + +// Interface exported by the server +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) { + } + + // A server-to-client streaming RPC. + // + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) { + } + + // A client-to-server streaming RPC. + // + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) { + } + + // Bidirectional streaming RPC. + // + // Accepts a streams of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) { + } +} -- cgit v1.2.3 From 9ab2c8b5bac6d2fd905a9ca341d3d44b935ae994 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 08:08:15 -0800 Subject: Another pass at the docs --- protos/route_guide.proto | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/protos/route_guide.proto b/protos/route_guide.proto index 0850239d01..57576937a6 100644 --- a/protos/route_guide.proto +++ b/protos/route_guide.proto @@ -54,7 +54,7 @@ message Rectangle { // A feature names something at a given point. // -// If a feature could not be named, the name value is blank. +// If a feature could not be named, the name is empty. message Feature { // The name of the feature. optional string name = 1; @@ -65,18 +65,18 @@ message Feature { // A RouteNote is a message sent while at a given point. message RouteNote { - // The location at from which the message is sent. + // The location from which the message is sent. optional Point location = 1; - // The message to be sent + // The message to be sent. optional string message = 2; } -// Route summary is the message received in response to a RecordRoute rpc. +// A RouteSummary is received in response to a RecordRoute rpc. // -// It details the number of individual points received, the number of detected -// features and the total distance covered as the cumulative sum of the -// distance between each point. +// It contains the number of individual points received, the number of +// detected features, and the total distance covered as the cumulative sum of +// the distance between each point. message RouteSummary { // The number of points received. optional int32 point_count = 1; @@ -115,9 +115,9 @@ service RouteGuide { rpc RecordRoute(stream Point) returns (RouteSummary) { } - // Bidirectional streaming RPC. + // A Bidirectional streaming RPC. // - // Accepts a streams of RouteNotes sent while a route is being traversed, + // Accepts a stream of RouteNotes sent while a route is being traversed, // while receiving other RouteNotes (e.g. from other users). rpc RouteChat(stream RouteNote) returns (stream RouteNote) { } -- cgit v1.2.3 From 66e79fa3618f8987fa9398eb2321fe89f42326e6 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 14:07:48 -0800 Subject: Cleans up helloworld.proto --- protos/helloworld.proto | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/protos/helloworld.proto b/protos/helloworld.proto index aa44b851f4..86402ad71f 100644 --- a/protos/helloworld.proto +++ b/protos/helloworld.proto @@ -33,19 +33,18 @@ option java_package = "ex.grpc"; package helloworld; +// The greeting service definition. +service Greetings { + // Sends a greeting + rpc hello (HelloRequest) returns (HelloReply) {} +} + // The request message containing the user's name. message HelloRequest { - optional string name = 1; + string name = 1; } // The response message containing the greetings message HelloReply { - optional string message = 1; -} - -// The greeting service definition. -service Greetings { - // Sends a greeting - rpc hello (HelloRequest) returns (HelloReply) { - } + string message = 1; } -- cgit v1.2.3 From c1ee3824b4a20a31fce4cd53ae69128e2d28bdc6 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 14:15:05 -0800 Subject: Cleans up route_guide.proto --- protos/route_guide.proto | 84 +++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/protos/route_guide.proto b/protos/route_guide.proto index 57576937a6..7cda80efad 100644 --- a/protos/route_guide.proto +++ b/protos/route_guide.proto @@ -33,23 +33,51 @@ option java_package = "ex.grpc"; package examples; +// Interface exported by the server. +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} + + // A server-to-client streaming RPC. + // + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} + + // A client-to-server streaming RPC. + // + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} + + // A Bidirectional streaming RPC. + // + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +} + // Points are represented as latitude-longitude pairs in the E7 representation // (degrees multiplied by 10**7 and rounded to the nearest integer). // Latitudes should be in the range +/- 90 degrees and longitude should be in // the range +/- 180 degrees (inclusive). message Point { - optional int32 latitude = 1; - optional int32 longitude = 2; + int32 latitude = 1; + int32 longitude = 2; } // A latitude-longitude rectangle, represented as two diagonally opposite // points "lo" and "hi". message Rectangle { // One corner of the rectangle. - optional Point lo = 1; + Point lo = 1; // The other corner of the rectangle. - optional Point hi = 2; + Point hi = 2; } // A feature names something at a given point. @@ -57,19 +85,19 @@ message Rectangle { // If a feature could not be named, the name is empty. message Feature { // The name of the feature. - optional string name = 1; + string name = 1; // The point where the feature is detected. - optional Point location = 2; + Point location = 2; } // A RouteNote is a message sent while at a given point. message RouteNote { // The location from which the message is sent. - optional Point location = 1; + Point location = 1; // The message to be sent. - optional string message = 2; + string message = 2; } // A RouteSummary is received in response to a RecordRoute rpc. @@ -79,46 +107,14 @@ message RouteNote { // the distance between each point. message RouteSummary { // The number of points received. - optional int32 point_count = 1; + int32 point_count = 1; // The number of known features passed while traversing the route. - optional int32 feature_count = 2; + int32 feature_count = 2; // The distance covered in metres. - optional int32 distance = 3; + int32 distance = 3; // The duration of the traversal in seconds. - optional int32 elapsed_time = 4; -} - -// Interface exported by the server -service RouteGuide { - // A simple RPC. - // - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) { - } - - // A server-to-client streaming RPC. - // - // Obtains the Features available within the given Rectangle. Results are - // streamed rather than returned at once (e.g. in a response message with a - // repeated field), as the rectangle may cover a large area and contain a - // huge number of features. - rpc ListFeatures(Rectangle) returns (stream Feature) { - } - - // A client-to-server streaming RPC. - // - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) { - } - - // A Bidirectional streaming RPC. - // - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) { - } + int32 elapsed_time = 4; } -- cgit v1.2.3 From c5a093c784e1c686bcd9731158d2323d04da19c1 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 14:28:50 -0800 Subject: Renames method and service name --- protos/helloworld.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protos/helloworld.proto b/protos/helloworld.proto index 86402ad71f..4781fb4830 100644 --- a/protos/helloworld.proto +++ b/protos/helloworld.proto @@ -34,9 +34,9 @@ option java_package = "ex.grpc"; package helloworld; // The greeting service definition. -service Greetings { +service Greeter { // Sends a greeting - rpc hello (HelloRequest) returns (HelloReply) {} + rpc sayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. -- cgit v1.2.3 From 01acb4cc49cf72d51594410a709ef7ad6a857627 Mon Sep 17 00:00:00 2001 From: louiscryan Date: Wed, 18 Feb 2015 15:34:00 -0800 Subject: Initial checkin of protocol draft. --- PROTOCOL-HTTP2.md | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 PROTOCOL-HTTP2.md diff --git a/PROTOCOL-HTTP2.md b/PROTOCOL-HTTP2.md new file mode 100644 index 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 ABNF syntax. + +### Outline + +The following is the general sequence of message atoms in a GRPC request & response message stream + +* Request → Request-Headers *Delimited-Message EOS +* Response → (Response-Headers *Delimited-Message Trailers) / Trailers-Only + + +### Requests + +* Request → Request-Headers *Delimited-Message EOS + +Request-Headers are delivered as HTTP2 headers in HEADERS + CONTINUATION frames. + +* **Request-Headers** → Call-Definition *Custom-Metadata +* **Call-Definition** → Method Scheme Path TE [Authority] [Timeout] [Content-Type] [Message-Type] [Message-Encoding] [User-Agent] +* **Method** → “:method POST” +* **Scheme** → “:scheme ” (“http” / “https”) +* **Path** → “:path” {_path identifying method within exposed API_} +* **Authority** → “:authority” {_virtual host name of authority_} +* **TE** → “te” “trailers” # Used to detect incompatible proxies +* **Timeout** → “grpc-timeout” TimeoutValue TimeoutUnit +* **TimeoutValue** → {_positive integer as ASCII string of at most 8 digits_} +* **TimeoutUnit** → Hour / Minute / Second / Millisecond / Microsecond / Nanosecond +* **Hour** → “H” +* **Minute** → “M” +* **Second** → “S” +* **Millisecond** → “m” +* **Microsecond** → “u” +* **Nanosecond** → “n” +* **Content-Type** → “content-type” “application/grpc” [(“+proto” / “+json” / {_custom_})] +* **Message-Encoding** → “grpc-encoding ” (“gzip” / “deflate” / “snappy” / {_custom_} ) +* **User-Agent** → “user-agent” {_structured user-agent string_} +* **Message-Type** → “grpc-message-type” {_type name for message schema_} +* **Custom-Metadata** → Binary-Header / ASCII-Header +* **Binary-Header** → {lowercase ASCII header name ending in “-bin” } {_base64 encoded value_} +* **ASCII-Header** → {lowercase ASCII header name} {_value_} + + +HTTP2 requires that reserved headers, ones starting with “:” appear before all other headers. Additionally implementations should send **Timeout** immediately after the reserved headers and they should send the **Call-Definition** headers before sending **Custom-Metadata**. + +If **Timeout** is omitted a server should assume an infinite timeout. Client implementations are free to send a default minimum timeout based on their deployment requirements. + +**Custom-Metadata** is an arbitrary set of key-value pairs defined by the application layer. Aside from transport limits on the total length of HTTP2 HEADERS the only other constraint is that header names starting with “grpc-” are reserved for future use. + +Note that HTTP2 does not allow arbitrary octet sequences for header values so binary header values must be encoded using Base64 as per https://tools.ietf.org/html/rfc4648#section-4. Implementations MUST accept padded and un-padded values and should emit un-padded values. Applications define binary headers by having their names end with “-bin”. Runtime libraries use this suffix to detect binary headers and properly apply base64 encoding & decoding as headers are sent and received. + +The repeated sequence of **Delimited-Message** items is delivered in DATA frames + +* **Delimited-Message** → Compressed-Flag Message-Length Message +* **Compressed-Flag** → 0 / 1 # encoded as 1 byte unsigned integer +* **Message-Length** → {_length of Message_} # encoded as 4 byte unsigned integer +* **Message** → *{binary octet} + +A **Compressed-Flag** value of 1 indicates that the binary octet sequence of **Message** is compressed using the mechanism declared by the **Message-Encoding** header. A value of 0 indicates that no encoding of **Message** bytes has occurred. Compression contexts are NOT maintained over message boundaries, implementations must create a new context for each message in the stream. If the **Message-Encoding** header is omitted then the **Compressed-Flag** must be 0. + +For requests, **EOS** (end-of-stream) is indicated by the presence of the END_STREAM flag on the last received DATA frame. In scenarios where the **Request** stream needs to be closed but no data remains to be sent implementations MUST send an empty DATA frame with this flag set. + +###Responses + +* **Response** → (Response-Headers *Delimited-Message Trailers) / Trailers-Only +* **Response-Headers** → HTTP-Status [Message-Encoding] Content-Type *Custom-Metadata +* **Trailers-Only** → HTTP-Status Content-Type Trailers +* **Trailers** → Status [Status-Message] *Custom-Metadata +* **HTTP-Status** → “:status 200” +* **Status** → “grpc-status” +* **Status-Message** → “grpc-message” + +**Response-Headers** & **Trailers-Only** are each delivered in a single HTTP2 HEADERS frame block. Most responses are expected to have both headers and trailers but **Trailers-Only** is permitted for calls that produce an immediate error. Status must be sent in **Trailers** even if the status code is OK. + +For responses end-of-stream is indicated by the presence of the END_STREAM flag on the last received HEADERS frame that carries **Trailers**. + +Implementations should expect broken deployments to send non-200 HTTP status codes in responses as well as a variety of non-GRPC content-types and to omit **Status** & **Status-Message**. Implementations must synthesize a **Status** & **Status-Message** to propagate to the application layer when this occurs. + +####Example + +Sample unary-call showing HTTP2 framing sequence + +**Request** + +``` +HEADERS (flags = END_HEADERS) +:method = POST +:scheme = http +:path = /google.pubsub.v2.PublisherService/CreateTopic +:authority = pubsub.googleapis.com +grpc-timeout = 1S +content-type = application/grpc+proto +grpc-encoding = gzip +authorization = Bearer y235.wef315yfh138vh31hv93hv8h3v + +DATA (flags = END_STREAM) + +``` +**Response** +``` +HEADERS (flags = END_HEADERS) +:status = 200 +grpc-encoding = gzip + +DATA + + +HEADERS (flags = END_STREAM, END_HEADERS) +grpc-status = 0 # OK +trace-proto-bin = jher831yy13JHy3hc +``` +####User Agents + +While the protocol does not require a user-agent to function it is recommended that clients provide a structured user-agent string that provides a basic description of the calling library, version & platform to facilitate issue diagnosis in heterogeneous environments. The following structure is recommended to library developers +``` +User-Agent → “grpc-” Language ?(“-” Variant) “/” Version ?( “ (“ *(AdditionalProperty “;”) “)” ) +``` +E.g. + +``` +grpc-java/1.2.3 +grpc-ruby/1.2.3 +grpc-ruby-jruby/1.3.4 +grpc-java-android/0.9.1 (gingerbread/1.2.4; nexus5; tmobile) +``` +####HTTP2 Transport Mapping + +#####Stream Identification +All GRPC calls need to specify an internal ID. We will use HTTP2 stream-ids as call identifiers in this scheme. NOTE: These id’s are contextual to an open HTTP2 session and will not be unique within a given process that is handling more than one HTTP2 session nor can they be used as GUIDs. + +#####Data Frames +DATA frame boundaries have no relation to **Delimited-Message** boundaries and implementations should make no assumptions about their alignment. + +#####Errors + +When an application or runtime error occurs during an RPC a **Status** and **Status-Message** are delivered in **Trailers**. + +In some cases it is possible that the framing of the message stream has become corrupt and the RPC runtime will choose to use an **RST_STREAM** frame to indicate this state to its peer. RPC runtime implementations should interpret RST_STREAM as immediate full-closure of the stream and should propagate an error up to the calling application layer. + +The following mapping from RST_STREAM error codes to GRPC error codes is applied. + +HTTP2 Code|GRPC Code +----------|----------- +NO_ERROR(0)|INTERNAL - An explicit GRPC status of OK should have been sent but this might be used to aggressively lameduck in some scenarios. +PROTOCOL_ERROR(1)|INTERNAL +INTERNAL_ERROR(2)|INTERNAL +FLOW_CONTROL_ERROR(3)|INTERNAL +SETTINGS_TIMEOUT(4)|INTERNAL +STREAM_CLOSED|No mapping as there is no open stream to propagate to. Implementations should log. +FRAME_SIZE_ERROR|INTERNAL +REFUSED_STREAM|UNAVAILABLE - Indicates that no processing occurred and the request can be retried, possibly elsewhere. +CANCEL(8)|Mapped to call cancellation when sent by a client.Mapped to CANCELLED when sent by a server. Note that servers should only use this mechanism when they need to cancel a call but the payload byte sequence is incomplete. +COMPRESSION_ERROR|INTERNAL +CONNECT_ERROR|INTERNAL +ENHANCE_YOUR_CALM|RESOURCE_EXHAUSTED ...with additional error detail provided by runtime to indicate that the exhausted resource is bandwidth. +INADEQUATE_SECURITY| PERMISSION_DENIED … with additional detail indicating that permission was denied as protocol is not secure enough for call. + + +#####Security + +The HTTP2 specification mandates the use of TLS 1.2 or higher when TLS is used with HTTP2. It also places some additional constraints on the allowed ciphers in deployments to avoid known-problems as well as requiring SNI support. It is also expected that HTTP2 will be used in conjunction with proprietary transport security mechanisms about which the specification can make no meaningful recommendations. + +#####Connection Management +######GOAWAY Frame +Sent by servers to clients to indicate that they will no longer accept any new streams on the associated connections. This frame includes the id of the last successfully accepted stream by the server. Clients should consider any stream initiated after the last successfully accepted stream as UNAVAILABLE and retry the call elsewhere. Clients are free to continue working with the already accepted streams until they complete or the connection is terminated. + +Servers should send GOAWAY before terminating a connection to reliably inform clients which work has been accepted by the server and is being executed. + +######PING Frame +Both clients and servers can send a PING frame that the peer must respond to by precisely echoing what they received. This is used to assert that the connection is still live as well as providing a means to estimate end-to-end latency. If a server initiated PING does not receive a response within the deadline expected by the runtime all outstanding calls on the server will be closed with a CANCELLED status. An expired client initiated PING will cause all calls to be closed with an UNAVAILABLE status. Note that the frequency of PINGs is highly dependent on the network environment, implementations are free to adjust PING frequency based on network and application requirements. + +######Connection failure +If a detectable connection failure occurs on the client all calls will be closed with an UNAVAILABLE status. For servers open calls will be closed with a CANCELLED status. + + +### Appendix A - GRPC for Protobuf + +The service interfaces declared by protobuf are easily mapped onto GRPC by code generation extensions to protoc. The following defines the mapping to be used + + +* **Path** → / Service-Name / {_method name_} +* **Service-Name** → ?( {_proto package name_} "." ) {_service name_} +* **Message-Type** → {_fully qualified proto message name_} +* **Content-Type** → "application/grpc+proto" + + -- cgit v1.2.3 From 87faa1cf45e498dd2b5969eb39bcbda89ab7eddd Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 17:22:46 -0800 Subject: Updates generated code to reflect the proto changes in #19 --- java/src/main/java/ex/grpc/GreeterGrpc.java | 172 ++++++++++++++++++++++++ java/src/main/java/ex/grpc/GreeterImpl.java | 16 +++ java/src/main/java/ex/grpc/GreetingsClient.java | 6 +- java/src/main/java/ex/grpc/GreetingsGrpc.java | 172 ------------------------ java/src/main/java/ex/grpc/GreetingsImpl.java | 16 --- java/src/main/java/ex/grpc/GreetingsServer.java | 2 +- java/src/main/java/ex/grpc/Helloworld.java | 12 +- 7 files changed, 198 insertions(+), 198 deletions(-) create mode 100644 java/src/main/java/ex/grpc/GreeterGrpc.java create mode 100644 java/src/main/java/ex/grpc/GreeterImpl.java delete mode 100644 java/src/main/java/ex/grpc/GreetingsGrpc.java delete mode 100644 java/src/main/java/ex/grpc/GreetingsImpl.java diff --git a/java/src/main/java/ex/grpc/GreeterGrpc.java b/java/src/main/java/ex/grpc/GreeterGrpc.java new file mode 100644 index 0000000000..080c3dfc43 --- /dev/null +++ b/java/src/main/java/ex/grpc/GreeterGrpc.java @@ -0,0 +1,172 @@ +package ex.grpc; + +import static com.google.net.stubby.stub.Calls.createMethodDescriptor; +import static com.google.net.stubby.stub.Calls.asyncUnaryCall; +import static com.google.net.stubby.stub.Calls.asyncServerStreamingCall; +import static com.google.net.stubby.stub.Calls.asyncClientStreamingCall; +import static com.google.net.stubby.stub.Calls.duplexStreamingCall; +import static com.google.net.stubby.stub.Calls.blockingUnaryCall; +import static com.google.net.stubby.stub.Calls.blockingServerStreamingCall; +import static com.google.net.stubby.stub.Calls.unaryFutureCall; +import static com.google.net.stubby.stub.ServerCalls.createMethodDefinition; +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 GreeterGrpc { + + private static final com.google.net.stubby.stub.Method METHOD_SAY_HELLO = + com.google.net.stubby.stub.Method.create( + 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 GreeterStub newStub(com.google.net.stubby.Channel channel) { + return new GreeterStub(channel, CONFIG); + } + + public static GreeterBlockingStub newBlockingStub( + com.google.net.stubby.Channel channel) { + return new GreeterBlockingStub(channel, CONFIG); + } + + public static GreeterFutureStub newFutureStub( + com.google.net.stubby.Channel channel) { + return new GreeterFutureStub(channel, CONFIG); + } + + public static final GreeterServiceDescriptor CONFIG = + new GreeterServiceDescriptor(); + + @javax.annotation.concurrent.Immutable + public static class GreeterServiceDescriptor extends + com.google.net.stubby.stub.AbstractServiceDescriptor { + public final com.google.net.stubby.MethodDescriptor sayHello; + + private GreeterServiceDescriptor() { + sayHello = createMethodDescriptor( + "helloworld.Greeter", METHOD_SAY_HELLO); + } + + private GreeterServiceDescriptor( + java.util.Map> methodMap) { + sayHello = (com.google.net.stubby.MethodDescriptor) methodMap.get( + CONFIG.sayHello.getName()); + } + + @java.lang.Override + protected GreeterServiceDescriptor build( + java.util.Map> methodMap) { + return new GreeterServiceDescriptor(methodMap); + } + + @java.lang.Override + public com.google.common.collect.ImmutableList> methods() { + return com.google.common.collect.ImmutableList.>of( + sayHello); + } + } + + public static interface Greeter { + + public void sayHello(ex.grpc.Helloworld.HelloRequest request, + com.google.net.stubby.stub.StreamObserver responseObserver); + } + + public static interface GreeterBlockingClient { + + public ex.grpc.Helloworld.HelloReply sayHello(ex.grpc.Helloworld.HelloRequest request); + } + + public static interface GreeterFutureClient { + + public com.google.common.util.concurrent.ListenableFuture sayHello( + ex.grpc.Helloworld.HelloRequest request); + } + + public static class GreeterStub extends + com.google.net.stubby.stub.AbstractStub + implements Greeter { + private GreeterStub(com.google.net.stubby.Channel channel, + GreeterServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected GreeterStub build(com.google.net.stubby.Channel channel, + GreeterServiceDescriptor config) { + return new GreeterStub(channel, config); + } + + @java.lang.Override + public void sayHello(ex.grpc.Helloworld.HelloRequest request, + com.google.net.stubby.stub.StreamObserver responseObserver) { + asyncUnaryCall( + channel.newCall(config.sayHello), request, responseObserver); + } + } + + public static class GreeterBlockingStub extends + com.google.net.stubby.stub.AbstractStub + implements GreeterBlockingClient { + private GreeterBlockingStub(com.google.net.stubby.Channel channel, + GreeterServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected GreeterBlockingStub build(com.google.net.stubby.Channel channel, + GreeterServiceDescriptor config) { + return new GreeterBlockingStub(channel, config); + } + + @java.lang.Override + public ex.grpc.Helloworld.HelloReply sayHello(ex.grpc.Helloworld.HelloRequest request) { + return blockingUnaryCall( + channel.newCall(config.sayHello), request); + } + } + + public static class GreeterFutureStub extends + com.google.net.stubby.stub.AbstractStub + implements GreeterFutureClient { + private GreeterFutureStub(com.google.net.stubby.Channel channel, + GreeterServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected 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 sayHello( + ex.grpc.Helloworld.HelloRequest request) { + return unaryFutureCall( + channel.newCall(config.sayHello), request); + } + } + + public static com.google.net.stubby.ServerServiceDefinition bindService( + final Greeter serviceImpl) { + return com.google.net.stubby.ServerServiceDefinition.builder("helloworld.Greeter") + .addMethod(createMethodDefinition( + METHOD_SAY_HELLO, + asyncUnaryRequestCall( + new com.google.net.stubby.stub.ServerCalls.UnaryRequestMethod< + ex.grpc.Helloworld.HelloRequest, + ex.grpc.Helloworld.HelloReply>() { + @java.lang.Override + public void invoke( + ex.grpc.Helloworld.HelloRequest request, + com.google.net.stubby.stub.StreamObserver responseObserver) { + serviceImpl.sayHello(request, responseObserver); + } + }))).build(); + } +} diff --git a/java/src/main/java/ex/grpc/GreeterImpl.java b/java/src/main/java/ex/grpc/GreeterImpl.java new file mode 100644 index 0000000000..825ba8631e --- /dev/null +++ b/java/src/main/java/ex/grpc/GreeterImpl.java @@ -0,0 +1,16 @@ +package ex.grpc; + +import com.google.net.stubby.stub.StreamObserver; + +public class GreeterImpl implements GreeterGrpc.Greeter { + + @Override + public void sayHello(Helloworld.HelloRequest req, + StreamObserver responseObserver) { + Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( + "Hello " + req.getName()).build(); + responseObserver.onValue(reply); + responseObserver.onCompleted(); + } + +} diff --git a/java/src/main/java/ex/grpc/GreetingsClient.java b/java/src/main/java/ex/grpc/GreetingsClient.java index 4ae2e7076b..141ad1e20a 100644 --- a/java/src/main/java/ex/grpc/GreetingsClient.java +++ b/java/src/main/java/ex/grpc/GreetingsClient.java @@ -13,13 +13,13 @@ public class GreetingsClient { private final Logger logger = Logger.getLogger( GreetingsClient.class.getName()); private final ChannelImpl channel; - private final GreetingsGrpc.GreetingsBlockingStub blockingStub; + private final GreeterGrpc.GreeterBlockingStub blockingStub; public GreetingsClient(String host, int port) { channel = NettyChannelBuilder.forAddress(host, port) .negotiationType(NegotiationType.PLAINTEXT) .build(); - blockingStub = GreetingsGrpc.newBlockingStub(channel); + blockingStub = GreeterGrpc.newBlockingStub(channel); } public void shutdown() throws InterruptedException { @@ -31,7 +31,7 @@ public class GreetingsClient { logger.fine("Will try to greet " + name + " ..."); Helloworld.HelloRequest req = Helloworld.HelloRequest.newBuilder().setName(name).build(); - Helloworld.HelloReply reply = blockingStub.hello(req); + Helloworld.HelloReply reply = blockingStub.sayHello(req); logger.info("Greeting: " + reply.getMessage()); } catch (RuntimeException e) { logger.log(Level.WARNING, "RPC failed", e); diff --git a/java/src/main/java/ex/grpc/GreetingsGrpc.java b/java/src/main/java/ex/grpc/GreetingsGrpc.java deleted file mode 100644 index 97c2f00a1e..0000000000 --- a/java/src/main/java/ex/grpc/GreetingsGrpc.java +++ /dev/null @@ -1,172 +0,0 @@ -package ex.grpc; - -import static com.google.net.stubby.stub.Calls.createMethodDescriptor; -import static com.google.net.stubby.stub.Calls.asyncUnaryCall; -import static com.google.net.stubby.stub.Calls.asyncServerStreamingCall; -import static com.google.net.stubby.stub.Calls.asyncClientStreamingCall; -import static com.google.net.stubby.stub.Calls.duplexStreamingCall; -import static com.google.net.stubby.stub.Calls.blockingUnaryCall; -import static com.google.net.stubby.stub.Calls.blockingServerStreamingCall; -import static com.google.net.stubby.stub.Calls.unaryFutureCall; -import static com.google.net.stubby.stub.ServerCalls.createMethodDefinition; -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 { - - private static final com.google.net.stubby.stub.Method METHOD_HELLO = - com.google.net.stubby.stub.Method.create( - com.google.net.stubby.MethodType.UNARY, "hello", - 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 GreetingsBlockingStub newBlockingStub( - com.google.net.stubby.Channel channel) { - return new GreetingsBlockingStub(channel, CONFIG); - } - - public static GreetingsFutureStub newFutureStub( - com.google.net.stubby.Channel channel) { - return new GreetingsFutureStub(channel, CONFIG); - } - - public static final GreetingsServiceDescriptor CONFIG = - new GreetingsServiceDescriptor(); - - @javax.annotation.concurrent.Immutable - public static class GreetingsServiceDescriptor extends - com.google.net.stubby.stub.AbstractServiceDescriptor { - public final com.google.net.stubby.MethodDescriptor hello; - - private GreetingsServiceDescriptor() { - hello = createMethodDescriptor( - "helloworld.Greetings", METHOD_HELLO); - } - - private GreetingsServiceDescriptor( - java.util.Map> methodMap) { - hello = (com.google.net.stubby.MethodDescriptor) methodMap.get( - CONFIG.hello.getName()); - } - - @java.lang.Override - protected GreetingsServiceDescriptor build( - java.util.Map> methodMap) { - return new GreetingsServiceDescriptor(methodMap); - } - - @java.lang.Override - public com.google.common.collect.ImmutableList> methods() { - return com.google.common.collect.ImmutableList.>of( - hello); - } - } - - public static interface Greetings { - - public void hello(ex.grpc.Helloworld.HelloRequest request, - com.google.net.stubby.stub.StreamObserver responseObserver); - } - - public static interface GreetingsBlockingClient { - - public ex.grpc.Helloworld.HelloReply hello(ex.grpc.Helloworld.HelloRequest request); - } - - public static interface GreetingsFutureClient { - - public com.google.common.util.concurrent.ListenableFuture hello( - ex.grpc.Helloworld.HelloRequest request); - } - - public static class GreetingsStub extends - com.google.net.stubby.stub.AbstractStub - implements Greetings { - private GreetingsStub(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { - super(channel, config); - } - - @java.lang.Override - protected GreetingsStub build(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { - return new GreetingsStub(channel, config); - } - - @java.lang.Override - public void hello(ex.grpc.Helloworld.HelloRequest request, - com.google.net.stubby.stub.StreamObserver responseObserver) { - asyncUnaryCall( - channel.newCall(config.hello), request, responseObserver); - } - } - - public static class GreetingsBlockingStub extends - com.google.net.stubby.stub.AbstractStub - implements GreetingsBlockingClient { - private GreetingsBlockingStub(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { - super(channel, config); - } - - @java.lang.Override - protected GreetingsBlockingStub build(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { - return new GreetingsBlockingStub(channel, config); - } - - @java.lang.Override - public ex.grpc.Helloworld.HelloReply hello(ex.grpc.Helloworld.HelloRequest request) { - return blockingUnaryCall( - channel.newCall(config.hello), request); - } - } - - public static class GreetingsFutureStub extends - com.google.net.stubby.stub.AbstractStub - implements GreetingsFutureClient { - private GreetingsFutureStub(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { - super(channel, config); - } - - @java.lang.Override - protected GreetingsFutureStub build(com.google.net.stubby.Channel channel, - GreetingsServiceDescriptor config) { - return new GreetingsFutureStub(channel, config); - } - - @java.lang.Override - public com.google.common.util.concurrent.ListenableFuture hello( - ex.grpc.Helloworld.HelloRequest request) { - return unaryFutureCall( - channel.newCall(config.hello), request); - } - } - - public static com.google.net.stubby.ServerServiceDefinition bindService( - final Greetings serviceImpl) { - return com.google.net.stubby.ServerServiceDefinition.builder("helloworld.Greetings") - .addMethod(createMethodDefinition( - METHOD_HELLO, - asyncUnaryRequestCall( - new com.google.net.stubby.stub.ServerCalls.UnaryRequestMethod< - ex.grpc.Helloworld.HelloRequest, - ex.grpc.Helloworld.HelloReply>() { - @java.lang.Override - public void invoke( - ex.grpc.Helloworld.HelloRequest request, - com.google.net.stubby.stub.StreamObserver responseObserver) { - serviceImpl.hello(request, responseObserver); - } - }))).build(); - } -} diff --git a/java/src/main/java/ex/grpc/GreetingsImpl.java b/java/src/main/java/ex/grpc/GreetingsImpl.java deleted file mode 100644 index 005489acaa..0000000000 --- a/java/src/main/java/ex/grpc/GreetingsImpl.java +++ /dev/null @@ -1,16 +0,0 @@ -package ex.grpc; - -import com.google.net.stubby.stub.StreamObserver; - -public class GreetingsImpl implements GreetingsGrpc.Greetings { - - @Override - public void hello(Helloworld.HelloRequest req, - StreamObserver responseObserver) { - Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( - "Hello " + req.getName()).build(); - responseObserver.onValue(reply); - responseObserver.onCompleted(); - } - -} diff --git a/java/src/main/java/ex/grpc/GreetingsServer.java b/java/src/main/java/ex/grpc/GreetingsServer.java index 834ae985a4..237309d13c 100644 --- a/java/src/main/java/ex/grpc/GreetingsServer.java +++ b/java/src/main/java/ex/grpc/GreetingsServer.java @@ -16,7 +16,7 @@ public class GreetingsServer { private void start() throws Exception { server = NettyServerBuilder.forPort(port) - .addService(GreetingsGrpc.bindService(new GreetingsImpl())) + .addService(GreeterGrpc.bindService(new GreeterImpl())) .build(); server.startAsync(); server.awaitRunning(5, TimeUnit.SECONDS); diff --git a/java/src/main/java/ex/grpc/Helloworld.java b/java/src/main/java/ex/grpc/Helloworld.java index 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() { -- cgit v1.2.3 From 2604848108f26d4b4a38ca9316db376d5e470634 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 17:31:03 -0800 Subject: Updates the main to reflect the proto changes in #19 --- README.md | 57 ++++++++++++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index fdbd1f0de0..1203465660 100644 --- a/README.md +++ b/README.md @@ -247,26 +247,26 @@ we need to create our example: - [`Helloworld.java`](java/src/main/java/ex/grpc/Helloworld.java), which has all the protocol buffer code to populate, serialize, and retrieve our `HelloRequest` and `HelloReply` message types -- [`GreetingsGrpc.java`](java/src/main/java/ex/grpc/GreetingsGrpc.java), +- [`GreeterGrpc.java`](java/src/main/java/ex/grpc/GreeterGrpc.java), which contains (along with some other useful code): - - an interface for `Greetings` servers to implement + - an interface for `Greeter` servers to implement ```java - public static interface Greetings { + public static interface Greeter { - public void hello(ex.grpc.Helloworld.HelloRequest request, + public void sayHello(ex.grpc.Helloworld.HelloRequest request, com.google.net.stubby.stub.StreamObserver responseObserver); } ``` - - _stub_ classes that clients can use to talk to a `Greetings` server. As you can see, they also implement the `Greetings` interface. + - _stub_ classes that clients can use to talk to a `Greeter` server. As you can see, they also implement the `Greeter` interface. ```java -public static class GreetingsStub extends - com.google.net.stubby.stub.AbstractStub - implements Greetings { +public static class GreeterStub extends + com.google.net.stubby.stub.AbstractStub + implements Greeter { ... } ``` @@ -282,18 +282,18 @@ tutorial for your chosen language (coming soon). Our server application has two classes: - a simple service implementation -[GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java). +[GreeterImpl.java](java/src/main/java/ex/grpc/GreeterImpl.java). - a server that hosts the service implementation and allows access over the -network: [GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java). +network: [GreeterServer.java](java/src/main/java/ex/grpc/GreeterServer.java). #### Service implementation -[GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java) +[GreeterImpl.java](java/src/main/java/ex/grpc/GreeterImpl.java) actually implements our GreetingService's required behaviour. -As you can see, the class `GreetingsImpl` implements the interface -`GreetingsGrpc.Greetings` that we [generated](#generating) from our proto +As you can see, the class `GreeterImpl` implements the interface +`GreeterGrpc.Greeter` that we [generated](#generating) from our proto [IDL](java/src/main/proto/helloworld.proto) by implementing the method `hello`: ```java @@ -325,7 +325,7 @@ finished dealing with this RPC. #### Server implementation -[GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) +[GreeterServer.java](java/src/main/java/ex/grpc/GreeterServer.java) shows the other main feature required to provide a gRPC service; making the service implementation available from the network. @@ -334,7 +334,7 @@ implementation available from the network. ... private void start() throws Exception { server = NettyServerBuilder.forPort(port) - .addService(GreetingsGrpc.bindService(new GreetingsImpl())) + .addService(GreeterGrpc.bindService(new GreeterImpl())) .build(); server.startAsync(); server.awaitRunning(5, TimeUnit.SECONDS); @@ -342,15 +342,15 @@ implementation available from the network. ``` -The `GreetingsServer` class has a `ServerImpl` member that actually runs the +The `GreeterServer` class has a `ServerImpl` member that actually runs the server. To create an appropriate `ServerImpl`, we use a special `ServerBuilder` -class (in this case a `NettyServerBuilder`) in the `GreetingsServer`'s `start` -method, binding the `GreetingsService` implementation that we created to a +class (in this case a `NettyServerBuilder`) in the `GreeterServer`'s `start` +method, binding the `GreeterService` implementation that we created to a port. Then we start the server running: the server is now ready to receive -requests from `Greetings` service clients on our specified port. We'll cover +requests from `Greeter` service clients on our specified port. We'll cover how all this works in a bit more detail in our language-specific documentation. -`GreetingsServer` also has a `stop` method that takes care of shutting down +`GreeterServer` also has a `stop` method that takes care of shutting down the service and cleaning up when the program exits. #### Build it @@ -367,9 +367,9 @@ We'll look at using a client to access the server in the next section. ### Writing a client Client-side gRPC is pretty simple. In this step, we'll use the generated code -to write a simple client that can access the `Greetings` server we created +to write a simple client that can access the `Greeter` server we created in the [previous section](#server). You can see the complete client code in -[GreetingsClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). +[GreetingClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). Again, we're not going to go into much detail about how to implement a client - we'll leave that for the tutorial. @@ -386,13 +386,13 @@ service. The channel in turn is used to construct the stub instance. ```java private final ChannelImpl channel; - private final GreetingGrpc.GreetingBlockingStub blockingStub; + private final GreeterGrpc.GreeterBlockingStub blockingStub; public HelloClient(String host, int port) { channel = NettyChannelBuilder.forAddress(host, port) .negotiationType(NegotiationType.PLAINTEXT) .build(); - blockingStub = GreetingGrpc.newBlockingStub(channel); + blockingStub = GreeterGrpc.newBlockingStub(channel); } ``` @@ -419,7 +419,7 @@ from which we can get our greeting. try { Helloworld.HelloRequest request = Helloworld.HelloRequest.newBuilder().setName(name).build(); - Helloworld.HelloReply reply = blockingStub.hello(request); + Helloworld.HelloReply reply = blockingStub.sayHello(request); logger.info("Greeting: " + reply.getMessage()); } catch (RuntimeException e) { logger.log(Level.WARNING, "RPC failed", e); @@ -474,8 +474,3 @@ $ ./run_greetings_client.sh ### Adding another client ###TODO: Section on Go client for same server - - - - - -- cgit v1.2.3 From a16a4d551f9035bd720107732ab71bb9bf337dda Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 18 Feb 2015 17:43:41 -0800 Subject: Complete the change s/Greetings/Greeter --- README.md | 6 +-- java/run_greeter_client.sh | 10 +++++ java/run_greeter_server.sh | 9 ++++ java/run_greetings_client.sh | 10 ----- java/run_greetings_server.sh | 9 ---- java/src/main/java/ex/grpc/GreeterClient.java | 55 +++++++++++++++++++++++++ java/src/main/java/ex/grpc/GreeterServer.java | 51 +++++++++++++++++++++++ java/src/main/java/ex/grpc/GreetingsClient.java | 55 ------------------------- java/src/main/java/ex/grpc/GreetingsServer.java | 51 ----------------------- 9 files changed, 128 insertions(+), 128 deletions(-) create mode 100755 java/run_greeter_client.sh create mode 100755 java/run_greeter_server.sh delete mode 100755 java/run_greetings_client.sh delete mode 100755 java/run_greetings_server.sh create mode 100644 java/src/main/java/ex/grpc/GreeterClient.java create mode 100644 java/src/main/java/ex/grpc/GreeterServer.java delete mode 100644 java/src/main/java/ex/grpc/GreetingsClient.java delete mode 100644 java/src/main/java/ex/grpc/GreetingsServer.java diff --git a/README.md b/README.md index 1203465660..71f3004c71 100644 --- a/README.md +++ b/README.md @@ -369,7 +369,7 @@ We'll look at using a client to access the server in the next section. Client-side gRPC is pretty simple. In this step, we'll use the generated code to write a simple client that can access the `Greeter` server we created in the [previous section](#server). You can see the complete client code in -[GreetingClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). +[GreeterClient.java](java/src/main/java/ex/grpc/GreeterClient.java). Again, we're not going to go into much detail about how to implement a client - we'll leave that for the tutorial. @@ -462,13 +462,13 @@ We've added simple shell scripts to simplifying running the examples. Now that they are built, you can run the server with: ```sh -$ ./run_greetings_server.sh +$ ./run_greeter_server.sh ``` and in another terminal window confirm that it receives a message. ```sh -$ ./run_greetings_client.sh +$ ./run_greeter_client.sh ``` ### Adding another client diff --git a/java/run_greeter_client.sh b/java/run_greeter_client.sh new file mode 100755 index 0000000000..e86ab4ae89 --- /dev/null +++ b/java/run_greeter_client.sh @@ -0,0 +1,10 @@ +#!/bin/bash -e +TARGET='Greeter Client' +TARGET_CLASS='ex.grpc.GreeterClient' +TARGET_ARGS="$@" + +cd "$(dirname "$0")" +mvn -q -nsu -am package -Dcheckstyle.skip=true -DskipTests +. target/bootclasspath.properties +echo "[INFO] Running: $TARGET ($TARGET_CLASS $TARGET_ARGS)" +exec java "$bootclasspath" -cp "$jar" "$TARGET_CLASS" $TARGET_ARGS diff --git a/java/run_greeter_server.sh b/java/run_greeter_server.sh new file mode 100755 index 0000000000..836abc7f48 --- /dev/null +++ b/java/run_greeter_server.sh @@ -0,0 +1,9 @@ +#!/bin/bash -e +TARGET='Greeter Server' +TARGET_CLASS='ex.grpc.GreeterServer' + +cd "$(dirname "$0")" +mvn -q -nsu -am package -Dcheckstyle.skip=true -DskipTests +. target/bootclasspath.properties +echo "[INFO] Running: $TARGET ($TARGET_CLASS)" +exec java "$bootclasspath" -cp "$jar" "$TARGET_CLASS" diff --git a/java/run_greetings_client.sh b/java/run_greetings_client.sh deleted file mode 100755 index 8155589adf..0000000000 --- a/java/run_greetings_client.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -e -TARGET='Greetings Client' -TARGET_CLASS='ex.grpc.GreetingsClient' -TARGET_ARGS="$@" - -cd "$(dirname "$0")" -mvn -q -nsu -am package -Dcheckstyle.skip=true -DskipTests -. target/bootclasspath.properties -echo "[INFO] Running: $TARGET ($TARGET_CLASS $TARGET_ARGS)" -exec java "$bootclasspath" -cp "$jar" "$TARGET_CLASS" $TARGET_ARGS diff --git a/java/run_greetings_server.sh b/java/run_greetings_server.sh deleted file mode 100755 index 248229e129..0000000000 --- a/java/run_greetings_server.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -e -TARGET='Greetings Server' -TARGET_CLASS='ex.grpc.GreetingsServer' - -cd "$(dirname "$0")" -mvn -q -nsu -am package -Dcheckstyle.skip=true -DskipTests -. target/bootclasspath.properties -echo "[INFO] Running: $TARGET ($TARGET_CLASS)" -exec java "$bootclasspath" -cp "$jar" "$TARGET_CLASS" diff --git a/java/src/main/java/ex/grpc/GreeterClient.java b/java/src/main/java/ex/grpc/GreeterClient.java new file mode 100644 index 0000000000..9a4615132d --- /dev/null +++ b/java/src/main/java/ex/grpc/GreeterClient.java @@ -0,0 +1,55 @@ +package ex.grpc; + +import com.google.net.stubby.ChannelImpl; +import com.google.net.stubby.stub.StreamObserver; +import com.google.net.stubby.transport.netty.NegotiationType; +import com.google.net.stubby.transport.netty.NettyChannelBuilder; + +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.concurrent.TimeUnit; + +public class GreeterClient { + private final Logger logger = Logger.getLogger( + GreeterClient.class.getName()); + private final ChannelImpl channel; + private final GreeterGrpc.GreeterBlockingStub blockingStub; + + public GreeterClient(String host, int port) { + channel = NettyChannelBuilder.forAddress(host, port) + .negotiationType(NegotiationType.PLAINTEXT) + .build(); + blockingStub = GreeterGrpc.newBlockingStub(channel); + } + + public void shutdown() throws InterruptedException { + channel.shutdown().awaitTerminated(5, TimeUnit.SECONDS); + } + + public void greet(String name) { + try { + logger.fine("Will try to greet " + name + " ..."); + Helloworld.HelloRequest req = + Helloworld.HelloRequest.newBuilder().setName(name).build(); + Helloworld.HelloReply reply = blockingStub.sayHello(req); + logger.info("Greeting: " + reply.getMessage()); + } catch (RuntimeException e) { + logger.log(Level.WARNING, "RPC failed", e); + return; + } + } + + public static void main(String[] args) throws Exception { + GreeterClient client = new GreeterClient("localhost", 50051); + try { + /* Access a service running on the local machine on port 50051 */ + String user = "world"; + if (args.length > 0) { + user = args[0]; /* Use the arg as the name to greet if provided */ + } + client.greet(user); + } finally { + client.shutdown(); + } + } +} diff --git a/java/src/main/java/ex/grpc/GreeterServer.java b/java/src/main/java/ex/grpc/GreeterServer.java new file mode 100644 index 0000000000..bb05680b0a --- /dev/null +++ b/java/src/main/java/ex/grpc/GreeterServer.java @@ -0,0 +1,51 @@ +package ex.grpc; + +import com.google.common.util.concurrent.MoreExecutors; +import com.google.net.stubby.ServerImpl; +import com.google.net.stubby.transport.netty.NettyServerBuilder; + +import java.util.concurrent.TimeUnit; + +/** + * Server that manages startup/shutdown of a {@code Greeter} server. + */ +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(GreeterGrpc.bindService(new GreeterImpl())) + .build(); + server.startAsync(); + server.awaitRunning(5, TimeUnit.SECONDS); + System.out.println("Server started on port:" + port); + } + + private void stop() throws Exception { + server.stopAsync(); + server.awaitTerminated(); + System.out.println("Server shutting down ..."); + } + + /** + * Main launches the server from the command line. + */ + public static void main(String[] args) throws Exception { + final GreeterServer server = new GreeterServer(); + + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + try { + System.out.println("Shutting down"); + server.stop(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + server.start(); + } +} diff --git a/java/src/main/java/ex/grpc/GreetingsClient.java b/java/src/main/java/ex/grpc/GreetingsClient.java deleted file mode 100644 index 141ad1e20a..0000000000 --- a/java/src/main/java/ex/grpc/GreetingsClient.java +++ /dev/null @@ -1,55 +0,0 @@ -package ex.grpc; - -import com.google.net.stubby.ChannelImpl; -import com.google.net.stubby.stub.StreamObserver; -import com.google.net.stubby.transport.netty.NegotiationType; -import com.google.net.stubby.transport.netty.NettyChannelBuilder; - -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.concurrent.TimeUnit; - -public class GreetingsClient { - private final Logger logger = Logger.getLogger( - GreetingsClient.class.getName()); - private final ChannelImpl channel; - private final GreeterGrpc.GreeterBlockingStub blockingStub; - - public GreetingsClient(String host, int port) { - channel = NettyChannelBuilder.forAddress(host, port) - .negotiationType(NegotiationType.PLAINTEXT) - .build(); - blockingStub = GreeterGrpc.newBlockingStub(channel); - } - - public void shutdown() throws InterruptedException { - channel.shutdown().awaitTerminated(5, TimeUnit.SECONDS); - } - - public void greet(String name) { - try { - logger.fine("Will try to greet " + name + " ..."); - Helloworld.HelloRequest req = - Helloworld.HelloRequest.newBuilder().setName(name).build(); - Helloworld.HelloReply reply = blockingStub.sayHello(req); - logger.info("Greeting: " + reply.getMessage()); - } catch (RuntimeException e) { - logger.log(Level.WARNING, "RPC failed", e); - return; - } - } - - public static void main(String[] args) throws Exception { - GreetingsClient client = new GreetingsClient("localhost", 50051); - try { - /* Access a service running on the local machine on port 50051 */ - String user = "world"; - if (args.length > 0) { - user = args[0]; /* Use the arg as the name to greet if provided */ - } - client.greet(user); - } finally { - client.shutdown(); - } - } -} diff --git a/java/src/main/java/ex/grpc/GreetingsServer.java b/java/src/main/java/ex/grpc/GreetingsServer.java deleted file mode 100644 index 237309d13c..0000000000 --- a/java/src/main/java/ex/grpc/GreetingsServer.java +++ /dev/null @@ -1,51 +0,0 @@ -package ex.grpc; - -import com.google.common.util.concurrent.MoreExecutors; -import com.google.net.stubby.ServerImpl; -import com.google.net.stubby.transport.netty.NettyServerBuilder; - -import java.util.concurrent.TimeUnit; - -/** - * Server that manages startup/shutdown of a {@code Greetings} server. - */ -public class GreetingsServer { - /* The port on which the server should run */ - private int port = 50051; - private ServerImpl server; - - private void start() throws Exception { - server = NettyServerBuilder.forPort(port) - .addService(GreeterGrpc.bindService(new GreeterImpl())) - .build(); - server.startAsync(); - server.awaitRunning(5, TimeUnit.SECONDS); - System.out.println("Server started on port:" + port); - } - - private void stop() throws Exception { - server.stopAsync(); - server.awaitTerminated(); - System.out.println("Server shutting down ..."); - } - - /** - * Main launches the server from the command line. - */ - public static void main(String[] args) throws Exception { - final GreetingsServer server = new GreetingsServer(); - - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - try { - System.out.println("Shutting down"); - server.stop(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - server.start(); - } -} -- cgit v1.2.3 From 5aa9eeba547205b309c66aed97253b4fb670fa60 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 19 Feb 2015 07:30:43 -0800 Subject: Removes the unused protos, updates the README to reflect the protos in use --- java/src/main/proto/helloworld.proto | 22 ---------- protos/README.md | 10 ++--- protos/math.proto | 79 ------------------------------------ protos/stock.proto | 71 -------------------------------- 4 files changed, 4 insertions(+), 178 deletions(-) delete mode 100644 java/src/main/proto/helloworld.proto delete mode 100644 protos/math.proto delete mode 100644 protos/stock.proto diff --git a/java/src/main/proto/helloworld.proto b/java/src/main/proto/helloworld.proto deleted file mode 100644 index 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/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/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/stock.proto b/protos/stock.proto deleted file mode 100644 index 49efbf2730..0000000000 --- a/protos/stock.proto +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2015, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -package examples; - -// Protocol type definitions -message StockRequest { - optional string symbol = 1; - optional int32 num_trades_to_watch = 2; -} - -message StockReply { - optional float price = 1; - optional string symbol = 2; -} - -// Interface exported by the server -service Stock { - // A simple blocking RPC. - // - // Obtains the last traded price for the given Stock. - rpc GetLastTradePrice(StockRequest) returns (StockReply) { - } - - // A Unidirectional server-to-client streaming RPC. - // - // Streams future prices for a given symbol. - rpc WatchFutureTrades(StockRequest) returns (stream StockReply) { - } - - // A Unidirectional client-to-server streaming RPC. - // - // Gets the highest traded price for a series of symbols - rpc GetHighestTradePrice(stream StockRequest) returns (StockReply) { - } - - // Bidirectional streaming RPC. - // - // Gets the most recent traded price of series of trades. - rpc GetLastTradePriceMultiple(stream StockRequest) returns - (stream StockReply) { - } -} -- cgit v1.2.3 From 554b4d7e202ff57b5f60619e6eb675858fb689a6 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Thu, 19 Feb 2015 16:05:49 +0000 Subject: More tidying up, pared down explanations for server and client code as was getting a bit too Java-specific. --- README.md | 72 ++++++++++++++++----------------------------------------------- 1 file changed, 18 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index fdbd1f0de0..5669b8318c 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Hello World example. More documentation is coming soon! ## What is gRPC? -In gRPC, like other RPC systems, a *client* application can directly call +In gRPC a *client* application can directly call methods on a *server* application on a different machine as if it was a local object, making it easier for you to create distributed applications and services. As in many RPC systems, gRPC is based around the idea of defining @@ -32,9 +32,8 @@ your applications. ### Working with protocol buffers -While gRPC’s architecture allows it to be extended for use with other -data formats such as JSON, by default it uses *protocol buffers*, Google’s -mature open source mechanism for serializing structured data. As you'll +By default gRPC uses *protocol buffers*, Google’s +mature open source mechanism for serializing structured data (although it can be used with other data formats such as JSON). As you'll see in our example below, you define gRPC services using *proto files*, with method parameters and return types specified as protocol buffer message types. You @@ -68,7 +67,7 @@ construction of a simple gRPC client-server application, showing you how to: - Create a protocol buffers schema that defines a simple RPC service with a single Hello World method. -- Create a Java server that implements thid interface. +- Create a Java server that implements this interface. - Create a Java client that accesses the Java server. - Create a [probably need a different language now] client that accesses the same Java server. - Update the service with more advanced features like RPC streaming. @@ -82,7 +81,7 @@ than how to install and run a few git commands. This is an introductory example rather than a comprehensive tutorial, so don't worry if you're not a Go or -Java developer - complete tutorials and reference documentation for all gRPC +Java developer - the concepts introduced here are similar for all languages, and complete tutorials and reference documentation for all gRPC languages are coming soon. @@ -209,9 +208,7 @@ our application - right now we're going to generate Java code, though you can generate gRPC code in any gRPC-supported language (as you'll see later in this example). The generated code contains both stub code for clients to use and an abstract interface for servers to implement, both with the method -defined in our `Greeting` service. A stub is code that initiates contact -with a gRPC service running remotely via the internet. [can probably define -this up in "what is gRPC"?] +defined in our `Greeting` service. (If you didn't install `protoc` on your system and are working along with the example, you can skip this step and move @@ -276,7 +273,7 @@ public static class GreetingsStub extends Now let's write some code! First we'll create a server application to implement our service. Note that we're not going to go into a lot of detail about how -to create a server in this section More detailed information will be in the +to create a server in this section. More detailed information will be in the tutorial for your chosen language (coming soon). Our server application has two classes: @@ -293,7 +290,7 @@ network: [GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) actually implements our GreetingService's required behaviour. As you can see, the class `GreetingsImpl` implements the interface -`GreetingsGrpc.Greetings` that we [generated](#generating) from our proto +`GreetingsGrpc.Greetings` that we [generated](#Generating gRPC code) from our proto [IDL](java/src/main/proto/helloworld.proto) by implementing the method `hello`: ```java @@ -306,9 +303,6 @@ As you can see, the class `GreetingsImpl` implements the interface responseObserver.onCompleted(); } ``` -- `hello's` signature is typesafe: - `hello(Helloworld.HelloRequest req, StreamObserver - responseObserver)` - `hello` takes two parameters: -`Helloworld.HelloRequest`: the request -`StreamObserver`: a response observer, which is @@ -318,9 +312,7 @@ To return our response to the client and complete the call: 1. We construct and populate a `HelloReply` response object with our exciting message, as specified in our interface definition. -2. We call `responseObserver.onValue()` with the `HelloReply` that we want to send back to the client. -3. Finally, we call `responseObserver.onCompleted()` to indicate that we're -finished dealing with this RPC. +2. We use the`responseObserver` to return the `HelloReply` to the client and then specify that we've finished dealing with the RPC #### Server implementation @@ -342,17 +334,11 @@ implementation available from the network. ``` -The `GreetingsServer` class has a `ServerImpl` member that actually runs the -server. To create an appropriate `ServerImpl`, we use a special `ServerBuilder` -class (in this case a `NettyServerBuilder`) in the `GreetingsServer`'s `start` -method, binding the `GreetingsService` implementation that we created to a +Here we create an appropriate gRPC server, binding the `GreetingsService` implementation that we created to a port. Then we start the server running: the server is now ready to receive requests from `Greetings` service clients on our specified port. We'll cover how all this works in a bit more detail in our language-specific documentation. -`GreetingsServer` also has a `stop` method that takes care of shutting down -the service and cleaning up when the program exits. - #### Build it Once we've implemented everything, we use Maven to build the server: @@ -376,12 +362,7 @@ Again, we're not going to go into much detail about how to implement a client #### Connecting to the service -First let's look at how we connect to the `Greetings` server. The internet -address -is configured in the client constructor. gRPC `Channel` provides the -abstraction layer over -transport handling; its constructor accepts the host name and port of the -service. The channel in turn is used to construct the stub instance. +First let's look at how we connect to the `Greetings` server. First we need to create a gRPC channel, specifying the hostname and port of the server we want to connect to. Then we use the channel to construct the stub instance. ```java @@ -402,14 +383,12 @@ for the server to respond, and will either return a response or raise an exception. gRPC Java has other kinds of stubs that make non-blocking calls to the server, where the response is returned asynchronously. -#### Obtaining a greeting +#### Calling an RPC -The `greet()` method uses the stub to contact the service and obtain -a greeting. -To do this: +Now we can contact the service and obtain a greeting: -1. We construct and fill in a `HelloRequest` to send to the stub. -2. We call the RPC with our request and get a `HelloReply` from the stub, +1. We construct and fill in a `HelloRequest` to send to the service. +2. We call the stub's `hello()` RPC with our request and get a `HelloReply` back, from which we can get our greeting. @@ -429,27 +408,10 @@ from which we can get our greeting. ``` -#### Running from the command line - -The main method puts together the example so that it can be run from a command -line. - -```java - /* Access a service running on the local machine on port 50051 */ - HelloClient client = new HelloClient("localhost", 50051); - String user = "world"; - if (args.length > 1) { - user = args[1]; - } - client.greet(user); - -``` - #### Build the client This is the same as building the server: our client and server are part of -the same maven -package so the same command builds both. +the same maven package so the same command builds both. ``` $ mvn package @@ -473,6 +435,8 @@ $ ./run_greetings_client.sh ### Adding another client +Finally, let's look at one of gRPC's most useful features - interoperability between code in different languages. So far, we've just generated Java code from our `Greetings` service definition. + ###TODO: Section on Go client for same server -- cgit v1.2.3 From e1a9ebdce3911f5b834d6590d5235b5f8d450ab3 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Thu, 19 Feb 2015 17:35:10 +0000 Subject: Couple more small fixes --- README.md | 76 +++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 5669b8318c..4701619b69 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # Getting started -## TODO: move this to the tutorial sub-folder - Welcome to the developer documentation for gRPC, a language-neutral, platform-neutral remote procedure call (RPC) system developed at Google. @@ -33,7 +31,8 @@ your applications. ### Working with protocol buffers By default gRPC uses *protocol buffers*, Google’s -mature open source mechanism for serializing structured data (although it can be used with other data formats such as JSON). As you'll +mature open source mechanism for serializing structured data (although it +can be used with other data formats such as JSON). As you'll see in our example below, you define gRPC services using *proto files*, with method parameters and return types specified as protocol buffer message types. You @@ -65,14 +64,17 @@ Now that you know a bit more about gRPC, the easiest way to see how it works is to look at a simple example. Our Hello World walks you through the construction of a simple gRPC client-server application, showing you how to: -- Create a protocol buffers schema that defines a simple RPC service with a single +- Create a protocol buffers schema that defines a simple RPC service with +a single Hello World method. - Create a Java server that implements this interface. - Create a Java client that accesses the Java server. -- Create a [probably need a different language now] client that accesses the same Java server. +- Create a [probably need a different language now] client that accesses +the same Java server. - Update the service with more advanced features like RPC streaming. -The complete code for the example is available in the `grpc-common` GitHub repository. You can +The complete code for the example is available in the `grpc-common` GitHub +repository. You can work along with the example and hack on the code in the comfort of your own computer, giving you hands-on practice of really writing gRPC code. We use the Git versioning system for source code management: @@ -81,14 +83,16 @@ than how to install and run a few git commands. This is an introductory example rather than a comprehensive tutorial, so don't worry if you're not a Go or -Java developer - the concepts introduced here are similar for all languages, and complete tutorials and reference documentation for all gRPC +Java developer - the concepts introduced here are similar for all languages, +and complete tutorials and reference documentation for all gRPC languages are coming soon. ### Setup This section explains how to set up your local machine to work with -the example code. If you just want to read the example, you can go straight to the [next step](#servicedef). +the example code. If you just want to read the example, you can go straight +to the [next step](#servicedef). #### Install Git @@ -167,7 +171,8 @@ server use interface code generated from the service definition. Here's our example service definition, defined using protocol buffers IDL in [helloworld.proto](java/src/main/proto/helloworld.proto). The `Greeting` -service has one method, `hello`, that lets the server receive a single `HelloRequest` +service has one method, `hello`, that lets the server receive a single +`HelloRequest` message from the remote client containing the user's name, then send back a greeting in a single `HelloReply`. This is the simplest type of RPC you can specify in gRPC - we'll look at some other types later in this document. @@ -179,22 +184,20 @@ option java_package = "ex.grpc"; package helloworld; +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc sayHello (HelloRequest) returns (HelloReply) {} +} + // The request message containing the user's name. message HelloRequest { - optional string name = 1; + string name = 1; } // The response message containing the greetings message HelloReply { - optional string message = 1; -} - -// The greeting service definition. -service Greeting { - - // Sends a greeting - rpc hello (HelloRequest) returns (HelloReply) { - } + string message = 1; } ``` @@ -257,7 +260,8 @@ which contains (along with some other useful code): } ``` - - _stub_ classes that clients can use to talk to a `Greetings` server. As you can see, they also implement the `Greetings` interface. + - _stub_ classes that clients can use to talk to a `Greetings` server. As + you can see, they also implement the `Greetings` interface. ```java public static class GreetingsStub extends @@ -282,7 +286,8 @@ Our server application has two classes: [GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java). - a server that hosts the service implementation and allows access over the -network: [GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java). +network: +[GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java). #### Service implementation @@ -290,8 +295,9 @@ network: [GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) actually implements our GreetingService's required behaviour. As you can see, the class `GreetingsImpl` implements the interface -`GreetingsGrpc.Greetings` that we [generated](#Generating gRPC code) from our proto -[IDL](java/src/main/proto/helloworld.proto) by implementing the method `hello`: +`GreetingsGrpc.Greetings` that we [generated](#generating) from +our proto +[IDL](proto/helloworld.proto) by implementing the method `hello`: ```java public void hello(Helloworld.HelloRequest req, @@ -312,13 +318,15 @@ To return our response to the client and complete the call: 1. We construct and populate a `HelloReply` response object with our exciting message, as specified in our interface definition. -2. We use the`responseObserver` to return the `HelloReply` to the client and then specify that we've finished dealing with the RPC +2. We use the`responseObserver` to return the `HelloReply` to the client +and then specify that we've finished dealing with the RPC #### Server implementation [GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) -shows the other main feature required to provide a gRPC service; making the service +shows the other main feature required to provide a gRPC service; making +the service implementation available from the network. ```java @@ -334,7 +342,8 @@ implementation available from the network. ``` -Here we create an appropriate gRPC server, binding the `GreetingsService` implementation that we created to a +Here we create an appropriate gRPC server, binding the `GreetingsService` +implementation that we created to a port. Then we start the server running: the server is now ready to receive requests from `Greetings` service clients on our specified port. We'll cover how all this works in a bit more detail in our language-specific documentation. @@ -357,12 +366,14 @@ to write a simple client that can access the `Greetings` server we created in the [previous section](#server). You can see the complete client code in [GreetingsClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). -Again, we're not going to go into much detail about how to implement a client -- we'll leave that for the tutorial. +Again, we're not going to go into much detail about how to implement a client; +we'll leave that for the tutorial. #### Connecting to the service -First let's look at how we connect to the `Greetings` server. First we need to create a gRPC channel, specifying the hostname and port of the server we want to connect to. Then we use the channel to construct the stub instance. +First let's look at how we connect to the `Greetings` server. First we need +to create a gRPC channel, specifying the hostname and port of the server we +want to connect to. Then we use the channel to construct the stub instance. ```java @@ -388,7 +399,8 @@ to the server, where the response is returned asynchronously. Now we can contact the service and obtain a greeting: 1. We construct and fill in a `HelloRequest` to send to the service. -2. We call the stub's `hello()` RPC with our request and get a `HelloReply` back, +2. We call the stub's `hello()` RPC with our request and get a `HelloReply` +back, from which we can get our greeting. @@ -435,7 +447,9 @@ $ ./run_greetings_client.sh ### Adding another client -Finally, let's look at one of gRPC's most useful features - interoperability between code in different languages. So far, we've just generated Java code from our `Greetings` service definition. +Finally, let's look at one of gRPC's most useful features - interoperability +between code in different languages. So far, we've just generated Java code +from our `Greetings` service definition.... ###TODO: Section on Go client for same server -- cgit v1.2.3 From 48dbd9bd6062193c955ee02523d40ed41791287c Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Thu, 19 Feb 2015 17:47:29 +0000 Subject: Mergey mergey --- README.md | 63 +++++++++++++++++++++++++++------------------------------------ 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 4701619b69..43c65b42a1 100644 --- a/README.md +++ b/README.md @@ -247,27 +247,26 @@ we need to create our example: - [`Helloworld.java`](java/src/main/java/ex/grpc/Helloworld.java), which has all the protocol buffer code to populate, serialize, and retrieve our `HelloRequest` and `HelloReply` message types -- [`GreetingsGrpc.java`](java/src/main/java/ex/grpc/GreetingsGrpc.java), +- [`GreeterGrpc.java`](java/src/main/java/ex/grpc/GreeterGrpc.java), which contains (along with some other useful code): - - an interface for `Greetings` servers to implement + - an interface for `Greeter` servers to implement ```java - public static interface Greetings { + public static interface Greeter { - public void hello(ex.grpc.Helloworld.HelloRequest request, + public void sayHello(ex.grpc.Helloworld.HelloRequest request, com.google.net.stubby.stub.StreamObserver responseObserver); } ``` - - _stub_ classes that clients can use to talk to a `Greetings` server. As - you can see, they also implement the `Greetings` interface. + - _stub_ classes that clients can use to talk to a `Greeter` server. As you can see, they also implement the `Greeter` interface. ```java -public static class GreetingsStub extends - com.google.net.stubby.stub.AbstractStub - implements Greetings { +public static class GreeterStub extends + com.google.net.stubby.stub.AbstractStub + implements Greeter { ... } ``` @@ -283,21 +282,18 @@ tutorial for your chosen language (coming soon). Our server application has two classes: - a simple service implementation -[GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java). +[GreeterImpl.java](java/src/main/java/ex/grpc/GreeterImpl.java). - a server that hosts the service implementation and allows access over the -network: -[GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java). +network: [GreeterServer.java](java/src/main/java/ex/grpc/GreeterServer.java). #### Service implementation -[GreetingsImpl.java](java/src/main/java/ex/grpc/GreetingsImpl.java) +[GreeterImpl.java](java/src/main/java/ex/grpc/GreeterImpl.java) actually implements our GreetingService's required behaviour. -As you can see, the class `GreetingsImpl` implements the interface -`GreetingsGrpc.Greetings` that we [generated](#generating) from -our proto -[IDL](proto/helloworld.proto) by implementing the method `hello`: +As you can see, the class `GreeterImpl` implements the interface +`GreeterGrpc.Greeter` that we [generated](#generating) from our proto ```java public void hello(Helloworld.HelloRequest req, @@ -324,9 +320,8 @@ and then specify that we've finished dealing with the RPC #### Server implementation -[GreetingsServer.java](java/src/main/java/ex/grpc/GreetingsServer.java) -shows the other main feature required to provide a gRPC service; making -the service +[GreeterServer.java](java/src/main/java/ex/grpc/GreeterServer.java) +shows the other main feature required to provide a gRPC service; making the service implementation available from the network. ```java @@ -334,7 +329,7 @@ implementation available from the network. ... private void start() throws Exception { server = NettyServerBuilder.forPort(port) - .addService(GreetingsGrpc.bindService(new GreetingsImpl())) + .addService(GreeterGrpc.bindService(new GreeterImpl())) .build(); server.startAsync(); server.awaitRunning(5, TimeUnit.SECONDS); @@ -342,10 +337,11 @@ implementation available from the network. ``` -Here we create an appropriate gRPC server, binding the `GreetingsService` + +Here we create an appropriate gRPC server, binding the `GreeterService` implementation that we created to a port. Then we start the server running: the server is now ready to receive -requests from `Greetings` service clients on our specified port. We'll cover +requests from `Greeter` service clients on our specified port. We'll cover how all this works in a bit more detail in our language-specific documentation. #### Build it @@ -362,9 +358,9 @@ We'll look at using a client to access the server in the next section. ### Writing a client Client-side gRPC is pretty simple. In this step, we'll use the generated code -to write a simple client that can access the `Greetings` server we created +to write a simple client that can access the `Greeter` server we created in the [previous section](#server). You can see the complete client code in -[GreetingsClient.java](java/src/main/java/ex/grpc/GreetingsClient.java). +[GreeterClient.java](java/src/main/java/ex/grpc/GreeterClient.java). Again, we're not going to go into much detail about how to implement a client; we'll leave that for the tutorial. @@ -378,13 +374,13 @@ want to connect to. Then we use the channel to construct the stub instance. ```java private final ChannelImpl channel; - private final GreetingGrpc.GreetingBlockingStub blockingStub; + private final GreeterGrpc.GreeterBlockingStub blockingStub; public HelloClient(String host, int port) { channel = NettyChannelBuilder.forAddress(host, port) .negotiationType(NegotiationType.PLAINTEXT) .build(); - blockingStub = GreetingGrpc.newBlockingStub(channel); + blockingStub = GreeterGrpc.newBlockingStub(channel); } ``` @@ -410,7 +406,7 @@ from which we can get our greeting. try { Helloworld.HelloRequest request = Helloworld.HelloRequest.newBuilder().setName(name).build(); - Helloworld.HelloReply reply = blockingStub.hello(request); + Helloworld.HelloReply reply = blockingStub.sayHello(request); logger.info("Greeting: " + reply.getMessage()); } catch (RuntimeException e) { logger.log(Level.WARNING, "RPC failed", e); @@ -436,13 +432,13 @@ We've added simple shell scripts to simplifying running the examples. Now that they are built, you can run the server with: ```sh -$ ./run_greetings_server.sh +$ ./run_greeter_server.sh ``` and in another terminal window confirm that it receives a message. ```sh -$ ./run_greetings_client.sh +$ ./run_greeter_client.sh ``` ### Adding another client @@ -452,8 +448,3 @@ between code in different languages. So far, we've just generated Java code from our `Greetings` service definition.... ###TODO: Section on Go client for same server - - - - - -- cgit v1.2.3 From 49f3ccdd012153c8c286f54baf2d4a925c1b4314 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 19 Feb 2015 11:09:19 -0800 Subject: Adds a helloworld sample in ruby. --- ruby/.gitignore | 15 +++++++++++ ruby/Gemfile | 15 +++++++++++ ruby/README.md | 35 ++++++++++++++++++++++++ ruby/greeter.gemspec | 23 ++++++++++++++++ ruby/greeter_client.rb | 50 ++++++++++++++++++++++++++++++++++ ruby/greeter_server.rb | 60 +++++++++++++++++++++++++++++++++++++++++ ruby/lib/helloworld.rb | 18 +++++++++++++ ruby/lib/helloworld_services.rb | 24 +++++++++++++++++ 8 files changed, 240 insertions(+) create mode 100644 ruby/.gitignore create mode 100644 ruby/Gemfile create mode 100644 ruby/README.md create mode 100644 ruby/greeter.gemspec create mode 100755 ruby/greeter_client.rb create mode 100755 ruby/greeter_server.rb create mode 100644 ruby/lib/helloworld.rb create mode 100644 ruby/lib/helloworld_services.rb diff --git a/ruby/.gitignore b/ruby/.gitignore new file mode 100644 index 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..d0ccf32f7d --- /dev/null +++ b/ruby/greeter.gemspec @@ -0,0 +1,23 @@ +# -*- ruby -*- +# encoding: utf-8 + +Gem::Specification.new do |s| + s.name = 'grpc' + s.version = '0.0.0' + s.authors = ['gRPC Authors'] + s.email = 'temiola@google.com' + s.homepage = 'https://github.com/google/grpc-common' + s.summary = 'gRPC Ruby overview sample' + s.description = 'Demonstrates how' + + s.files = `git ls-files -- ruby/*`.split("\n") + s.executables = `git ls-files -- ruby/greeter*.rb`.split("\n").map do |f| + File.basename(f) + end + s.require_paths = ['lib'] + s.platform = Gem::Platform::RUBY + + s.add_dependency 'grpc', '~> 0.0.1' + + s.add_development_dependency 'bundler', '~> 1.7' +end diff --git a/ruby/greeter_client.rb b/ruby/greeter_client.rb new file mode 100755 index 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 -- cgit v1.2.3 From c1500a5abb97912618fe72bbf89a4a531ecbc453 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 19 Feb 2015 11:46:19 -0800 Subject: Minor corrections --- ruby/greeter.gemspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruby/greeter.gemspec b/ruby/greeter.gemspec index d0ccf32f7d..be1afae7de 100644 --- a/ruby/greeter.gemspec +++ b/ruby/greeter.gemspec @@ -6,9 +6,9 @@ Gem::Specification.new do |s| s.version = '0.0.0' s.authors = ['gRPC Authors'] s.email = 'temiola@google.com' - s.homepage = 'https://github.com/google/grpc-common' + s.homepage = 'https://github.com/grpc/grpc-common' s.summary = 'gRPC Ruby overview sample' - s.description = 'Demonstrates how' + s.description = 'Simple demo of using gRPC from Ruby' s.files = `git ls-files -- ruby/*`.split("\n") s.executables = `git ls-files -- ruby/greeter*.rb`.split("\n").map do |f| -- cgit v1.2.3 From 7b68400fa42ad54fd35fe28d29e6415c5de35441 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 19 Feb 2015 12:52:26 -0800 Subject: Fixes the gem name. --- ruby/greeter.gemspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruby/greeter.gemspec b/ruby/greeter.gemspec index be1afae7de..795c84c0f5 100644 --- a/ruby/greeter.gemspec +++ b/ruby/greeter.gemspec @@ -2,8 +2,8 @@ # encoding: utf-8 Gem::Specification.new do |s| - s.name = 'grpc' - s.version = '0.0.0' + s.name = 'grpc-greeter' + s.version = '0.1.0' s.authors = ['gRPC Authors'] s.email = 'temiola@google.com' s.homepage = 'https://github.com/grpc/grpc-common' -- cgit v1.2.3 From e89af55a86cd742a076463ee5a639212b029e511 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 19 Feb 2015 13:33:04 -0800 Subject: Added node hello world example --- node/.gitignore | 3 +++ node/README.md | 30 ++++++++++++++++++++++++ node/greeter_client.js | 52 +++++++++++++++++++++++++++++++++++++++++ node/greeter_server.js | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ node/helloworld.proto | 50 +++++++++++++++++++++++++++++++++++++++ node/package.json | 7 ++++++ 6 files changed, 205 insertions(+) create mode 100644 node/.gitignore create mode 100644 node/README.md create mode 100644 node/greeter_client.js create mode 100644 node/greeter_server.js create mode 100644 node/helloworld.proto create mode 100644 node/package.json diff --git a/node/.gitignore b/node/.gitignore new file mode 100644 index 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..4b2c902689 --- /dev/null +++ b/node/README.md @@ -0,0 +1,30 @@ +# gRPC Node.js Helloworld + +## INSTALLATION REQUIREMENTS + +This requires Node 10.x or greater. + +## INSTALL + + - Clone this repository + - Follow the instructions in [INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL) to install the gRPC C core. + - Run `npm install` to install dependencies + - If `grpc` is not found, clone the [gRPC](https://github.com/grpc/grpc) repository and run `npm install path/to/grpc/src/node`. + +## USAGE + + - Run the server + ```sh + $ # from this directory + $ nodejs ./greeter_server.js & + ``` + - Run the client + ```sh + $ # from this directory + $ nodejs ./greeter_client.js + ``` + +## NOTE + +This directory has a copy of `helloworld.proto` because it currently depends on +some Protocol Buffer 2.0 syntax that is deprecated in Protocol Buffer 3.0. diff --git a/node/greeter_client.js b/node/greeter_client.js new file mode 100644 index 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/node/helloworld.proto b/node/helloworld.proto new file mode 100644 index 0000000000..e1f5700725 --- /dev/null +++ b/node/helloworld.proto @@ -0,0 +1,50 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "ex.grpc"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc sayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + optional string name = 1; +} + +// The response message containing the greetings +message HelloReply { + optional string message = 1; +} diff --git a/node/package.json b/node/package.json new file mode 100644 index 0000000000..435654034f --- /dev/null +++ b/node/package.json @@ -0,0 +1,7 @@ +{ + "name": "grpc-greeter", + "version": "0.1.0", + "dependencies": { + "grpc" : "~0.2.0" + } +} -- cgit v1.2.3 From ec8fa8339ed06df87c529f4900a03d8d234d0116 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 19 Feb 2015 13:35:13 -0800 Subject: Fixed formatting --- node/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/node/README.md b/node/README.md index 4b2c902689..57dc83ee3f 100644 --- a/node/README.md +++ b/node/README.md @@ -14,11 +14,14 @@ This requires Node 10.x or greater. ## USAGE - Run the server + ```sh $ # from this directory $ nodejs ./greeter_server.js & ``` + - Run the client + ```sh $ # from this directory $ nodejs ./greeter_client.js -- cgit v1.2.3 From d95693724c45648f2f023cff29df11fc1d9910dd Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Thu, 19 Feb 2015 14:22:52 -0800 Subject: Add helloworld example in c++ --- cpp/helloworld/Makefile | 47 +++ cpp/helloworld/greeter_client.cc | 91 ++++++ cpp/helloworld/greeter_server.cc | 84 +++++ cpp/helloworld/helloworld.pb.cc | 640 +++++++++++++++++++++++++++++++++++++++ cpp/helloworld/helloworld.pb.h | 359 ++++++++++++++++++++++ 5 files changed, 1221 insertions(+) create mode 100644 cpp/helloworld/Makefile create mode 100644 cpp/helloworld/greeter_client.cc create mode 100644 cpp/helloworld/greeter_server.cc create mode 100644 cpp/helloworld/helloworld.pb.cc create mode 100644 cpp/helloworld/helloworld.pb.h diff --git a/cpp/helloworld/Makefile b/cpp/helloworld/Makefile new file mode 100644 index 0000000000..38f4ff081f --- /dev/null +++ b/cpp/helloworld/Makefile @@ -0,0 +1,47 @@ +# +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +CC=g++ +CCFLAGS=-I/usr/local/include -std=c++11 +LDFLAGS=-L/usr/local/lib -lgrpc -lgrpc++ -lprotobuf -ldl + +all: greeter_client greeter_server + +greeter_client: helloworld.pb.cc greeter_client.cc + $(CC) $(CCFLAGS) greeter_client.cc helloworld.pb.cc $(LDFLAGS) -o greeter_client.out + + +greeter_server: helloworld.pb.cc greeter_server.cc + $(CC) $(CCFLAGS) greeter_server.cc helloworld.pb.cc $(LDFLAGS) -o greeter_server.out + +clean: + rm *.out + diff --git a/cpp/helloworld/greeter_client.cc b/cpp/helloworld/greeter_client.cc new file mode 100644 index 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include "helloworld.pb.h" + +using grpc::ChannelArguments; +using grpc::ChannelInterface; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterClient { + public: + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + std::string SayHello(const std::string& user) { + HelloRequest request; + request.set_name(user); + HelloReply reply; + ClientContext context; + + Status status = stub_->sayHello(&context, request, &reply); + if (status.IsOk()) { + return reply.message(); + } else { + return "Rpc failed"; + } + } + + void Shutdown() { stub_.reset(); } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + grpc_init(); + + GreeterClient greeter( + grpc::CreateChannel("localhost:50051", ChannelArguments())); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter received: " << reply << std::endl; + + greeter.Shutdown(); + + grpc_shutdown(); +} diff --git a/cpp/helloworld/greeter_server.cc b/cpp/helloworld/greeter_server.cc new file mode 100644 index 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include "helloworld.pb.h" + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterServiceImpl final : public Greeter::Service { + Status sayHello(ServerContext* context, const HelloRequest* request, + HelloReply* reply) override { + std::string prefix("Hello "); + reply->set_message(prefix + request->name()); + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; + + ServerBuilder builder; + builder.AddPort(server_address); + builder.RegisterService(&service); + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + while (true) { + std::this_thread::sleep_for(std::chrono::seconds(5)); + } +} + +int main(int argc, char** argv) { + grpc_init(); + + RunServer(); + + grpc_shutdown(); + return 0; +} diff --git a/cpp/helloworld/helloworld.pb.cc b/cpp/helloworld/helloworld.pb.cc new file mode 100644 index 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace helloworld { + +namespace { + +const ::google::protobuf::Descriptor* HelloRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + HelloRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* HelloReply_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + HelloReply_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_helloworld_2eproto() { + protobuf_AddDesc_helloworld_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "helloworld.proto"); + GOOGLE_CHECK(file != NULL); + HelloRequest_descriptor_ = file->message_type(0); + static const int HelloRequest_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HelloRequest, name_), + }; + HelloRequest_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + HelloRequest_descriptor_, + HelloRequest::default_instance_, + HelloRequest_offsets_, + -1, + -1, + -1, + sizeof(HelloRequest), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HelloRequest, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HelloRequest, _is_default_instance_)); + HelloReply_descriptor_ = file->message_type(1); + static const int HelloReply_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HelloReply, message_), + }; + HelloReply_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + HelloReply_descriptor_, + HelloReply::default_instance_, + HelloReply_offsets_, + -1, + -1, + -1, + sizeof(HelloReply), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HelloReply, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HelloReply, _is_default_instance_)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_helloworld_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + HelloRequest_descriptor_, &HelloRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + HelloReply_descriptor_, &HelloReply::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_helloworld_2eproto() { + delete HelloRequest::default_instance_; + delete HelloRequest_reflection_; + delete HelloReply::default_instance_; + delete HelloReply_reflection_; +} + +void protobuf_AddDesc_helloworld_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\020helloworld.proto\022\nhelloworld\"\034\n\014HelloR" + "equest\022\014\n\004name\030\001 \001(\t\"\035\n\nHelloReply\022\017\n\007me" + "ssage\030\001 \001(\t2I\n\007Greeter\022>\n\010sayHello\022\030.hel" + "loworld.HelloRequest\032\026.helloworld.HelloR" + "eply\"\000B\t\n\007ex.grpcb\006proto3", 185); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "helloworld.proto", &protobuf_RegisterTypes); + HelloRequest::default_instance_ = new HelloRequest(); + HelloReply::default_instance_ = new HelloReply(); + HelloRequest::default_instance_->InitAsDefaultInstance(); + HelloReply::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_helloworld_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_helloworld_2eproto { + StaticDescriptorInitializer_helloworld_2eproto() { + protobuf_AddDesc_helloworld_2eproto(); + } +} static_descriptor_initializer_helloworld_2eproto_; + +namespace { + +static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; +static void MergeFromFail(int line) { + GOOGLE_CHECK(false) << __FILE__ << ":" << line; +} + +} // namespace + + +// =================================================================== + +#ifndef _MSC_VER +const int HelloRequest::kNameFieldNumber; +#endif // !_MSC_VER + +HelloRequest::HelloRequest() + : ::google::protobuf::Message() , _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:helloworld.HelloRequest) +} + +void HelloRequest::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +HelloRequest::HelloRequest(const HelloRequest& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:helloworld.HelloRequest) +} + +void HelloRequest::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +HelloRequest::~HelloRequest() { + // @@protoc_insertion_point(destructor:helloworld.HelloRequest) + SharedDtor(); +} + +void HelloRequest::SharedDtor() { + name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void HelloRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* HelloRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return HelloRequest_descriptor_; +} + +const HelloRequest& HelloRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_helloworld_2eproto(); + return *default_instance_; +} + +HelloRequest* HelloRequest::default_instance_ = NULL; + +HelloRequest* HelloRequest::New(::google::protobuf::Arena* arena) const { + HelloRequest* n = new HelloRequest; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void HelloRequest::Clear() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +bool HelloRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:helloworld.HelloRequest) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "helloworld.HelloRequest.name"); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:helloworld.HelloRequest) + return true; +failure: + // @@protoc_insertion_point(parse_failure:helloworld.HelloRequest) + return false; +#undef DO_ +} + +void HelloRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:helloworld.HelloRequest) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "helloworld.HelloRequest.name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->name(), output); + } + + // @@protoc_insertion_point(serialize_end:helloworld.HelloRequest) +} + +::google::protobuf::uint8* HelloRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:helloworld.HelloRequest) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "helloworld.HelloRequest.name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:helloworld.HelloRequest) + return target; +} + +int HelloRequest::ByteSize() const { + int total_size = 0; + + // optional string name = 1; + if (this->name().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void HelloRequest::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const HelloRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void HelloRequest::MergeFrom(const HelloRequest& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.name().size() > 0) { + + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } +} + +void HelloRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void HelloRequest::CopyFrom(const HelloRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool HelloRequest::IsInitialized() const { + + return true; +} + +void HelloRequest::Swap(HelloRequest* other) { + if (other == this) return; + InternalSwap(other); +} +void HelloRequest::InternalSwap(HelloRequest* other) { + name_.Swap(&other->name_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata HelloRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = HelloRequest_descriptor_; + metadata.reflection = HelloRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int HelloReply::kMessageFieldNumber; +#endif // !_MSC_VER + +HelloReply::HelloReply() + : ::google::protobuf::Message() , _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:helloworld.HelloReply) +} + +void HelloReply::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +HelloReply::HelloReply(const HelloReply& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:helloworld.HelloReply) +} + +void HelloReply::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +HelloReply::~HelloReply() { + // @@protoc_insertion_point(destructor:helloworld.HelloReply) + SharedDtor(); +} + +void HelloReply::SharedDtor() { + message_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void HelloReply::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* HelloReply::descriptor() { + protobuf_AssignDescriptorsOnce(); + return HelloReply_descriptor_; +} + +const HelloReply& HelloReply::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_helloworld_2eproto(); + return *default_instance_; +} + +HelloReply* HelloReply::default_instance_ = NULL; + +HelloReply* HelloReply::New(::google::protobuf::Arena* arena) const { + HelloReply* n = new HelloReply; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void HelloReply::Clear() { + message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +bool HelloReply::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:helloworld.HelloReply) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string message = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_message())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->message().data(), this->message().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "helloworld.HelloReply.message"); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:helloworld.HelloReply) + return true; +failure: + // @@protoc_insertion_point(parse_failure:helloworld.HelloReply) + return false; +#undef DO_ +} + +void HelloReply::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:helloworld.HelloReply) + // optional string message = 1; + if (this->message().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->message().data(), this->message().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "helloworld.HelloReply.message"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->message(), output); + } + + // @@protoc_insertion_point(serialize_end:helloworld.HelloReply) +} + +::google::protobuf::uint8* HelloReply::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:helloworld.HelloReply) + // optional string message = 1; + if (this->message().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->message().data(), this->message().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "helloworld.HelloReply.message"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->message(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:helloworld.HelloReply) + return target; +} + +int HelloReply::ByteSize() const { + int total_size = 0; + + // optional string message = 1; + if (this->message().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->message()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void HelloReply::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const HelloReply* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void HelloReply::MergeFrom(const HelloReply& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.message().size() > 0) { + + message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_); + } +} + +void HelloReply::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void HelloReply::CopyFrom(const HelloReply& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool HelloReply::IsInitialized() const { + + return true; +} + +void HelloReply::Swap(HelloReply* other) { + if (other == this) return; + InternalSwap(other); +} +void HelloReply::InternalSwap(HelloReply* other) { + message_.Swap(&other->message_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata HelloReply::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = HelloReply_descriptor_; + metadata.reflection = HelloReply_reflection_; + return metadata; +} + + +static const char* Greeter_method_names[] = { + "/helloworld.Greeter/sayHello", +}; + +Greeter::Stub* Greeter::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel) { + Greeter::Stub* stub = new Greeter::Stub(); + stub->set_channel(channel); + return stub; +}; + +::grpc::Status Greeter::Stub::sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) { + return ::grpc::BlockingUnaryCall(channel(),::grpc::RpcMethod(Greeter_method_names[0]), context, request, response); +} + +::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* Greeter::Stub::sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq, void* tag) { + return new ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>(channel(), cq, ::grpc::RpcMethod(Greeter_method_names[0]), context, request, tag); +} + +Greeter::AsyncService::AsyncService(::grpc::CompletionQueue* cq) : ::grpc::AsynchronousService(cq, Greeter_method_names, 1) {} + +Greeter::Service::~Service() { + delete service_; +} + +::grpc::Status Greeter::Service::sayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) { + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED); +} + +void Greeter::AsyncService::RequestsayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* cq, void* tag) { + AsynchronousService::RequestAsyncUnary(0, context, request, response, cq, tag); +} + +::grpc::RpcService* Greeter::Service::service() { + if (service_ != nullptr) { + return service_; + } + service_ = new ::grpc::RpcService(); + service_->AddMethod(new ::grpc::RpcServiceMethod( + Greeter_method_names[0], + ::grpc::RpcMethod::NORMAL_RPC, + new ::grpc::RpcMethodHandler< Greeter::Service, ::helloworld::HelloRequest, ::helloworld::HelloReply>( + std::function< ::grpc::Status(Greeter::Service*, ::grpc::ServerContext*, const ::helloworld::HelloRequest*, ::helloworld::HelloReply*)>(&Greeter::Service::sayHello), this), + new ::helloworld::HelloRequest, new ::helloworld::HelloReply)); + return service_; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace helloworld + +// @@protoc_insertion_point(global_scope) diff --git a/cpp/helloworld/helloworld.pb.h b/cpp/helloworld/helloworld.pb.h new file mode 100644 index 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 + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace grpc { +class CompletionQueue; +class ChannelInterface; +class RpcService; +class ServerContext; +template class ClientAsyncResponseReader; +template class ServerAsyncResponseWriter; +} // namespace grpc +// @@protoc_insertion_point(includes) + +namespace helloworld { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_helloworld_2eproto(); +void protobuf_AssignDesc_helloworld_2eproto(); +void protobuf_ShutdownFile_helloworld_2eproto(); + +class HelloRequest; +class HelloReply; + +// =================================================================== + +class HelloRequest : public ::google::protobuf::Message { + public: + HelloRequest(); + virtual ~HelloRequest(); + + HelloRequest(const HelloRequest& from); + + inline HelloRequest& operator=(const HelloRequest& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const HelloRequest& default_instance(); + + void Swap(HelloRequest* other); + + // implements Message ---------------------------------------------- + + inline HelloRequest* New() const { return New(NULL); } + + HelloRequest* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const HelloRequest& from); + void MergeFrom(const HelloRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(HelloRequest* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // @@protoc_insertion_point(class_scope:helloworld.HelloRequest) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + mutable int _cached_size_; + friend void protobuf_AddDesc_helloworld_2eproto(); + friend void protobuf_AssignDesc_helloworld_2eproto(); + friend void protobuf_ShutdownFile_helloworld_2eproto(); + + void InitAsDefaultInstance(); + static HelloRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class HelloReply : public ::google::protobuf::Message { + public: + HelloReply(); + virtual ~HelloReply(); + + HelloReply(const HelloReply& from); + + inline HelloReply& operator=(const HelloReply& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const HelloReply& default_instance(); + + void Swap(HelloReply* other); + + // implements Message ---------------------------------------------- + + inline HelloReply* New() const { return New(NULL); } + + HelloReply* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const HelloReply& from); + void MergeFrom(const HelloReply& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(HelloReply* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string message = 1; + inline void clear_message(); + static const int kMessageFieldNumber = 1; + inline const ::std::string& message() const; + inline void set_message(const ::std::string& value); + inline void set_message(const char* value); + inline void set_message(const char* value, size_t size); + inline ::std::string* mutable_message(); + inline ::std::string* release_message(); + inline void set_allocated_message(::std::string* message); + + // @@protoc_insertion_point(class_scope:helloworld.HelloReply) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr message_; + mutable int _cached_size_; + friend void protobuf_AddDesc_helloworld_2eproto(); + friend void protobuf_AssignDesc_helloworld_2eproto(); + friend void protobuf_ShutdownFile_helloworld_2eproto(); + + void InitAsDefaultInstance(); + static HelloReply* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// HelloRequest + +// optional string name = 1; +inline void HelloRequest::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& HelloRequest::name() const { + // @@protoc_insertion_point(field_get:helloworld.HelloRequest.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void HelloRequest::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:helloworld.HelloRequest.name) +} +inline void HelloRequest::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:helloworld.HelloRequest.name) +} +inline void HelloRequest::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:helloworld.HelloRequest.name) +} +inline ::std::string* HelloRequest::mutable_name() { + + // @@protoc_insertion_point(field_mutable:helloworld.HelloRequest.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* HelloRequest::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void HelloRequest::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:helloworld.HelloRequest.name) +} + +// ------------------------------------------------------------------- + +// HelloReply + +// optional string message = 1; +inline void HelloReply::clear_message() { + message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& HelloReply::message() const { + // @@protoc_insertion_point(field_get:helloworld.HelloReply.message) + return message_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void HelloReply::set_message(const ::std::string& value) { + + message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:helloworld.HelloReply.message) +} +inline void HelloReply::set_message(const char* value) { + + message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:helloworld.HelloReply.message) +} +inline void HelloReply::set_message(const char* value, size_t size) { + + message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:helloworld.HelloReply.message) +} +inline ::std::string* HelloReply::mutable_message() { + + // @@protoc_insertion_point(field_mutable:helloworld.HelloReply.message) + return message_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* HelloReply::release_message() { + + return message_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void HelloReply::set_allocated_message(::std::string* message) { + if (message != NULL) { + + } else { + + } + message_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), message); + // @@protoc_insertion_point(field_set_allocated:helloworld.HelloReply.message) +} + + +class Greeter final { + public: + class Stub final : public ::grpc::InternalStub { + public: + ::grpc::Status sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response); + ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq, void* tag); + }; + static Stub* NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); + + class Service : public ::grpc::SynchronousService { + public: + Service() : service_(nullptr) {} + virtual ~Service(); + virtual ::grpc::Status sayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response); + ::grpc::RpcService* service() override final; + private: + ::grpc::RpcService* service_; + }; + class AsyncService final : public ::grpc::AsynchronousService { + public: + explicit AsyncService(::grpc::CompletionQueue* cq); + ~AsyncService() {}; + void RequestsayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* cq, void *tag); + }; +}; + +// @@protoc_insertion_point(namespace_scope) + +} // namespace helloworld + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_helloworld_2eproto__INCLUDED -- cgit v1.2.3 From 72bc5647960e0ec6cc9e8b5889acdf68f346286f Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Thu, 19 Feb 2015 14:45:41 -0800 Subject: Resolve comments on makefile --- cpp/helloworld/Makefile | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/cpp/helloworld/Makefile b/cpp/helloworld/Makefile index 38f4ff081f..7211aa5cbe 100644 --- a/cpp/helloworld/Makefile +++ b/cpp/helloworld/Makefile @@ -29,19 +29,28 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -CC=g++ -CCFLAGS=-I/usr/local/include -std=c++11 -LDFLAGS=-L/usr/local/lib -lgrpc -lgrpc++ -lprotobuf -ldl +CXX=g++ +CPPFLAGS=-I/usr/local/include -pthread +CXXFLAGS=-std=c++11 +LDFLAGS=-L/usr/local/lib -lgrpc -lgrpc++ -lprotobuf -lpthread -ldl all: greeter_client greeter_server -greeter_client: helloworld.pb.cc greeter_client.cc - $(CC) $(CCFLAGS) greeter_client.cc helloworld.pb.cc $(LDFLAGS) -o greeter_client.out +helloworld.o: helloworld.pb.cc + $(CXX) -c $(CXXFLAGS) $^ +greeter_client.o: greeter_client.cc + $(CXX) -c $(CXXFLAGS) $^ -greeter_server: helloworld.pb.cc greeter_server.cc - $(CC) $(CCFLAGS) greeter_server.cc helloworld.pb.cc $(LDFLAGS) -o greeter_server.out +greeter_server.o: greeter_server.cc + $(CXX) -c $(CXXFLAGS) $^ + +greeter_client: helloworld.pb.o greeter_client.o + $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ + +greeter_server: helloworld.pb.o greeter_server.o + $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ clean: - rm *.out + rm -f *.o greeter_client greeter_server -- cgit v1.2.3 From 2e4032e14c5f0d6b6b40b85e8321ee752d84ecf3 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Thu, 19 Feb 2015 14:52:47 -0800 Subject: resolve comments --- cpp/helloworld/Makefile | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cpp/helloworld/Makefile b/cpp/helloworld/Makefile index 7211aa5cbe..b9579e0c96 100644 --- a/cpp/helloworld/Makefile +++ b/cpp/helloworld/Makefile @@ -36,15 +36,6 @@ LDFLAGS=-L/usr/local/lib -lgrpc -lgrpc++ -lprotobuf -lpthread -ldl all: greeter_client greeter_server -helloworld.o: helloworld.pb.cc - $(CXX) -c $(CXXFLAGS) $^ - -greeter_client.o: greeter_client.cc - $(CXX) -c $(CXXFLAGS) $^ - -greeter_server.o: greeter_server.cc - $(CXX) -c $(CXXFLAGS) $^ - greeter_client: helloworld.pb.o greeter_client.o $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ -- cgit v1.2.3 From f00df5bb8ac523a095ec7319e726697b3187af43 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Fri, 20 Feb 2015 11:50:29 +0000 Subject: Simple streaming example for overview --- protos/hellostreamingworld.proto | 53 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 protos/hellostreamingworld.proto diff --git a/protos/hellostreamingworld.proto b/protos/hellostreamingworld.proto new file mode 100644 index 0000000000..ec8405c78b --- /dev/null +++ b/protos/hellostreamingworld.proto @@ -0,0 +1,53 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "ex.grpc"; + +package hellostreamingworld; + +// The greeting service definition. +service MultiGreeter { + // Sends multiple greetings + rpc sayHello (HelloRequest) returns (stream HelloReply) {} +} + +// The request message containing the user's name and how many greetings +// they want. +message HelloRequest { + string name = 1; + string num_greetings = 2; +} + +// A response message containing a greeting +message HelloReply { + string message = 1; +} + -- cgit v1.2.3 From 81580a97bbe5411e8576409a2b681a34a070a165 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 20 Feb 2015 03:47:37 -0800 Subject: Adds a helloworld sample in Go. --- go/README.md | 51 +++++++++++++++++++ go/greeter_client/main.go | 70 ++++++++++++++++++++++++++ go/greeter_server/main.go | 65 ++++++++++++++++++++++++ go/helloworld/helloworld.pb.go | 109 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 295 insertions(+) create mode 100644 go/README.md create mode 100644 go/greeter_client/main.go create mode 100644 go/greeter_server/main.go create mode 100644 go/helloworld/helloworld.pb.go diff --git a/go/README.md b/go/README.md new file mode 100644 index 0000000000..df81915c9b --- /dev/null +++ b/go/README.md @@ -0,0 +1,51 @@ +gRPC Go Hello World +=================== + +PREREQUISITES +------------- + +- This requires Go 1.4.x +- Requires that [GOPATH is set](https://golang.org/doc/code.html#GOPATH) +```sh +$ go help gopath +$ # ensure the PATH contains $GOPATH/bin or $GOBIN +$ export PATH=PATH: +``` + +INSTALL +------- + +```sh +$ export GOPATH= +$ go install -u github.com/grpc-common/go/greeter_client +$ go install -u github.com/grpc-common/go/greeter_server +``` + +OPTIONAL - Rebuild the generated code +------------------------------------- + +1 First [install protoc](https://github.com/google/protobuf/blob/master/INSTALL.txt) + - For now, this needs to be installed from source + - This is will change once proto3 is officially released +2 Install the protoc Go plugin. +```sh +$ go install -a github.com/golang/protobuf/protoc-gen-go +$ # ensure the PATH contains $GOPATH/bin or $GOBIN +$ export PATH=PATH: +$ +$ # from ths dir; invoke protoc +$ protoc -I ../protos ../protos/helloworld.proto --go_out=plugins=grpc:. +``` + +TRY IT! +------- + +- Run the server +```sh +$ greeter_server & +``` + +- Run the client +```sh +$ greeter_client +``` diff --git a/go/greeter_client/main.go b/go/greeter_client/main.go new file mode 100644 index 0000000000..abe33c0e2a --- /dev/null +++ b/go/greeter_client/main.go @@ -0,0 +1,70 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +package main + +import ( + "log" + "os" + + pb "github.com/grpc-common/go/helloworld" + "golang.org/x/net/context" + "google.golang.org/grpc" +) + +const ( + address = "localhost:50051" + defaultName = "world" +) + +func main() { + // Set up a connection to the server. + var opts []grpc.DialOption + conn, err := grpc.Dial(address, opts...) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + defer conn.Close() + + // Contact the server and print out its response. + name := defaultName + if len(os.Args) > 1 { + name = os.Args[1] + } + c := pb.NewGreeterClient(conn) + r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name}) + if err != nil { + log.Fatalf("could not greet: %v", err) + } + log.Printf("Greeting: %s", r.Message) +} diff --git a/go/greeter_server/main.go b/go/greeter_server/main.go new file mode 100644 index 0000000000..643524bde7 --- /dev/null +++ b/go/greeter_server/main.go @@ -0,0 +1,65 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +package main + +import ( + "log" + "net" + + pb "github.com/grpc-common/go/helloworld" + "golang.org/x/net/context" + "google.golang.org/grpc" +) + +const ( + port = ":50051" +) + +// server is used to implement hellowrld.GreeterServer. +type server struct{} + +// SayHello implements helloworld.GreeterServer +func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { + return &pb.HelloReply{Message: "Hello " + in.Name}, nil +} + +func main() { + l, err := net.Listen("tcp", port) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + s := grpc.NewServer() + pb.RegisterGreeterServer(s, &server{}) + s.Serve(l) +} diff --git a/go/helloworld/helloworld.pb.go b/go/helloworld/helloworld.pb.go new file mode 100644 index 0000000000..399adda5ea --- /dev/null +++ b/go/helloworld/helloworld.pb.go @@ -0,0 +1,109 @@ +// Code generated by protoc-gen-go. +// source: helloworld.proto +// DO NOT EDIT! + +/* +Package helloworld is a generated protocol buffer package. + +It is generated from these files: + helloworld.proto + +It has these top-level messages: + HelloRequest + HelloReply +*/ +package helloworld + +import proto "github.com/golang/protobuf/proto" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal + +// The request message containing the user's name. +type HelloRequest struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` +} + +func (m *HelloRequest) Reset() { *m = HelloRequest{} } +func (m *HelloRequest) String() string { return proto.CompactTextString(m) } +func (*HelloRequest) ProtoMessage() {} + +// The response message containing the greetings +type HelloReply struct { + Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` +} + +func (m *HelloReply) Reset() { *m = HelloReply{} } +func (m *HelloReply) String() string { return proto.CompactTextString(m) } +func (*HelloReply) ProtoMessage() {} + +func init() { +} + +// Client API for Greeter service + +type GreeterClient interface { + // Sends a greeting + SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) +} + +type greeterClient struct { + cc *grpc.ClientConn +} + +func NewGreeterClient(cc *grpc.ClientConn) GreeterClient { + return &greeterClient{cc} +} + +func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) { + out := new(HelloReply) + err := grpc.Invoke(ctx, "/helloworld.Greeter/sayHello", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for Greeter service + +type GreeterServer interface { + // Sends a greeting + SayHello(context.Context, *HelloRequest) (*HelloReply, error) +} + +func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) { + s.RegisterService(&_Greeter_serviceDesc, srv) +} + +func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, buf []byte) (proto.Message, error) { + in := new(HelloRequest) + if err := proto.Unmarshal(buf, in); err != nil { + return nil, err + } + out, err := srv.(GreeterServer).SayHello(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + +var _Greeter_serviceDesc = grpc.ServiceDesc{ + ServiceName: "helloworld.Greeter", + HandlerType: (*GreeterServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "sayHello", + Handler: _Greeter_SayHello_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, +} -- cgit v1.2.3 From ea8eb3c7030da5a4396eba646b5f5e6291413030 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 20 Feb 2015 07:48:04 -0800 Subject: Pushes the optional code-gen section to the bottom --- go/README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/go/README.md b/go/README.md index df81915c9b..2bcb5ab0a9 100644 --- a/go/README.md +++ b/go/README.md @@ -21,8 +21,21 @@ $ go install -u github.com/grpc-common/go/greeter_client $ go install -u github.com/grpc-common/go/greeter_server ``` -OPTIONAL - Rebuild the generated code -------------------------------------- +TRY IT! +------- + +- Run the server +```sh +$ greeter_server & +``` + +- Run the client +```sh +$ greeter_client +``` + +OPTIONAL - Rebuilding the generated code +---------------------------------------- 1 First [install protoc](https://github.com/google/protobuf/blob/master/INSTALL.txt) - For now, this needs to be installed from source @@ -36,16 +49,3 @@ $ $ # from ths dir; invoke protoc $ protoc -I ../protos ../protos/helloworld.proto --go_out=plugins=grpc:. ``` - -TRY IT! -------- - -- Run the server -```sh -$ greeter_server & -``` - -- Run the client -```sh -$ greeter_client -``` -- cgit v1.2.3 From 4ee7225fbf09b1944dd2a4a31f35dae6f3929047 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 20 Feb 2015 08:14:34 -0800 Subject: Changed the documentation title --- go/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/README.md b/go/README.md index 2bcb5ab0a9..d464b45d36 100644 --- a/go/README.md +++ b/go/README.md @@ -1,5 +1,5 @@ -gRPC Go Hello World -=================== +gRPC in 3 minutes (Go) +====================== PREREQUISITES ------------- -- cgit v1.2.3 From 7c7e9c339603652621184131daad9a50ca1d78a7 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Fri, 20 Feb 2015 10:34:02 -0800 Subject: Fork code from helloworld and generate code --- cpp/route_guide/Makefile | 47 + cpp/route_guide/route_guide.pb.cc | 1736 +++++++++++++++++++++++++++++++++ cpp/route_guide/route_guide.pb.h | 929 ++++++++++++++++++ cpp/route_guide/route_guide_client.cc | 91 ++ cpp/route_guide/route_guide_server.cc | 84 ++ 5 files changed, 2887 insertions(+) create mode 100644 cpp/route_guide/Makefile create mode 100644 cpp/route_guide/route_guide.pb.cc create mode 100644 cpp/route_guide/route_guide.pb.h create mode 100644 cpp/route_guide/route_guide_client.cc create mode 100644 cpp/route_guide/route_guide_server.cc diff --git a/cpp/route_guide/Makefile b/cpp/route_guide/Makefile new file mode 100644 index 0000000000..b9579e0c96 --- /dev/null +++ b/cpp/route_guide/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/route_guide/route_guide.pb.cc b/cpp/route_guide/route_guide.pb.cc new file mode 100644 index 0000000000..6f4a1e7066 --- /dev/null +++ b/cpp/route_guide/route_guide.pb.cc @@ -0,0 +1,1736 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: route_guide.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "route_guide.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace examples { + +namespace { + +const ::google::protobuf::Descriptor* Point_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Point_reflection_ = NULL; +const ::google::protobuf::Descriptor* Rectangle_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Rectangle_reflection_ = NULL; +const ::google::protobuf::Descriptor* Feature_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Feature_reflection_ = NULL; +const ::google::protobuf::Descriptor* RouteNote_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RouteNote_reflection_ = NULL; +const ::google::protobuf::Descriptor* RouteSummary_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RouteSummary_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_route_5fguide_2eproto() { + protobuf_AddDesc_route_5fguide_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "route_guide.proto"); + GOOGLE_CHECK(file != NULL); + Point_descriptor_ = file->message_type(0); + static const int Point_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Point, latitude_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Point, longitude_), + }; + Point_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Point_descriptor_, + Point::default_instance_, + Point_offsets_, + -1, + -1, + -1, + sizeof(Point), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Point, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Point, _is_default_instance_)); + Rectangle_descriptor_ = file->message_type(1); + static const int Rectangle_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Rectangle, lo_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Rectangle, hi_), + }; + Rectangle_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Rectangle_descriptor_, + Rectangle::default_instance_, + Rectangle_offsets_, + -1, + -1, + -1, + sizeof(Rectangle), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Rectangle, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Rectangle, _is_default_instance_)); + Feature_descriptor_ = file->message_type(2); + static const int Feature_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Feature, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Feature, location_), + }; + Feature_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Feature_descriptor_, + Feature::default_instance_, + Feature_offsets_, + -1, + -1, + -1, + sizeof(Feature), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Feature, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Feature, _is_default_instance_)); + RouteNote_descriptor_ = file->message_type(3); + static const int RouteNote_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteNote, location_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteNote, message_), + }; + RouteNote_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + RouteNote_descriptor_, + RouteNote::default_instance_, + RouteNote_offsets_, + -1, + -1, + -1, + sizeof(RouteNote), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteNote, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteNote, _is_default_instance_)); + RouteSummary_descriptor_ = file->message_type(4); + static const int RouteSummary_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteSummary, point_count_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteSummary, feature_count_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteSummary, distance_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteSummary, elapsed_time_), + }; + RouteSummary_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + RouteSummary_descriptor_, + RouteSummary::default_instance_, + RouteSummary_offsets_, + -1, + -1, + -1, + sizeof(RouteSummary), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteSummary, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteSummary, _is_default_instance_)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_route_5fguide_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Point_descriptor_, &Point::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Rectangle_descriptor_, &Rectangle::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Feature_descriptor_, &Feature::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RouteNote_descriptor_, &RouteNote::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RouteSummary_descriptor_, &RouteSummary::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_route_5fguide_2eproto() { + delete Point::default_instance_; + delete Point_reflection_; + delete Rectangle::default_instance_; + delete Rectangle_reflection_; + delete Feature::default_instance_; + delete Feature_reflection_; + delete RouteNote::default_instance_; + delete RouteNote_reflection_; + delete RouteSummary::default_instance_; + delete RouteSummary_reflection_; +} + +void protobuf_AddDesc_route_5fguide_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\021route_guide.proto\022\010examples\",\n\005Point\022\020" + "\n\010latitude\030\001 \001(\005\022\021\n\tlongitude\030\002 \001(\005\"E\n\tR" + "ectangle\022\033\n\002lo\030\001 \001(\0132\017.examples.Point\022\033\n" + "\002hi\030\002 \001(\0132\017.examples.Point\":\n\007Feature\022\014\n" + "\004name\030\001 \001(\t\022!\n\010location\030\002 \001(\0132\017.examples" + ".Point\"\?\n\tRouteNote\022!\n\010location\030\001 \001(\0132\017." + "examples.Point\022\017\n\007message\030\002 \001(\t\"b\n\014Route" + "Summary\022\023\n\013point_count\030\001 \001(\005\022\025\n\rfeature_" + "count\030\002 \001(\005\022\020\n\010distance\030\003 \001(\005\022\024\n\014elapsed" + "_time\030\004 \001(\0052\365\001\n\nRouteGuide\0222\n\nGetFeature" + "\022\017.examples.Point\032\021.examples.Feature\"\000\022:" + "\n\014ListFeatures\022\023.examples.Rectangle\032\021.ex" + "amples.Feature\"\0000\001\022:\n\013RecordRoute\022\017.exam" + "ples.Point\032\026.examples.RouteSummary\"\000(\001\022;" + "\n\tRouteChat\022\023.examples.RouteNote\032\023.examp" + "les.RouteNote\"\000(\0010\001B\t\n\007ex.grpcb\006proto3", 638); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "route_guide.proto", &protobuf_RegisterTypes); + Point::default_instance_ = new Point(); + Rectangle::default_instance_ = new Rectangle(); + Feature::default_instance_ = new Feature(); + RouteNote::default_instance_ = new RouteNote(); + RouteSummary::default_instance_ = new RouteSummary(); + Point::default_instance_->InitAsDefaultInstance(); + Rectangle::default_instance_->InitAsDefaultInstance(); + Feature::default_instance_->InitAsDefaultInstance(); + RouteNote::default_instance_->InitAsDefaultInstance(); + RouteSummary::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_route_5fguide_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_route_5fguide_2eproto { + StaticDescriptorInitializer_route_5fguide_2eproto() { + protobuf_AddDesc_route_5fguide_2eproto(); + } +} static_descriptor_initializer_route_5fguide_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 Point::kLatitudeFieldNumber; +const int Point::kLongitudeFieldNumber; +#endif // !_MSC_VER + +Point::Point() + : ::google::protobuf::Message() , _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:examples.Point) +} + +void Point::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +Point::Point(const Point& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:examples.Point) +} + +void Point::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; + latitude_ = 0; + longitude_ = 0; +} + +Point::~Point() { + // @@protoc_insertion_point(destructor:examples.Point) + SharedDtor(); +} + +void Point::SharedDtor() { + if (this != default_instance_) { + } +} + +void Point::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Point::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Point_descriptor_; +} + +const Point& Point::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_route_5fguide_2eproto(); + return *default_instance_; +} + +Point* Point::default_instance_ = NULL; + +Point* Point::New(::google::protobuf::Arena* arena) const { + Point* n = new Point; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Point::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(latitude_, longitude_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + +} + +bool Point::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:examples.Point) + 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 int32 latitude = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &latitude_))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_longitude; + break; + } + + // optional int32 longitude = 2; + case 2: { + if (tag == 16) { + parse_longitude: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &longitude_))); + + } 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:examples.Point) + return true; +failure: + // @@protoc_insertion_point(parse_failure:examples.Point) + return false; +#undef DO_ +} + +void Point::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:examples.Point) + // optional int32 latitude = 1; + if (this->latitude() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->latitude(), output); + } + + // optional int32 longitude = 2; + if (this->longitude() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->longitude(), output); + } + + // @@protoc_insertion_point(serialize_end:examples.Point) +} + +::google::protobuf::uint8* Point::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:examples.Point) + // optional int32 latitude = 1; + if (this->latitude() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->latitude(), target); + } + + // optional int32 longitude = 2; + if (this->longitude() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->longitude(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:examples.Point) + return target; +} + +int Point::ByteSize() const { + int total_size = 0; + + // optional int32 latitude = 1; + if (this->latitude() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->latitude()); + } + + // optional int32 longitude = 2; + if (this->longitude() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->longitude()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Point::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Point* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Point::MergeFrom(const Point& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.latitude() != 0) { + set_latitude(from.latitude()); + } + if (from.longitude() != 0) { + set_longitude(from.longitude()); + } +} + +void Point::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Point::CopyFrom(const Point& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Point::IsInitialized() const { + + return true; +} + +void Point::Swap(Point* other) { + if (other == this) return; + InternalSwap(other); +} +void Point::InternalSwap(Point* other) { + std::swap(latitude_, other->latitude_); + std::swap(longitude_, other->longitude_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Point::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Point_descriptor_; + metadata.reflection = Point_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Rectangle::kLoFieldNumber; +const int Rectangle::kHiFieldNumber; +#endif // !_MSC_VER + +Rectangle::Rectangle() + : ::google::protobuf::Message() , _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:examples.Rectangle) +} + +void Rectangle::InitAsDefaultInstance() { + _is_default_instance_ = true; + lo_ = const_cast< ::examples::Point*>(&::examples::Point::default_instance()); + hi_ = const_cast< ::examples::Point*>(&::examples::Point::default_instance()); +} + +Rectangle::Rectangle(const Rectangle& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:examples.Rectangle) +} + +void Rectangle::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; + lo_ = NULL; + hi_ = NULL; +} + +Rectangle::~Rectangle() { + // @@protoc_insertion_point(destructor:examples.Rectangle) + SharedDtor(); +} + +void Rectangle::SharedDtor() { + if (this != default_instance_) { + delete lo_; + delete hi_; + } +} + +void Rectangle::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Rectangle::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Rectangle_descriptor_; +} + +const Rectangle& Rectangle::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_route_5fguide_2eproto(); + return *default_instance_; +} + +Rectangle* Rectangle::default_instance_ = NULL; + +Rectangle* Rectangle::New(::google::protobuf::Arena* arena) const { + Rectangle* n = new Rectangle; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Rectangle::Clear() { + if (lo_ != NULL) delete lo_; + lo_ = NULL; + if (hi_ != NULL) delete hi_; + hi_ = NULL; +} + +bool Rectangle::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:examples.Rectangle) + 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 .examples.Point lo = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_lo())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_hi; + break; + } + + // optional .examples.Point hi = 2; + case 2: { + if (tag == 18) { + parse_hi: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_hi())); + } 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:examples.Rectangle) + return true; +failure: + // @@protoc_insertion_point(parse_failure:examples.Rectangle) + return false; +#undef DO_ +} + +void Rectangle::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:examples.Rectangle) + // optional .examples.Point lo = 1; + if (this->has_lo()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, *this->lo_, output); + } + + // optional .examples.Point hi = 2; + if (this->has_hi()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, *this->hi_, output); + } + + // @@protoc_insertion_point(serialize_end:examples.Rectangle) +} + +::google::protobuf::uint8* Rectangle::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:examples.Rectangle) + // optional .examples.Point lo = 1; + if (this->has_lo()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, *this->lo_, target); + } + + // optional .examples.Point hi = 2; + if (this->has_hi()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, *this->hi_, target); + } + + // @@protoc_insertion_point(serialize_to_array_end:examples.Rectangle) + return target; +} + +int Rectangle::ByteSize() const { + int total_size = 0; + + // optional .examples.Point lo = 1; + if (this->has_lo()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + *this->lo_); + } + + // optional .examples.Point hi = 2; + if (this->has_hi()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + *this->hi_); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Rectangle::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Rectangle* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Rectangle::MergeFrom(const Rectangle& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.has_lo()) { + mutable_lo()->::examples::Point::MergeFrom(from.lo()); + } + if (from.has_hi()) { + mutable_hi()->::examples::Point::MergeFrom(from.hi()); + } +} + +void Rectangle::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Rectangle::CopyFrom(const Rectangle& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Rectangle::IsInitialized() const { + + return true; +} + +void Rectangle::Swap(Rectangle* other) { + if (other == this) return; + InternalSwap(other); +} +void Rectangle::InternalSwap(Rectangle* other) { + std::swap(lo_, other->lo_); + std::swap(hi_, other->hi_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Rectangle::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Rectangle_descriptor_; + metadata.reflection = Rectangle_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Feature::kNameFieldNumber; +const int Feature::kLocationFieldNumber; +#endif // !_MSC_VER + +Feature::Feature() + : ::google::protobuf::Message() , _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:examples.Feature) +} + +void Feature::InitAsDefaultInstance() { + _is_default_instance_ = true; + location_ = const_cast< ::examples::Point*>(&::examples::Point::default_instance()); +} + +Feature::Feature(const Feature& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:examples.Feature) +} + +void Feature::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + location_ = NULL; +} + +Feature::~Feature() { + // @@protoc_insertion_point(destructor:examples.Feature) + SharedDtor(); +} + +void Feature::SharedDtor() { + name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + delete location_; + } +} + +void Feature::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Feature::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Feature_descriptor_; +} + +const Feature& Feature::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_route_5fguide_2eproto(); + return *default_instance_; +} + +Feature* Feature::default_instance_ = NULL; + +Feature* Feature::New(::google::protobuf::Arena* arena) const { + Feature* n = new Feature; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Feature::Clear() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (location_ != NULL) delete location_; + location_ = NULL; +} + +bool Feature::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:examples.Feature) + 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, + "examples.Feature.name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_location; + break; + } + + // optional .examples.Point location = 2; + case 2: { + if (tag == 18) { + parse_location: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_location())); + } 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:examples.Feature) + return true; +failure: + // @@protoc_insertion_point(parse_failure:examples.Feature) + return false; +#undef DO_ +} + +void Feature::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:examples.Feature) + // 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, + "examples.Feature.name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->name(), output); + } + + // optional .examples.Point location = 2; + if (this->has_location()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, *this->location_, output); + } + + // @@protoc_insertion_point(serialize_end:examples.Feature) +} + +::google::protobuf::uint8* Feature::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:examples.Feature) + // 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, + "examples.Feature.name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // optional .examples.Point location = 2; + if (this->has_location()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, *this->location_, target); + } + + // @@protoc_insertion_point(serialize_to_array_end:examples.Feature) + return target; +} + +int Feature::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()); + } + + // optional .examples.Point location = 2; + if (this->has_location()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + *this->location_); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Feature::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Feature* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Feature::MergeFrom(const Feature& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.name().size() > 0) { + + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } + if (from.has_location()) { + mutable_location()->::examples::Point::MergeFrom(from.location()); + } +} + +void Feature::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Feature::CopyFrom(const Feature& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Feature::IsInitialized() const { + + return true; +} + +void Feature::Swap(Feature* other) { + if (other == this) return; + InternalSwap(other); +} +void Feature::InternalSwap(Feature* other) { + name_.Swap(&other->name_); + std::swap(location_, other->location_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Feature::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Feature_descriptor_; + metadata.reflection = Feature_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int RouteNote::kLocationFieldNumber; +const int RouteNote::kMessageFieldNumber; +#endif // !_MSC_VER + +RouteNote::RouteNote() + : ::google::protobuf::Message() , _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:examples.RouteNote) +} + +void RouteNote::InitAsDefaultInstance() { + _is_default_instance_ = true; + location_ = const_cast< ::examples::Point*>(&::examples::Point::default_instance()); +} + +RouteNote::RouteNote(const RouteNote& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:examples.RouteNote) +} + +void RouteNote::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + location_ = NULL; + message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +RouteNote::~RouteNote() { + // @@protoc_insertion_point(destructor:examples.RouteNote) + SharedDtor(); +} + +void RouteNote::SharedDtor() { + message_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + delete location_; + } +} + +void RouteNote::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RouteNote::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RouteNote_descriptor_; +} + +const RouteNote& RouteNote::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_route_5fguide_2eproto(); + return *default_instance_; +} + +RouteNote* RouteNote::default_instance_ = NULL; + +RouteNote* RouteNote::New(::google::protobuf::Arena* arena) const { + RouteNote* n = new RouteNote; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void RouteNote::Clear() { + if (location_ != NULL) delete location_; + location_ = NULL; + message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +bool RouteNote::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:examples.RouteNote) + 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 .examples.Point location = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_location())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_message; + break; + } + + // optional string message = 2; + case 2: { + if (tag == 18) { + parse_message: + 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, + "examples.RouteNote.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:examples.RouteNote) + return true; +failure: + // @@protoc_insertion_point(parse_failure:examples.RouteNote) + return false; +#undef DO_ +} + +void RouteNote::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:examples.RouteNote) + // optional .examples.Point location = 1; + if (this->has_location()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, *this->location_, output); + } + + // optional string message = 2; + if (this->message().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->message().data(), this->message().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "examples.RouteNote.message"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->message(), output); + } + + // @@protoc_insertion_point(serialize_end:examples.RouteNote) +} + +::google::protobuf::uint8* RouteNote::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:examples.RouteNote) + // optional .examples.Point location = 1; + if (this->has_location()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, *this->location_, target); + } + + // optional string message = 2; + if (this->message().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->message().data(), this->message().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "examples.RouteNote.message"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->message(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:examples.RouteNote) + return target; +} + +int RouteNote::ByteSize() const { + int total_size = 0; + + // optional .examples.Point location = 1; + if (this->has_location()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + *this->location_); + } + + // optional string message = 2; + 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 RouteNote::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const RouteNote* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RouteNote::MergeFrom(const RouteNote& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.has_location()) { + mutable_location()->::examples::Point::MergeFrom(from.location()); + } + if (from.message().size() > 0) { + + message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_); + } +} + +void RouteNote::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RouteNote::CopyFrom(const RouteNote& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RouteNote::IsInitialized() const { + + return true; +} + +void RouteNote::Swap(RouteNote* other) { + if (other == this) return; + InternalSwap(other); +} +void RouteNote::InternalSwap(RouteNote* other) { + std::swap(location_, other->location_); + message_.Swap(&other->message_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata RouteNote::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RouteNote_descriptor_; + metadata.reflection = RouteNote_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int RouteSummary::kPointCountFieldNumber; +const int RouteSummary::kFeatureCountFieldNumber; +const int RouteSummary::kDistanceFieldNumber; +const int RouteSummary::kElapsedTimeFieldNumber; +#endif // !_MSC_VER + +RouteSummary::RouteSummary() + : ::google::protobuf::Message() , _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:examples.RouteSummary) +} + +void RouteSummary::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +RouteSummary::RouteSummary(const RouteSummary& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:examples.RouteSummary) +} + +void RouteSummary::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; + point_count_ = 0; + feature_count_ = 0; + distance_ = 0; + elapsed_time_ = 0; +} + +RouteSummary::~RouteSummary() { + // @@protoc_insertion_point(destructor:examples.RouteSummary) + SharedDtor(); +} + +void RouteSummary::SharedDtor() { + if (this != default_instance_) { + } +} + +void RouteSummary::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RouteSummary::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RouteSummary_descriptor_; +} + +const RouteSummary& RouteSummary::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_route_5fguide_2eproto(); + return *default_instance_; +} + +RouteSummary* RouteSummary::default_instance_ = NULL; + +RouteSummary* RouteSummary::New(::google::protobuf::Arena* arena) const { + RouteSummary* n = new RouteSummary; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void RouteSummary::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(point_count_, elapsed_time_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + +} + +bool RouteSummary::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:examples.RouteSummary) + 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 int32 point_count = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &point_count_))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_feature_count; + break; + } + + // optional int32 feature_count = 2; + case 2: { + if (tag == 16) { + parse_feature_count: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &feature_count_))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_distance; + break; + } + + // optional int32 distance = 3; + case 3: { + if (tag == 24) { + parse_distance: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &distance_))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_elapsed_time; + break; + } + + // optional int32 elapsed_time = 4; + case 4: { + if (tag == 32) { + parse_elapsed_time: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &elapsed_time_))); + + } 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:examples.RouteSummary) + return true; +failure: + // @@protoc_insertion_point(parse_failure:examples.RouteSummary) + return false; +#undef DO_ +} + +void RouteSummary::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:examples.RouteSummary) + // optional int32 point_count = 1; + if (this->point_count() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->point_count(), output); + } + + // optional int32 feature_count = 2; + if (this->feature_count() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->feature_count(), output); + } + + // optional int32 distance = 3; + if (this->distance() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->distance(), output); + } + + // optional int32 elapsed_time = 4; + if (this->elapsed_time() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->elapsed_time(), output); + } + + // @@protoc_insertion_point(serialize_end:examples.RouteSummary) +} + +::google::protobuf::uint8* RouteSummary::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:examples.RouteSummary) + // optional int32 point_count = 1; + if (this->point_count() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->point_count(), target); + } + + // optional int32 feature_count = 2; + if (this->feature_count() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->feature_count(), target); + } + + // optional int32 distance = 3; + if (this->distance() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->distance(), target); + } + + // optional int32 elapsed_time = 4; + if (this->elapsed_time() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->elapsed_time(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:examples.RouteSummary) + return target; +} + +int RouteSummary::ByteSize() const { + int total_size = 0; + + // optional int32 point_count = 1; + if (this->point_count() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->point_count()); + } + + // optional int32 feature_count = 2; + if (this->feature_count() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->feature_count()); + } + + // optional int32 distance = 3; + if (this->distance() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->distance()); + } + + // optional int32 elapsed_time = 4; + if (this->elapsed_time() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->elapsed_time()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RouteSummary::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const RouteSummary* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RouteSummary::MergeFrom(const RouteSummary& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.point_count() != 0) { + set_point_count(from.point_count()); + } + if (from.feature_count() != 0) { + set_feature_count(from.feature_count()); + } + if (from.distance() != 0) { + set_distance(from.distance()); + } + if (from.elapsed_time() != 0) { + set_elapsed_time(from.elapsed_time()); + } +} + +void RouteSummary::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RouteSummary::CopyFrom(const RouteSummary& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RouteSummary::IsInitialized() const { + + return true; +} + +void RouteSummary::Swap(RouteSummary* other) { + if (other == this) return; + InternalSwap(other); +} +void RouteSummary::InternalSwap(RouteSummary* other) { + std::swap(point_count_, other->point_count_); + std::swap(feature_count_, other->feature_count_); + std::swap(distance_, other->distance_); + std::swap(elapsed_time_, other->elapsed_time_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata RouteSummary::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RouteSummary_descriptor_; + metadata.reflection = RouteSummary_reflection_; + return metadata; +} + + +static const char* RouteGuide_method_names[] = { + "/examples.RouteGuide/GetFeature", + "/examples.RouteGuide/ListFeatures", + "/examples.RouteGuide/RecordRoute", + "/examples.RouteGuide/RouteChat", +}; + +RouteGuide::Stub* RouteGuide::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel) { + RouteGuide::Stub* stub = new RouteGuide::Stub(); + stub->set_channel(channel); + return stub; +}; + +::grpc::Status RouteGuide::Stub::GetFeature(::grpc::ClientContext* context, const ::examples::Point& request, ::examples::Feature* response) { + return ::grpc::BlockingUnaryCall(channel(),::grpc::RpcMethod(RouteGuide_method_names[0]), context, request, response); +} + +::grpc::ClientAsyncResponseReader< ::examples::Feature>* RouteGuide::Stub::GetFeature(::grpc::ClientContext* context, const ::examples::Point& request, ::grpc::CompletionQueue* cq, void* tag) { + return new ::grpc::ClientAsyncResponseReader< ::examples::Feature>(channel(), cq, ::grpc::RpcMethod(RouteGuide_method_names[0]), context, request, tag); +} + +::grpc::ClientReader< ::examples::Feature>* RouteGuide::Stub::ListFeatures(::grpc::ClientContext* context, const ::examples::Rectangle& request) { + return new ::grpc::ClientReader< ::examples::Feature>(channel(),::grpc::RpcMethod(RouteGuide_method_names[1], ::grpc::RpcMethod::RpcType::SERVER_STREAMING), context, request); +} + +::grpc::ClientAsyncReader< ::examples::Feature>* RouteGuide::Stub::ListFeatures(::grpc::ClientContext* context, const ::examples::Rectangle& request, ::grpc::CompletionQueue* cq, void* tag) { + return new ::grpc::ClientAsyncReader< ::examples::Feature>(channel(), cq, ::grpc::RpcMethod(RouteGuide_method_names[1], ::grpc::RpcMethod::RpcType::SERVER_STREAMING), context, request, tag); +} + +::grpc::ClientWriter< ::examples::Point>* RouteGuide::Stub::RecordRoute(::grpc::ClientContext* context, ::examples::RouteSummary* response) { + return new ::grpc::ClientWriter< ::examples::Point>(channel(),::grpc::RpcMethod(RouteGuide_method_names[2], ::grpc::RpcMethod::RpcType::CLIENT_STREAMING), context, response); +} + +::grpc::ClientAsyncWriter< ::examples::Point>* RouteGuide::Stub::RecordRoute(::grpc::ClientContext* context, ::examples::RouteSummary* response, ::grpc::CompletionQueue* cq, void* tag) { + return new ::grpc::ClientAsyncWriter< ::examples::Point>(channel(), cq, ::grpc::RpcMethod(RouteGuide_method_names[2], ::grpc::RpcMethod::RpcType::CLIENT_STREAMING), context, response, tag); +} + +::grpc::ClientReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* RouteGuide::Stub::RouteChat(::grpc::ClientContext* context) { + return new ::grpc::ClientReaderWriter< ::examples::RouteNote, ::examples::RouteNote>(channel(),::grpc::RpcMethod(RouteGuide_method_names[3], ::grpc::RpcMethod::RpcType::BIDI_STREAMING), context); +} + +::grpc::ClientAsyncReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* RouteGuide::Stub::RouteChat(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) { + return new ::grpc::ClientAsyncReaderWriter< ::examples::RouteNote, ::examples::RouteNote>(channel(), cq, ::grpc::RpcMethod(RouteGuide_method_names[3], ::grpc::RpcMethod::RpcType::BIDI_STREAMING), context, tag); +} + +RouteGuide::AsyncService::AsyncService(::grpc::CompletionQueue* cq) : ::grpc::AsynchronousService(cq, RouteGuide_method_names, 4) {} + +RouteGuide::Service::~Service() { + delete service_; +} + +::grpc::Status RouteGuide::Service::GetFeature(::grpc::ServerContext* context, const ::examples::Point* request, ::examples::Feature* response) { + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED); +} + +void RouteGuide::AsyncService::RequestGetFeature(::grpc::ServerContext* context, ::examples::Point* request, ::grpc::ServerAsyncResponseWriter< ::examples::Feature>* response, ::grpc::CompletionQueue* cq, void* tag) { + AsynchronousService::RequestAsyncUnary(0, context, request, response, cq, tag); +} + +::grpc::Status RouteGuide::Service::ListFeatures(::grpc::ServerContext* context, const ::examples::Rectangle* request, ::grpc::ServerWriter< ::examples::Feature>* writer) { + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED); +} + +void RouteGuide::AsyncService::RequestListFeatures(::grpc::ServerContext* context, ::examples::Rectangle* request, ::grpc::ServerAsyncWriter< ::examples::Feature>* writer, ::grpc::CompletionQueue* cq, void* tag) { + AsynchronousService::RequestServerStreaming(1, context, request, writer, cq, tag); +} + +::grpc::Status RouteGuide::Service::RecordRoute(::grpc::ServerContext* context, ::grpc::ServerReader< ::examples::Point>* reader, ::examples::RouteSummary* response) { + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED); +} + +void RouteGuide::AsyncService::RequestRecordRoute(::grpc::ServerContext* context, ::grpc::ServerAsyncReader< ::examples::RouteSummary, ::examples::Point>* reader, ::grpc::CompletionQueue* cq, void* tag) { + AsynchronousService::RequestClientStreaming(2, context, reader, cq, tag); +} + +::grpc::Status RouteGuide::Service::RouteChat(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* stream) { + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED); +} + +void RouteGuide::AsyncService::RequestRouteChat(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* stream, ::grpc::CompletionQueue* cq, void *tag) { + AsynchronousService::RequestBidiStreaming(3, context, stream, cq, tag); +} + +::grpc::RpcService* RouteGuide::Service::service() { + if (service_ != nullptr) { + return service_; + } + service_ = new ::grpc::RpcService(); + service_->AddMethod(new ::grpc::RpcServiceMethod( + RouteGuide_method_names[0], + ::grpc::RpcMethod::NORMAL_RPC, + new ::grpc::RpcMethodHandler< RouteGuide::Service, ::examples::Point, ::examples::Feature>( + std::function< ::grpc::Status(RouteGuide::Service*, ::grpc::ServerContext*, const ::examples::Point*, ::examples::Feature*)>(&RouteGuide::Service::GetFeature), this), + new ::examples::Point, new ::examples::Feature)); + service_->AddMethod(new ::grpc::RpcServiceMethod( + RouteGuide_method_names[1], + ::grpc::RpcMethod::SERVER_STREAMING, + new ::grpc::ServerStreamingHandler< RouteGuide::Service, ::examples::Rectangle, ::examples::Feature>( + std::function< ::grpc::Status(RouteGuide::Service*, ::grpc::ServerContext*, const ::examples::Rectangle*, ::grpc::ServerWriter< ::examples::Feature>*)>(&RouteGuide::Service::ListFeatures), this), + new ::examples::Rectangle, new ::examples::Feature)); + service_->AddMethod(new ::grpc::RpcServiceMethod( + RouteGuide_method_names[2], + ::grpc::RpcMethod::CLIENT_STREAMING, + new ::grpc::ClientStreamingHandler< RouteGuide::Service, ::examples::Point, ::examples::RouteSummary>( + std::function< ::grpc::Status(RouteGuide::Service*, ::grpc::ServerContext*, ::grpc::ServerReader< ::examples::Point>*, ::examples::RouteSummary*)>(&RouteGuide::Service::RecordRoute), this), + new ::examples::Point, new ::examples::RouteSummary)); + service_->AddMethod(new ::grpc::RpcServiceMethod( + RouteGuide_method_names[3], + ::grpc::RpcMethod::BIDI_STREAMING, + new ::grpc::BidiStreamingHandler< RouteGuide::Service, ::examples::RouteNote, ::examples::RouteNote>( + std::function< ::grpc::Status(RouteGuide::Service*, ::grpc::ServerContext*, ::grpc::ServerReaderWriter< ::examples::RouteNote, ::examples::RouteNote>*)>(&RouteGuide::Service::RouteChat), this), + new ::examples::RouteNote, new ::examples::RouteNote)); + return service_; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace examples + +// @@protoc_insertion_point(global_scope) diff --git a/cpp/route_guide/route_guide.pb.h b/cpp/route_guide/route_guide.pb.h new file mode 100644 index 0000000000..7689003f0a --- /dev/null +++ b/cpp/route_guide/route_guide.pb.h @@ -0,0 +1,929 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: route_guide.proto + +#ifndef PROTOBUF_route_5fguide_2eproto__INCLUDED +#define PROTOBUF_route_5fguide_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace grpc { +class CompletionQueue; +class ChannelInterface; +class RpcService; +class ServerContext; +template class ClientAsyncResponseReader; +template class ServerAsyncResponseWriter; +template class ClientWriter; +template class ServerReader; +template class ClientAsyncWriter; +template class ServerAsyncReader; +template class ClientReader; +template class ServerWriter; +template class ClientAsyncReader; +template class ServerAsyncWriter; +template +class ClientReaderWriter; +template +class ServerReaderWriter; +template +class ClientAsyncReaderWriter; +template +class ServerAsyncReaderWriter; +} // namespace grpc +// @@protoc_insertion_point(includes) + +namespace examples { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_route_5fguide_2eproto(); +void protobuf_AssignDesc_route_5fguide_2eproto(); +void protobuf_ShutdownFile_route_5fguide_2eproto(); + +class Point; +class Rectangle; +class Feature; +class RouteNote; +class RouteSummary; + +// =================================================================== + +class Point : public ::google::protobuf::Message { + public: + Point(); + virtual ~Point(); + + Point(const Point& from); + + inline Point& operator=(const Point& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Point& default_instance(); + + void Swap(Point* other); + + // implements Message ---------------------------------------------- + + inline Point* New() const { return New(NULL); } + + Point* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Point& from); + void MergeFrom(const Point& 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(Point* 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 int32 latitude = 1; + inline void clear_latitude(); + static const int kLatitudeFieldNumber = 1; + inline ::google::protobuf::int32 latitude() const; + inline void set_latitude(::google::protobuf::int32 value); + + // optional int32 longitude = 2; + inline void clear_longitude(); + static const int kLongitudeFieldNumber = 2; + inline ::google::protobuf::int32 longitude() const; + inline void set_longitude(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:examples.Point) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::int32 latitude_; + ::google::protobuf::int32 longitude_; + mutable int _cached_size_; + friend void protobuf_AddDesc_route_5fguide_2eproto(); + friend void protobuf_AssignDesc_route_5fguide_2eproto(); + friend void protobuf_ShutdownFile_route_5fguide_2eproto(); + + void InitAsDefaultInstance(); + static Point* default_instance_; +}; +// ------------------------------------------------------------------- + +class Rectangle : public ::google::protobuf::Message { + public: + Rectangle(); + virtual ~Rectangle(); + + Rectangle(const Rectangle& from); + + inline Rectangle& operator=(const Rectangle& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Rectangle& default_instance(); + + void Swap(Rectangle* other); + + // implements Message ---------------------------------------------- + + inline Rectangle* New() const { return New(NULL); } + + Rectangle* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Rectangle& from); + void MergeFrom(const Rectangle& 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(Rectangle* 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 .examples.Point lo = 1; + inline bool has_lo() const; + inline void clear_lo(); + static const int kLoFieldNumber = 1; + inline const ::examples::Point& lo() const; + inline ::examples::Point* mutable_lo(); + inline ::examples::Point* release_lo(); + inline void set_allocated_lo(::examples::Point* lo); + + // optional .examples.Point hi = 2; + inline bool has_hi() const; + inline void clear_hi(); + static const int kHiFieldNumber = 2; + inline const ::examples::Point& hi() const; + inline ::examples::Point* mutable_hi(); + inline ::examples::Point* release_hi(); + inline void set_allocated_hi(::examples::Point* hi); + + // @@protoc_insertion_point(class_scope:examples.Rectangle) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::examples::Point* lo_; + ::examples::Point* hi_; + mutable int _cached_size_; + friend void protobuf_AddDesc_route_5fguide_2eproto(); + friend void protobuf_AssignDesc_route_5fguide_2eproto(); + friend void protobuf_ShutdownFile_route_5fguide_2eproto(); + + void InitAsDefaultInstance(); + static Rectangle* default_instance_; +}; +// ------------------------------------------------------------------- + +class Feature : public ::google::protobuf::Message { + public: + Feature(); + virtual ~Feature(); + + Feature(const Feature& from); + + inline Feature& operator=(const Feature& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Feature& default_instance(); + + void Swap(Feature* other); + + // implements Message ---------------------------------------------- + + inline Feature* New() const { return New(NULL); } + + Feature* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Feature& from); + void MergeFrom(const Feature& 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(Feature* 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); + + // optional .examples.Point location = 2; + inline bool has_location() const; + inline void clear_location(); + static const int kLocationFieldNumber = 2; + inline const ::examples::Point& location() const; + inline ::examples::Point* mutable_location(); + inline ::examples::Point* release_location(); + inline void set_allocated_location(::examples::Point* location); + + // @@protoc_insertion_point(class_scope:examples.Feature) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::examples::Point* location_; + mutable int _cached_size_; + friend void protobuf_AddDesc_route_5fguide_2eproto(); + friend void protobuf_AssignDesc_route_5fguide_2eproto(); + friend void protobuf_ShutdownFile_route_5fguide_2eproto(); + + void InitAsDefaultInstance(); + static Feature* default_instance_; +}; +// ------------------------------------------------------------------- + +class RouteNote : public ::google::protobuf::Message { + public: + RouteNote(); + virtual ~RouteNote(); + + RouteNote(const RouteNote& from); + + inline RouteNote& operator=(const RouteNote& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RouteNote& default_instance(); + + void Swap(RouteNote* other); + + // implements Message ---------------------------------------------- + + inline RouteNote* New() const { return New(NULL); } + + RouteNote* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RouteNote& from); + void MergeFrom(const RouteNote& 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(RouteNote* 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 .examples.Point location = 1; + inline bool has_location() const; + inline void clear_location(); + static const int kLocationFieldNumber = 1; + inline const ::examples::Point& location() const; + inline ::examples::Point* mutable_location(); + inline ::examples::Point* release_location(); + inline void set_allocated_location(::examples::Point* location); + + // optional string message = 2; + inline void clear_message(); + static const int kMessageFieldNumber = 2; + 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:examples.RouteNote) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::examples::Point* location_; + ::google::protobuf::internal::ArenaStringPtr message_; + mutable int _cached_size_; + friend void protobuf_AddDesc_route_5fguide_2eproto(); + friend void protobuf_AssignDesc_route_5fguide_2eproto(); + friend void protobuf_ShutdownFile_route_5fguide_2eproto(); + + void InitAsDefaultInstance(); + static RouteNote* default_instance_; +}; +// ------------------------------------------------------------------- + +class RouteSummary : public ::google::protobuf::Message { + public: + RouteSummary(); + virtual ~RouteSummary(); + + RouteSummary(const RouteSummary& from); + + inline RouteSummary& operator=(const RouteSummary& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RouteSummary& default_instance(); + + void Swap(RouteSummary* other); + + // implements Message ---------------------------------------------- + + inline RouteSummary* New() const { return New(NULL); } + + RouteSummary* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RouteSummary& from); + void MergeFrom(const RouteSummary& 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(RouteSummary* 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 int32 point_count = 1; + inline void clear_point_count(); + static const int kPointCountFieldNumber = 1; + inline ::google::protobuf::int32 point_count() const; + inline void set_point_count(::google::protobuf::int32 value); + + // optional int32 feature_count = 2; + inline void clear_feature_count(); + static const int kFeatureCountFieldNumber = 2; + inline ::google::protobuf::int32 feature_count() const; + inline void set_feature_count(::google::protobuf::int32 value); + + // optional int32 distance = 3; + inline void clear_distance(); + static const int kDistanceFieldNumber = 3; + inline ::google::protobuf::int32 distance() const; + inline void set_distance(::google::protobuf::int32 value); + + // optional int32 elapsed_time = 4; + inline void clear_elapsed_time(); + static const int kElapsedTimeFieldNumber = 4; + inline ::google::protobuf::int32 elapsed_time() const; + inline void set_elapsed_time(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:examples.RouteSummary) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::int32 point_count_; + ::google::protobuf::int32 feature_count_; + ::google::protobuf::int32 distance_; + ::google::protobuf::int32 elapsed_time_; + mutable int _cached_size_; + friend void protobuf_AddDesc_route_5fguide_2eproto(); + friend void protobuf_AssignDesc_route_5fguide_2eproto(); + friend void protobuf_ShutdownFile_route_5fguide_2eproto(); + + void InitAsDefaultInstance(); + static RouteSummary* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// Point + +// optional int32 latitude = 1; +inline void Point::clear_latitude() { + latitude_ = 0; +} +inline ::google::protobuf::int32 Point::latitude() const { + // @@protoc_insertion_point(field_get:examples.Point.latitude) + return latitude_; +} +inline void Point::set_latitude(::google::protobuf::int32 value) { + + latitude_ = value; + // @@protoc_insertion_point(field_set:examples.Point.latitude) +} + +// optional int32 longitude = 2; +inline void Point::clear_longitude() { + longitude_ = 0; +} +inline ::google::protobuf::int32 Point::longitude() const { + // @@protoc_insertion_point(field_get:examples.Point.longitude) + return longitude_; +} +inline void Point::set_longitude(::google::protobuf::int32 value) { + + longitude_ = value; + // @@protoc_insertion_point(field_set:examples.Point.longitude) +} + +// ------------------------------------------------------------------- + +// Rectangle + +// optional .examples.Point lo = 1; +inline bool Rectangle::has_lo() const { + return !_is_default_instance_ && lo_ != NULL; +} +inline void Rectangle::clear_lo() { + if (lo_ != NULL) delete lo_; + lo_ = NULL; +} +inline const ::examples::Point& Rectangle::lo() const { + // @@protoc_insertion_point(field_get:examples.Rectangle.lo) + return lo_ != NULL ? *lo_ : *default_instance_->lo_; +} +inline ::examples::Point* Rectangle::mutable_lo() { + + if (lo_ == NULL) { + lo_ = new ::examples::Point; + } + // @@protoc_insertion_point(field_mutable:examples.Rectangle.lo) + return lo_; +} +inline ::examples::Point* Rectangle::release_lo() { + + ::examples::Point* temp = lo_; + lo_ = NULL; + return temp; +} +inline void Rectangle::set_allocated_lo(::examples::Point* lo) { + delete lo_; + lo_ = lo; + if (lo) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:examples.Rectangle.lo) +} + +// optional .examples.Point hi = 2; +inline bool Rectangle::has_hi() const { + return !_is_default_instance_ && hi_ != NULL; +} +inline void Rectangle::clear_hi() { + if (hi_ != NULL) delete hi_; + hi_ = NULL; +} +inline const ::examples::Point& Rectangle::hi() const { + // @@protoc_insertion_point(field_get:examples.Rectangle.hi) + return hi_ != NULL ? *hi_ : *default_instance_->hi_; +} +inline ::examples::Point* Rectangle::mutable_hi() { + + if (hi_ == NULL) { + hi_ = new ::examples::Point; + } + // @@protoc_insertion_point(field_mutable:examples.Rectangle.hi) + return hi_; +} +inline ::examples::Point* Rectangle::release_hi() { + + ::examples::Point* temp = hi_; + hi_ = NULL; + return temp; +} +inline void Rectangle::set_allocated_hi(::examples::Point* hi) { + delete hi_; + hi_ = hi; + if (hi) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:examples.Rectangle.hi) +} + +// ------------------------------------------------------------------- + +// Feature + +// optional string name = 1; +inline void Feature::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Feature::name() const { + // @@protoc_insertion_point(field_get:examples.Feature.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Feature::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:examples.Feature.name) +} +inline void Feature::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:examples.Feature.name) +} +inline void Feature::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:examples.Feature.name) +} +inline ::std::string* Feature::mutable_name() { + + // @@protoc_insertion_point(field_mutable:examples.Feature.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Feature::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Feature::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:examples.Feature.name) +} + +// optional .examples.Point location = 2; +inline bool Feature::has_location() const { + return !_is_default_instance_ && location_ != NULL; +} +inline void Feature::clear_location() { + if (location_ != NULL) delete location_; + location_ = NULL; +} +inline const ::examples::Point& Feature::location() const { + // @@protoc_insertion_point(field_get:examples.Feature.location) + return location_ != NULL ? *location_ : *default_instance_->location_; +} +inline ::examples::Point* Feature::mutable_location() { + + if (location_ == NULL) { + location_ = new ::examples::Point; + } + // @@protoc_insertion_point(field_mutable:examples.Feature.location) + return location_; +} +inline ::examples::Point* Feature::release_location() { + + ::examples::Point* temp = location_; + location_ = NULL; + return temp; +} +inline void Feature::set_allocated_location(::examples::Point* location) { + delete location_; + location_ = location; + if (location) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:examples.Feature.location) +} + +// ------------------------------------------------------------------- + +// RouteNote + +// optional .examples.Point location = 1; +inline bool RouteNote::has_location() const { + return !_is_default_instance_ && location_ != NULL; +} +inline void RouteNote::clear_location() { + if (location_ != NULL) delete location_; + location_ = NULL; +} +inline const ::examples::Point& RouteNote::location() const { + // @@protoc_insertion_point(field_get:examples.RouteNote.location) + return location_ != NULL ? *location_ : *default_instance_->location_; +} +inline ::examples::Point* RouteNote::mutable_location() { + + if (location_ == NULL) { + location_ = new ::examples::Point; + } + // @@protoc_insertion_point(field_mutable:examples.RouteNote.location) + return location_; +} +inline ::examples::Point* RouteNote::release_location() { + + ::examples::Point* temp = location_; + location_ = NULL; + return temp; +} +inline void RouteNote::set_allocated_location(::examples::Point* location) { + delete location_; + location_ = location; + if (location) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:examples.RouteNote.location) +} + +// optional string message = 2; +inline void RouteNote::clear_message() { + message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& RouteNote::message() const { + // @@protoc_insertion_point(field_get:examples.RouteNote.message) + return message_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void RouteNote::set_message(const ::std::string& value) { + + message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:examples.RouteNote.message) +} +inline void RouteNote::set_message(const char* value) { + + message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:examples.RouteNote.message) +} +inline void RouteNote::set_message(const char* value, size_t size) { + + message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:examples.RouteNote.message) +} +inline ::std::string* RouteNote::mutable_message() { + + // @@protoc_insertion_point(field_mutable:examples.RouteNote.message) + return message_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* RouteNote::release_message() { + + return message_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void RouteNote::set_allocated_message(::std::string* message) { + if (message != NULL) { + + } else { + + } + message_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), message); + // @@protoc_insertion_point(field_set_allocated:examples.RouteNote.message) +} + +// ------------------------------------------------------------------- + +// RouteSummary + +// optional int32 point_count = 1; +inline void RouteSummary::clear_point_count() { + point_count_ = 0; +} +inline ::google::protobuf::int32 RouteSummary::point_count() const { + // @@protoc_insertion_point(field_get:examples.RouteSummary.point_count) + return point_count_; +} +inline void RouteSummary::set_point_count(::google::protobuf::int32 value) { + + point_count_ = value; + // @@protoc_insertion_point(field_set:examples.RouteSummary.point_count) +} + +// optional int32 feature_count = 2; +inline void RouteSummary::clear_feature_count() { + feature_count_ = 0; +} +inline ::google::protobuf::int32 RouteSummary::feature_count() const { + // @@protoc_insertion_point(field_get:examples.RouteSummary.feature_count) + return feature_count_; +} +inline void RouteSummary::set_feature_count(::google::protobuf::int32 value) { + + feature_count_ = value; + // @@protoc_insertion_point(field_set:examples.RouteSummary.feature_count) +} + +// optional int32 distance = 3; +inline void RouteSummary::clear_distance() { + distance_ = 0; +} +inline ::google::protobuf::int32 RouteSummary::distance() const { + // @@protoc_insertion_point(field_get:examples.RouteSummary.distance) + return distance_; +} +inline void RouteSummary::set_distance(::google::protobuf::int32 value) { + + distance_ = value; + // @@protoc_insertion_point(field_set:examples.RouteSummary.distance) +} + +// optional int32 elapsed_time = 4; +inline void RouteSummary::clear_elapsed_time() { + elapsed_time_ = 0; +} +inline ::google::protobuf::int32 RouteSummary::elapsed_time() const { + // @@protoc_insertion_point(field_get:examples.RouteSummary.elapsed_time) + return elapsed_time_; +} +inline void RouteSummary::set_elapsed_time(::google::protobuf::int32 value) { + + elapsed_time_ = value; + // @@protoc_insertion_point(field_set:examples.RouteSummary.elapsed_time) +} + + +class RouteGuide final { + public: + class Stub final : public ::grpc::InternalStub { + public: + ::grpc::Status GetFeature(::grpc::ClientContext* context, const ::examples::Point& request, ::examples::Feature* response); + ::grpc::ClientAsyncResponseReader< ::examples::Feature>* GetFeature(::grpc::ClientContext* context, const ::examples::Point& request, ::grpc::CompletionQueue* cq, void* tag); + ::grpc::ClientReader< ::examples::Feature>* ListFeatures(::grpc::ClientContext* context, const ::examples::Rectangle& request); + ::grpc::ClientAsyncReader< ::examples::Feature>* ListFeatures(::grpc::ClientContext* context, const ::examples::Rectangle& request, ::grpc::CompletionQueue* cq, void* tag); + ::grpc::ClientWriter< ::examples::Point>* RecordRoute(::grpc::ClientContext* context, ::examples::RouteSummary* response); + ::grpc::ClientAsyncWriter< ::examples::Point>* RecordRoute(::grpc::ClientContext* context, ::examples::RouteSummary* response, ::grpc::CompletionQueue* cq, void* tag); + ::grpc::ClientReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* RouteChat(::grpc::ClientContext* context); + ::grpc::ClientAsyncReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* RouteChat(::grpc::ClientContext* context, ::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 GetFeature(::grpc::ServerContext* context, const ::examples::Point* request, ::examples::Feature* response); + virtual ::grpc::Status ListFeatures(::grpc::ServerContext* context, const ::examples::Rectangle* request, ::grpc::ServerWriter< ::examples::Feature>* writer); + virtual ::grpc::Status RecordRoute(::grpc::ServerContext* context, ::grpc::ServerReader< ::examples::Point>* reader, ::examples::RouteSummary* response); + virtual ::grpc::Status RouteChat(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* stream); + ::grpc::RpcService* service() override final; + private: + ::grpc::RpcService* service_; + }; + class AsyncService final : public ::grpc::AsynchronousService { + public: + explicit AsyncService(::grpc::CompletionQueue* cq); + ~AsyncService() {}; + void RequestGetFeature(::grpc::ServerContext* context, ::examples::Point* request, ::grpc::ServerAsyncResponseWriter< ::examples::Feature>* response, ::grpc::CompletionQueue* cq, void *tag); + void RequestListFeatures(::grpc::ServerContext* context, ::examples::Rectangle* request, ::grpc::ServerAsyncWriter< ::examples::Feature>* writer, ::grpc::CompletionQueue* cq, void *tag); + void RequestRecordRoute(::grpc::ServerContext* context, ::grpc::ServerAsyncReader< ::examples::RouteSummary, ::examples::Point>* reader, ::grpc::CompletionQueue* cq, void *tag); + void RequestRouteChat(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* stream, ::grpc::CompletionQueue* cq, void *tag); + }; +}; + +// @@protoc_insertion_point(namespace_scope) + +} // namespace examples + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_route_5fguide_2eproto__INCLUDED diff --git a/cpp/route_guide/route_guide_client.cc b/cpp/route_guide/route_guide_client.cc new file mode 100644 index 0000000000..4a51f5eb38 --- /dev/null +++ b/cpp/route_guide/route_guide_client.cc @@ -0,0 +1,91 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "helloworld.pb.h" + +using grpc::ChannelArguments; +using grpc::ChannelInterface; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterClient { + public: + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + std::string SayHello(const std::string& user) { + HelloRequest request; + request.set_name(user); + HelloReply reply; + ClientContext context; + + Status status = stub_->sayHello(&context, request, &reply); + if (status.IsOk()) { + return reply.message(); + } else { + return "Rpc failed"; + } + } + + void Shutdown() { stub_.reset(); } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + grpc_init(); + + GreeterClient greeter( + grpc::CreateChannel("localhost:50051", ChannelArguments())); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter received: " << reply << std::endl; + + greeter.Shutdown(); + + grpc_shutdown(); +} diff --git a/cpp/route_guide/route_guide_server.cc b/cpp/route_guide/route_guide_server.cc new file mode 100644 index 0000000000..3a2ab60e89 --- /dev/null +++ b/cpp/route_guide/route_guide_server.cc @@ -0,0 +1,84 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "helloworld.pb.h" + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterServiceImpl final : public Greeter::Service { + Status sayHello(ServerContext* context, const HelloRequest* request, + HelloReply* reply) override { + std::string prefix("Hello "); + reply->set_message(prefix + request->name()); + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; + + ServerBuilder builder; + builder.AddPort(server_address); + builder.RegisterService(&service); + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + while (true) { + std::this_thread::sleep_for(std::chrono::seconds(5)); + } +} + +int main(int argc, char** argv) { + grpc_init(); + + RunServer(); + + grpc_shutdown(); + return 0; +} -- cgit v1.2.3 From 600d70cd8dbebd1ef86cad1d1ba0faf600002250 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Fri, 20 Feb 2015 10:50:46 -0800 Subject: change proto README cpp node ruby --- README.md | 6 +++--- cpp/helloworld/greeter_client.cc | 2 +- cpp/helloworld/greeter_server.cc | 2 +- cpp/helloworld/helloworld.pb.cc | 14 +++++++------- cpp/helloworld/helloworld.pb.h | 8 ++++---- node/greeter_client.js | 2 +- node/greeter_server.js | 6 +++--- node/helloworld.proto | 2 +- protos/helloworld.proto | 2 +- ruby/greeter_server.rb | 2 +- ruby/lib/helloworld_services.rb | 2 +- 11 files changed, 24 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 3a2fb8d7d1..c48007a1cb 100644 --- a/README.md +++ b/README.md @@ -187,7 +187,7 @@ package helloworld; // The greeting service definition. service Greeter { // Sends a greeting - rpc sayHello (HelloRequest) returns (HelloReply) {} + rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. @@ -254,7 +254,7 @@ which contains (along with some other useful code): ```java public static interface Greeter { - public void sayHello(ex.grpc.Helloworld.HelloRequest request, + public void SayHello(ex.grpc.Helloworld.HelloRequest request, com.google.net.stubby.stub.StreamObserver responseObserver); } @@ -405,7 +405,7 @@ from which we can get our greeting. try { Helloworld.HelloRequest request = Helloworld.HelloRequest.newBuilder().setName(name).build(); - Helloworld.HelloReply reply = blockingStub.sayHello(request); + Helloworld.HelloReply reply = blockingStub.SayHello(request); logger.info("Greeting: " + reply.getMessage()); } catch (RuntimeException e) { logger.log(Level.WARNING, "RPC failed", e); diff --git a/cpp/helloworld/greeter_client.cc b/cpp/helloworld/greeter_client.cc index 4a51f5eb38..3c2bbc2074 100644 --- a/cpp/helloworld/greeter_client.cc +++ b/cpp/helloworld/greeter_client.cc @@ -62,7 +62,7 @@ class GreeterClient { HelloReply reply; ClientContext context; - Status status = stub_->sayHello(&context, request, &reply); + Status status = stub_->SayHello(&context, request, &reply); if (status.IsOk()) { return reply.message(); } else { diff --git a/cpp/helloworld/greeter_server.cc b/cpp/helloworld/greeter_server.cc index 3a2ab60e89..01a0bf242d 100644 --- a/cpp/helloworld/greeter_server.cc +++ b/cpp/helloworld/greeter_server.cc @@ -52,7 +52,7 @@ using helloworld::HelloReply; using helloworld::Greeter; class GreeterServiceImpl final : public Greeter::Service { - Status sayHello(ServerContext* context, const HelloRequest* request, + Status SayHello(ServerContext* context, const HelloRequest* request, HelloReply* reply) override { std::string prefix("Hello "); reply->set_message(prefix + request->name()); diff --git a/cpp/helloworld/helloworld.pb.cc b/cpp/helloworld/helloworld.pb.cc index a5b82c5ed5..9540f2c94c 100644 --- a/cpp/helloworld/helloworld.pb.cc +++ b/cpp/helloworld/helloworld.pb.cc @@ -109,7 +109,7 @@ void protobuf_AddDesc_helloworld_2eproto() { ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( "\n\020helloworld.proto\022\nhelloworld\"\034\n\014HelloR" "equest\022\014\n\004name\030\001 \001(\t\"\035\n\nHelloReply\022\017\n\007me" - "ssage\030\001 \001(\t2I\n\007Greeter\022>\n\010sayHello\022\030.hel" + "ssage\030\001 \001(\t2I\n\007Greeter\022>\n\010SayHello\022\030.hel" "loworld.HelloRequest\032\026.helloworld.HelloR" "eply\"\000B\t\n\007ex.grpcb\006proto3", 185); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( @@ -587,7 +587,7 @@ void HelloReply::InternalSwap(HelloReply* other) { static const char* Greeter_method_names[] = { - "/helloworld.Greeter/sayHello", + "/helloworld.Greeter/SayHello", }; Greeter::Stub* Greeter::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel) { @@ -596,11 +596,11 @@ Greeter::Stub* Greeter::NewStub(const std::shared_ptr< ::grpc::ChannelInterface> return stub; }; -::grpc::Status Greeter::Stub::sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) { +::grpc::Status Greeter::Stub::SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) { return ::grpc::BlockingUnaryCall(channel(),::grpc::RpcMethod(Greeter_method_names[0]), context, request, response); } -::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* Greeter::Stub::sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq, void* tag) { +::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* Greeter::Stub::SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq, void* tag) { return new ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>(channel(), cq, ::grpc::RpcMethod(Greeter_method_names[0]), context, request, tag); } @@ -610,11 +610,11 @@ Greeter::Service::~Service() { delete service_; } -::grpc::Status Greeter::Service::sayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) { +::grpc::Status Greeter::Service::SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED); } -void Greeter::AsyncService::RequestsayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* cq, void* tag) { +void Greeter::AsyncService::RequestSayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* cq, void* tag) { AsynchronousService::RequestAsyncUnary(0, context, request, response, cq, tag); } @@ -627,7 +627,7 @@ void Greeter::AsyncService::RequestsayHello(::grpc::ServerContext* context, ::he Greeter_method_names[0], ::grpc::RpcMethod::NORMAL_RPC, new ::grpc::RpcMethodHandler< Greeter::Service, ::helloworld::HelloRequest, ::helloworld::HelloReply>( - std::function< ::grpc::Status(Greeter::Service*, ::grpc::ServerContext*, const ::helloworld::HelloRequest*, ::helloworld::HelloReply*)>(&Greeter::Service::sayHello), this), + std::function< ::grpc::Status(Greeter::Service*, ::grpc::ServerContext*, const ::helloworld::HelloRequest*, ::helloworld::HelloReply*)>(&Greeter::Service::SayHello), this), new ::helloworld::HelloRequest, new ::helloworld::HelloReply)); return service_; } diff --git a/cpp/helloworld/helloworld.pb.h b/cpp/helloworld/helloworld.pb.h index f49adae84a..1eb870166a 100644 --- a/cpp/helloworld/helloworld.pb.h +++ b/cpp/helloworld/helloworld.pb.h @@ -319,8 +319,8 @@ class Greeter final { public: class Stub final : public ::grpc::InternalStub { public: - ::grpc::Status sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response); - ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* sayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq, void* tag); + ::grpc::Status SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response); + ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq, void* tag); }; static Stub* NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); @@ -328,7 +328,7 @@ class Greeter final { public: Service() : service_(nullptr) {} virtual ~Service(); - virtual ::grpc::Status sayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response); + virtual ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response); ::grpc::RpcService* service() override final; private: ::grpc::RpcService* service_; @@ -337,7 +337,7 @@ class Greeter final { public: explicit AsyncService(::grpc::CompletionQueue* cq); ~AsyncService() {}; - void RequestsayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* cq, void *tag); + void RequestSayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* cq, void *tag); }; }; diff --git a/node/greeter_client.js b/node/greeter_client.js index ab7050ab21..db45afca77 100644 --- a/node/greeter_client.js +++ b/node/greeter_client.js @@ -44,7 +44,7 @@ function main() { } else { user = 'world'; } - client.sayHello({name: user}, function(err, response) { + client.SayHello({name: user}, function(err, response) { console.log('Greeting:', response.message); }); } diff --git a/node/greeter_server.js b/node/greeter_server.js index 6d4183c0ce..fa95cea2e9 100644 --- a/node/greeter_server.js +++ b/node/greeter_server.js @@ -39,9 +39,9 @@ var hello_proto = grpc.load(PROTO_PATH).helloworld; var Server = grpc.buildServer([hello_proto.Greeter.service]); /** - * Implements the sayHello RPC method. + * Implements the SayHello RPC method. */ -function sayHello(call, callback) { +function SayHello(call, callback) { callback(null, {message: 'Hello ' + call.request.name}); } @@ -52,7 +52,7 @@ function sayHello(call, callback) { function main() { var server = new Server({ "helloworld.Greeter": { - sayHello: sayHello + SayHello: SayHello } }); diff --git a/node/helloworld.proto b/node/helloworld.proto index e1f5700725..a52c947f89 100644 --- a/node/helloworld.proto +++ b/node/helloworld.proto @@ -36,7 +36,7 @@ package helloworld; // The greeting service definition. service Greeter { // Sends a greeting - rpc sayHello (HelloRequest) returns (HelloReply) {} + rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. diff --git a/protos/helloworld.proto b/protos/helloworld.proto index 4781fb4830..f9abd3d87f 100644 --- a/protos/helloworld.proto +++ b/protos/helloworld.proto @@ -36,7 +36,7 @@ package helloworld; // The greeting service definition. service Greeter { // Sends a greeting - rpc sayHello (HelloRequest) returns (HelloReply) {} + rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. diff --git a/ruby/greeter_server.rb b/ruby/greeter_server.rb index eb1a6ab454..d4f9cf7d0f 100755 --- a/ruby/greeter_server.rb +++ b/ruby/greeter_server.rb @@ -42,7 +42,7 @@ require 'helloworld_services' # GreeterServer is simple server that implements the Helloworld Greeter server. class GreeterServer < Helloworld::Greeter::Service - # say_hello implements the sayHello rpc method. + # say_hello implements the SayHello rpc method. def say_hello(hello_req, _unused_call) Helloworld::HelloReply.new(message: "Hello #{hello_req.name}") end diff --git a/ruby/lib/helloworld_services.rb b/ruby/lib/helloworld_services.rb index 9bd528485a..7da45ebc6b 100644 --- a/ruby/lib/helloworld_services.rb +++ b/ruby/lib/helloworld_services.rb @@ -16,7 +16,7 @@ module Helloworld self.unmarshal_class_method = :decode self.service_name = 'helloworld.Greeter' - rpc :sayHello, HelloRequest, HelloReply + rpc :SayHello, HelloRequest, HelloReply end Stub = Service.rpc_stub_class -- cgit v1.2.3 From bfad7921e122d83549f0b0947737273904bcc17f Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Fri, 20 Feb 2015 11:30:46 -0800 Subject: makefile change --- cpp/route_guide/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp/route_guide/Makefile b/cpp/route_guide/Makefile index b9579e0c96..444841f8b8 100644 --- a/cpp/route_guide/Makefile +++ b/cpp/route_guide/Makefile @@ -34,14 +34,14 @@ 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 +all: route_guide_client route_guide_server -greeter_client: helloworld.pb.o greeter_client.o +route_guide_client: route_guide.pb.o route_guide_client.o $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ -greeter_server: helloworld.pb.o greeter_server.o +route_guide_server: route_guide.pb.o route_guide_server.o $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ clean: - rm -f *.o greeter_client greeter_server + rm -f *.o route_guide_client route_guide_server -- cgit v1.2.3 From 3440548d83452321d72e2b93992c298f999f1359 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Fri, 20 Feb 2015 11:35:20 -0800 Subject: revert js changes. --- node/greeter_client.js | 2 +- node/greeter_server.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/node/greeter_client.js b/node/greeter_client.js index db45afca77..ab7050ab21 100644 --- a/node/greeter_client.js +++ b/node/greeter_client.js @@ -44,7 +44,7 @@ function main() { } else { user = 'world'; } - client.SayHello({name: user}, function(err, response) { + client.sayHello({name: user}, function(err, response) { console.log('Greeting:', response.message); }); } diff --git a/node/greeter_server.js b/node/greeter_server.js index fa95cea2e9..2fb95f0f90 100644 --- a/node/greeter_server.js +++ b/node/greeter_server.js @@ -41,7 +41,7 @@ var Server = grpc.buildServer([hello_proto.Greeter.service]); /** * Implements the SayHello RPC method. */ -function SayHello(call, callback) { +function sayHello(call, callback) { callback(null, {message: 'Hello ' + call.request.name}); } @@ -52,7 +52,7 @@ function SayHello(call, callback) { function main() { var server = new Server({ "helloworld.Greeter": { - SayHello: SayHello + sayHello: sayHello } }); -- cgit v1.2.3 From b7538ee7554fde3e5225db379c816ed78f4c93f7 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 20 Feb 2015 22:56:43 +0100 Subject: Improving user experience. --- cpp/helloworld/Makefile | 79 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 8 deletions(-) diff --git a/cpp/helloworld/Makefile b/cpp/helloworld/Makefile index b9579e0c96..83f2ad4904 100644 --- a/cpp/helloworld/Makefile +++ b/cpp/helloworld/Makefile @@ -29,19 +29,82 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -CXX=g++ -CPPFLAGS=-I/usr/local/include -pthread -CXXFLAGS=-std=c++11 -LDFLAGS=-L/usr/local/lib -lgrpc -lgrpc++ -lprotobuf -lpthread -ldl +CXX = g++ +CPPFLAGS = -I/usr/local/include -pthread +CXXFLAGS = -std=c++11 +LDFLAGS = -L/usr/local/lib -lgrpc -lgrpc++ -lprotobuf -lpthread -ldl +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` -all: greeter_client greeter_server +PROTOS_PATH = ../../protos + +vpath %.proto $(PROTOS_PATH) + +all: system-check greeter_client greeter_server greeter_client: helloworld.pb.o greeter_client.o - $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ + $(CXX) $^ $(LDFLAGS) -o $@ greeter_server: helloworld.pb.o greeter_server.o - $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ + $(CXX) $^ $(LDFLAGS) -o $@ + +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< clean: - rm -f *.o greeter_client greeter_server + rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server + + +# The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + +PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + +SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif +system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-alpha-1" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif -- cgit v1.2.3 From 8c0464dcf64507d028601abe97e003720c656922 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Fri, 20 Feb 2015 14:19:31 -0800 Subject: Fixes var name --- go/greeter_server/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/greeter_server/main.go b/go/greeter_server/main.go index 643524bde7..231f5c607b 100644 --- a/go/greeter_server/main.go +++ b/go/greeter_server/main.go @@ -55,11 +55,11 @@ func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloRe } func main() { - l, err := net.Listen("tcp", port) + lis, err := net.Listen("tcp", port) if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterGreeterServer(s, &server{}) - s.Serve(l) + s.Serve(lis) } -- cgit v1.2.3 From bc0c2dcc6b91e56eaacab5990106450d0560d542 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 20 Feb 2015 15:24:56 -0800 Subject: Created new top-level README_NEW --- README_NEW.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 README_NEW.md diff --git a/README_NEW.md b/README_NEW.md new file mode 100644 index 0000000000..583136bc0d --- /dev/null +++ b/README_NEW.md @@ -0,0 +1,8 @@ + +# Please pick your language to proceed: +### [C++](https://github.com/grpc/grpc-common/tree/master/cpp) +### [Java](https://github.com/grpc/grpc-common/tree/master/java) +### [Python](https://github.com/grpc/grpc-common/tree/master/python) +### [Go](https://github.com/grpc/grpc-common/tree/master/go) +### [ruby](https://github.com/grpc/grpc-common/tree/master/ruby) +### [Node.js](https://github.com/grpc/grpc-common/tree/master/node) -- cgit v1.2.3 From 3a5592ce1ebfe3af2169b05827d5b9eee6ad8067 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 20 Feb 2015 15:32:42 -0800 Subject: Created cpp/README --- cpp/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 cpp/README.md diff --git a/cpp/README.md b/cpp/README.md new file mode 100644 index 0000000000..376a3731c3 --- /dev/null +++ b/cpp/README.md @@ -0,0 +1,8 @@ +#gRPC C++ Getting started + +First you need to install gRPC on your system. Follow the instructions here: +[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/INSTALL). + +After installing, you can proceed to the [gRPC C++ Hello World tutorial](https://github.com/grpc/grpc-common/cpp/helloworld). + +A more detailed tutorial is coming soon. -- cgit v1.2.3 From aa6c5fd7769cf2d398852153e9c89bbe5a0e0b4e Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 20 Feb 2015 15:41:55 -0800 Subject: Fixed broken link --- cpp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/README.md b/cpp/README.md index 376a3731c3..a95bd3c8f0 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -1,7 +1,7 @@ #gRPC C++ Getting started First you need to install gRPC on your system. Follow the instructions here: -[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/INSTALL). +[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). After installing, you can proceed to the [gRPC C++ Hello World tutorial](https://github.com/grpc/grpc-common/cpp/helloworld). -- cgit v1.2.3 From 5621545e4c66fabec705284c6bfa86d0223bb0a8 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Fri, 20 Feb 2015 16:01:15 -0800 Subject: Finish of a dummy client/server pair --- cpp/route_guide/Makefile | 79 +- cpp/route_guide/route_guide.pb.cc | 1736 --------------------------------- cpp/route_guide/route_guide.pb.h | 929 ------------------ cpp/route_guide/route_guide_client.cc | 99 +- cpp/route_guide/route_guide_server.cc | 37 +- 5 files changed, 177 insertions(+), 2703 deletions(-) delete mode 100644 cpp/route_guide/route_guide.pb.cc delete mode 100644 cpp/route_guide/route_guide.pb.h diff --git a/cpp/route_guide/Makefile b/cpp/route_guide/Makefile index 444841f8b8..fae9a9d284 100644 --- a/cpp/route_guide/Makefile +++ b/cpp/route_guide/Makefile @@ -29,19 +29,82 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -CXX=g++ -CPPFLAGS=-I/usr/local/include -pthread -CXXFLAGS=-std=c++11 -LDFLAGS=-L/usr/local/lib -lgrpc -lgrpc++ -lprotobuf -lpthread -ldl +CXX = g++ +CPPFLAGS = -I/usr/local/include -pthread +CXXFLAGS = -std=c++11 +LDFLAGS = -L/usr/local/lib -lgpr -lgrpc -lgrpc++ -lprotobuf -lpthread -ldl +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` -all: route_guide_client route_guide_server +PROTOS_PATH = ../../protos + +vpath %.proto $(PROTOS_PATH) + +all: system-check route_guide_client route_guide_server route_guide_client: route_guide.pb.o route_guide_client.o - $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ + $(CXX) $^ $(LDFLAGS) -o $@ route_guide_server: route_guide.pb.o route_guide_server.o - $(CXX) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ + $(CXX) $^ $(LDFLAGS) -o $@ + +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< clean: - rm -f *.o route_guide_client route_guide_server + rm -f *.o *.pb.cc *.pb.h route_guide_client route_guide_server + + +# The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + +PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + +SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif +system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-alpha-1" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif diff --git a/cpp/route_guide/route_guide.pb.cc b/cpp/route_guide/route_guide.pb.cc deleted file mode 100644 index 6f4a1e7066..0000000000 --- a/cpp/route_guide/route_guide.pb.cc +++ /dev/null @@ -1,1736 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: route_guide.proto - -#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION -#include "route_guide.pb.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// @@protoc_insertion_point(includes) - -namespace examples { - -namespace { - -const ::google::protobuf::Descriptor* Point_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - Point_reflection_ = NULL; -const ::google::protobuf::Descriptor* Rectangle_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - Rectangle_reflection_ = NULL; -const ::google::protobuf::Descriptor* Feature_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - Feature_reflection_ = NULL; -const ::google::protobuf::Descriptor* RouteNote_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - RouteNote_reflection_ = NULL; -const ::google::protobuf::Descriptor* RouteSummary_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - RouteSummary_reflection_ = NULL; - -} // namespace - - -void protobuf_AssignDesc_route_5fguide_2eproto() { - protobuf_AddDesc_route_5fguide_2eproto(); - const ::google::protobuf::FileDescriptor* file = - ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( - "route_guide.proto"); - GOOGLE_CHECK(file != NULL); - Point_descriptor_ = file->message_type(0); - static const int Point_offsets_[2] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Point, latitude_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Point, longitude_), - }; - Point_reflection_ = - ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( - Point_descriptor_, - Point::default_instance_, - Point_offsets_, - -1, - -1, - -1, - sizeof(Point), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Point, _internal_metadata_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Point, _is_default_instance_)); - Rectangle_descriptor_ = file->message_type(1); - static const int Rectangle_offsets_[2] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Rectangle, lo_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Rectangle, hi_), - }; - Rectangle_reflection_ = - ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( - Rectangle_descriptor_, - Rectangle::default_instance_, - Rectangle_offsets_, - -1, - -1, - -1, - sizeof(Rectangle), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Rectangle, _internal_metadata_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Rectangle, _is_default_instance_)); - Feature_descriptor_ = file->message_type(2); - static const int Feature_offsets_[2] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Feature, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Feature, location_), - }; - Feature_reflection_ = - ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( - Feature_descriptor_, - Feature::default_instance_, - Feature_offsets_, - -1, - -1, - -1, - sizeof(Feature), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Feature, _internal_metadata_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Feature, _is_default_instance_)); - RouteNote_descriptor_ = file->message_type(3); - static const int RouteNote_offsets_[2] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteNote, location_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteNote, message_), - }; - RouteNote_reflection_ = - ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( - RouteNote_descriptor_, - RouteNote::default_instance_, - RouteNote_offsets_, - -1, - -1, - -1, - sizeof(RouteNote), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteNote, _internal_metadata_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteNote, _is_default_instance_)); - RouteSummary_descriptor_ = file->message_type(4); - static const int RouteSummary_offsets_[4] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteSummary, point_count_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteSummary, feature_count_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteSummary, distance_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteSummary, elapsed_time_), - }; - RouteSummary_reflection_ = - ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( - RouteSummary_descriptor_, - RouteSummary::default_instance_, - RouteSummary_offsets_, - -1, - -1, - -1, - sizeof(RouteSummary), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteSummary, _internal_metadata_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RouteSummary, _is_default_instance_)); -} - -namespace { - -GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); -inline void protobuf_AssignDescriptorsOnce() { - ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, - &protobuf_AssignDesc_route_5fguide_2eproto); -} - -void protobuf_RegisterTypes(const ::std::string&) { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - Point_descriptor_, &Point::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - Rectangle_descriptor_, &Rectangle::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - Feature_descriptor_, &Feature::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - RouteNote_descriptor_, &RouteNote::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - RouteSummary_descriptor_, &RouteSummary::default_instance()); -} - -} // namespace - -void protobuf_ShutdownFile_route_5fguide_2eproto() { - delete Point::default_instance_; - delete Point_reflection_; - delete Rectangle::default_instance_; - delete Rectangle_reflection_; - delete Feature::default_instance_; - delete Feature_reflection_; - delete RouteNote::default_instance_; - delete RouteNote_reflection_; - delete RouteSummary::default_instance_; - delete RouteSummary_reflection_; -} - -void protobuf_AddDesc_route_5fguide_2eproto() { - static bool already_here = false; - if (already_here) return; - already_here = true; - GOOGLE_PROTOBUF_VERIFY_VERSION; - - ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - "\n\021route_guide.proto\022\010examples\",\n\005Point\022\020" - "\n\010latitude\030\001 \001(\005\022\021\n\tlongitude\030\002 \001(\005\"E\n\tR" - "ectangle\022\033\n\002lo\030\001 \001(\0132\017.examples.Point\022\033\n" - "\002hi\030\002 \001(\0132\017.examples.Point\":\n\007Feature\022\014\n" - "\004name\030\001 \001(\t\022!\n\010location\030\002 \001(\0132\017.examples" - ".Point\"\?\n\tRouteNote\022!\n\010location\030\001 \001(\0132\017." - "examples.Point\022\017\n\007message\030\002 \001(\t\"b\n\014Route" - "Summary\022\023\n\013point_count\030\001 \001(\005\022\025\n\rfeature_" - "count\030\002 \001(\005\022\020\n\010distance\030\003 \001(\005\022\024\n\014elapsed" - "_time\030\004 \001(\0052\365\001\n\nRouteGuide\0222\n\nGetFeature" - "\022\017.examples.Point\032\021.examples.Feature\"\000\022:" - "\n\014ListFeatures\022\023.examples.Rectangle\032\021.ex" - "amples.Feature\"\0000\001\022:\n\013RecordRoute\022\017.exam" - "ples.Point\032\026.examples.RouteSummary\"\000(\001\022;" - "\n\tRouteChat\022\023.examples.RouteNote\032\023.examp" - "les.RouteNote\"\000(\0010\001B\t\n\007ex.grpcb\006proto3", 638); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( - "route_guide.proto", &protobuf_RegisterTypes); - Point::default_instance_ = new Point(); - Rectangle::default_instance_ = new Rectangle(); - Feature::default_instance_ = new Feature(); - RouteNote::default_instance_ = new RouteNote(); - RouteSummary::default_instance_ = new RouteSummary(); - Point::default_instance_->InitAsDefaultInstance(); - Rectangle::default_instance_->InitAsDefaultInstance(); - Feature::default_instance_->InitAsDefaultInstance(); - RouteNote::default_instance_->InitAsDefaultInstance(); - RouteSummary::default_instance_->InitAsDefaultInstance(); - ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_route_5fguide_2eproto); -} - -// Force AddDescriptors() to be called at static initialization time. -struct StaticDescriptorInitializer_route_5fguide_2eproto { - StaticDescriptorInitializer_route_5fguide_2eproto() { - protobuf_AddDesc_route_5fguide_2eproto(); - } -} static_descriptor_initializer_route_5fguide_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 Point::kLatitudeFieldNumber; -const int Point::kLongitudeFieldNumber; -#endif // !_MSC_VER - -Point::Point() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { - SharedCtor(); - // @@protoc_insertion_point(constructor:examples.Point) -} - -void Point::InitAsDefaultInstance() { - _is_default_instance_ = true; -} - -Point::Point(const Point& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL) { - SharedCtor(); - MergeFrom(from); - // @@protoc_insertion_point(copy_constructor:examples.Point) -} - -void Point::SharedCtor() { - _is_default_instance_ = false; - _cached_size_ = 0; - latitude_ = 0; - longitude_ = 0; -} - -Point::~Point() { - // @@protoc_insertion_point(destructor:examples.Point) - SharedDtor(); -} - -void Point::SharedDtor() { - if (this != default_instance_) { - } -} - -void Point::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* Point::descriptor() { - protobuf_AssignDescriptorsOnce(); - return Point_descriptor_; -} - -const Point& Point::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_route_5fguide_2eproto(); - return *default_instance_; -} - -Point* Point::default_instance_ = NULL; - -Point* Point::New(::google::protobuf::Arena* arena) const { - Point* n = new Point; - if (arena != NULL) { - arena->Own(n); - } - return n; -} - -void Point::Clear() { -#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ - &reinterpret_cast(16)->f) - \ - reinterpret_cast(16)) - -#define ZR_(first, last) do { \ - size_t f = OFFSET_OF_FIELD_(first); \ - size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ - ::memset(&first, 0, n); \ - } while (0) - - ZR_(latitude_, longitude_); - -#undef OFFSET_OF_FIELD_ -#undef ZR_ - -} - -bool Point::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:examples.Point) - 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 int32 latitude = 1; - case 1: { - if (tag == 8) { - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( - input, &latitude_))); - - } else { - goto handle_unusual; - } - if (input->ExpectTag(16)) goto parse_longitude; - break; - } - - // optional int32 longitude = 2; - case 2: { - if (tag == 16) { - parse_longitude: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( - input, &longitude_))); - - } 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:examples.Point) - return true; -failure: - // @@protoc_insertion_point(parse_failure:examples.Point) - return false; -#undef DO_ -} - -void Point::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:examples.Point) - // optional int32 latitude = 1; - if (this->latitude() != 0) { - ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->latitude(), output); - } - - // optional int32 longitude = 2; - if (this->longitude() != 0) { - ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->longitude(), output); - } - - // @@protoc_insertion_point(serialize_end:examples.Point) -} - -::google::protobuf::uint8* Point::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // @@protoc_insertion_point(serialize_to_array_start:examples.Point) - // optional int32 latitude = 1; - if (this->latitude() != 0) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->latitude(), target); - } - - // optional int32 longitude = 2; - if (this->longitude() != 0) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->longitude(), target); - } - - // @@protoc_insertion_point(serialize_to_array_end:examples.Point) - return target; -} - -int Point::ByteSize() const { - int total_size = 0; - - // optional int32 latitude = 1; - if (this->latitude() != 0) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size( - this->latitude()); - } - - // optional int32 longitude = 2; - if (this->longitude() != 0) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size( - this->longitude()); - } - - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void Point::MergeFrom(const ::google::protobuf::Message& from) { - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const Point* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void Point::MergeFrom(const Point& from) { - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - if (from.latitude() != 0) { - set_latitude(from.latitude()); - } - if (from.longitude() != 0) { - set_longitude(from.longitude()); - } -} - -void Point::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void Point::CopyFrom(const Point& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool Point::IsInitialized() const { - - return true; -} - -void Point::Swap(Point* other) { - if (other == this) return; - InternalSwap(other); -} -void Point::InternalSwap(Point* other) { - std::swap(latitude_, other->latitude_); - std::swap(longitude_, other->longitude_); - _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); -} - -::google::protobuf::Metadata Point::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = Point_descriptor_; - metadata.reflection = Point_reflection_; - return metadata; -} - - -// =================================================================== - -#ifndef _MSC_VER -const int Rectangle::kLoFieldNumber; -const int Rectangle::kHiFieldNumber; -#endif // !_MSC_VER - -Rectangle::Rectangle() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { - SharedCtor(); - // @@protoc_insertion_point(constructor:examples.Rectangle) -} - -void Rectangle::InitAsDefaultInstance() { - _is_default_instance_ = true; - lo_ = const_cast< ::examples::Point*>(&::examples::Point::default_instance()); - hi_ = const_cast< ::examples::Point*>(&::examples::Point::default_instance()); -} - -Rectangle::Rectangle(const Rectangle& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL) { - SharedCtor(); - MergeFrom(from); - // @@protoc_insertion_point(copy_constructor:examples.Rectangle) -} - -void Rectangle::SharedCtor() { - _is_default_instance_ = false; - _cached_size_ = 0; - lo_ = NULL; - hi_ = NULL; -} - -Rectangle::~Rectangle() { - // @@protoc_insertion_point(destructor:examples.Rectangle) - SharedDtor(); -} - -void Rectangle::SharedDtor() { - if (this != default_instance_) { - delete lo_; - delete hi_; - } -} - -void Rectangle::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* Rectangle::descriptor() { - protobuf_AssignDescriptorsOnce(); - return Rectangle_descriptor_; -} - -const Rectangle& Rectangle::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_route_5fguide_2eproto(); - return *default_instance_; -} - -Rectangle* Rectangle::default_instance_ = NULL; - -Rectangle* Rectangle::New(::google::protobuf::Arena* arena) const { - Rectangle* n = new Rectangle; - if (arena != NULL) { - arena->Own(n); - } - return n; -} - -void Rectangle::Clear() { - if (lo_ != NULL) delete lo_; - lo_ = NULL; - if (hi_ != NULL) delete hi_; - hi_ = NULL; -} - -bool Rectangle::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:examples.Rectangle) - 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 .examples.Point lo = 1; - case 1: { - if (tag == 10) { - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_lo())); - } else { - goto handle_unusual; - } - if (input->ExpectTag(18)) goto parse_hi; - break; - } - - // optional .examples.Point hi = 2; - case 2: { - if (tag == 18) { - parse_hi: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_hi())); - } 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:examples.Rectangle) - return true; -failure: - // @@protoc_insertion_point(parse_failure:examples.Rectangle) - return false; -#undef DO_ -} - -void Rectangle::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:examples.Rectangle) - // optional .examples.Point lo = 1; - if (this->has_lo()) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 1, *this->lo_, output); - } - - // optional .examples.Point hi = 2; - if (this->has_hi()) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 2, *this->hi_, output); - } - - // @@protoc_insertion_point(serialize_end:examples.Rectangle) -} - -::google::protobuf::uint8* Rectangle::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // @@protoc_insertion_point(serialize_to_array_start:examples.Rectangle) - // optional .examples.Point lo = 1; - if (this->has_lo()) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 1, *this->lo_, target); - } - - // optional .examples.Point hi = 2; - if (this->has_hi()) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, *this->hi_, target); - } - - // @@protoc_insertion_point(serialize_to_array_end:examples.Rectangle) - return target; -} - -int Rectangle::ByteSize() const { - int total_size = 0; - - // optional .examples.Point lo = 1; - if (this->has_lo()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - *this->lo_); - } - - // optional .examples.Point hi = 2; - if (this->has_hi()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - *this->hi_); - } - - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void Rectangle::MergeFrom(const ::google::protobuf::Message& from) { - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const Rectangle* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void Rectangle::MergeFrom(const Rectangle& from) { - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - if (from.has_lo()) { - mutable_lo()->::examples::Point::MergeFrom(from.lo()); - } - if (from.has_hi()) { - mutable_hi()->::examples::Point::MergeFrom(from.hi()); - } -} - -void Rectangle::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void Rectangle::CopyFrom(const Rectangle& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool Rectangle::IsInitialized() const { - - return true; -} - -void Rectangle::Swap(Rectangle* other) { - if (other == this) return; - InternalSwap(other); -} -void Rectangle::InternalSwap(Rectangle* other) { - std::swap(lo_, other->lo_); - std::swap(hi_, other->hi_); - _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); -} - -::google::protobuf::Metadata Rectangle::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = Rectangle_descriptor_; - metadata.reflection = Rectangle_reflection_; - return metadata; -} - - -// =================================================================== - -#ifndef _MSC_VER -const int Feature::kNameFieldNumber; -const int Feature::kLocationFieldNumber; -#endif // !_MSC_VER - -Feature::Feature() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { - SharedCtor(); - // @@protoc_insertion_point(constructor:examples.Feature) -} - -void Feature::InitAsDefaultInstance() { - _is_default_instance_ = true; - location_ = const_cast< ::examples::Point*>(&::examples::Point::default_instance()); -} - -Feature::Feature(const Feature& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL) { - SharedCtor(); - MergeFrom(from); - // @@protoc_insertion_point(copy_constructor:examples.Feature) -} - -void Feature::SharedCtor() { - _is_default_instance_ = false; - ::google::protobuf::internal::GetEmptyString(); - _cached_size_ = 0; - name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - location_ = NULL; -} - -Feature::~Feature() { - // @@protoc_insertion_point(destructor:examples.Feature) - SharedDtor(); -} - -void Feature::SharedDtor() { - name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (this != default_instance_) { - delete location_; - } -} - -void Feature::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* Feature::descriptor() { - protobuf_AssignDescriptorsOnce(); - return Feature_descriptor_; -} - -const Feature& Feature::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_route_5fguide_2eproto(); - return *default_instance_; -} - -Feature* Feature::default_instance_ = NULL; - -Feature* Feature::New(::google::protobuf::Arena* arena) const { - Feature* n = new Feature; - if (arena != NULL) { - arena->Own(n); - } - return n; -} - -void Feature::Clear() { - name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (location_ != NULL) delete location_; - location_ = NULL; -} - -bool Feature::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:examples.Feature) - 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, - "examples.Feature.name"); - } else { - goto handle_unusual; - } - if (input->ExpectTag(18)) goto parse_location; - break; - } - - // optional .examples.Point location = 2; - case 2: { - if (tag == 18) { - parse_location: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_location())); - } 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:examples.Feature) - return true; -failure: - // @@protoc_insertion_point(parse_failure:examples.Feature) - return false; -#undef DO_ -} - -void Feature::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:examples.Feature) - // 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, - "examples.Feature.name"); - ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( - 1, this->name(), output); - } - - // optional .examples.Point location = 2; - if (this->has_location()) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 2, *this->location_, output); - } - - // @@protoc_insertion_point(serialize_end:examples.Feature) -} - -::google::protobuf::uint8* Feature::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // @@protoc_insertion_point(serialize_to_array_start:examples.Feature) - // 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, - "examples.Feature.name"); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->name(), target); - } - - // optional .examples.Point location = 2; - if (this->has_location()) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, *this->location_, target); - } - - // @@protoc_insertion_point(serialize_to_array_end:examples.Feature) - return target; -} - -int Feature::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()); - } - - // optional .examples.Point location = 2; - if (this->has_location()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - *this->location_); - } - - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void Feature::MergeFrom(const ::google::protobuf::Message& from) { - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const Feature* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void Feature::MergeFrom(const Feature& from) { - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - if (from.name().size() > 0) { - - name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); - } - if (from.has_location()) { - mutable_location()->::examples::Point::MergeFrom(from.location()); - } -} - -void Feature::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void Feature::CopyFrom(const Feature& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool Feature::IsInitialized() const { - - return true; -} - -void Feature::Swap(Feature* other) { - if (other == this) return; - InternalSwap(other); -} -void Feature::InternalSwap(Feature* other) { - name_.Swap(&other->name_); - std::swap(location_, other->location_); - _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); -} - -::google::protobuf::Metadata Feature::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = Feature_descriptor_; - metadata.reflection = Feature_reflection_; - return metadata; -} - - -// =================================================================== - -#ifndef _MSC_VER -const int RouteNote::kLocationFieldNumber; -const int RouteNote::kMessageFieldNumber; -#endif // !_MSC_VER - -RouteNote::RouteNote() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { - SharedCtor(); - // @@protoc_insertion_point(constructor:examples.RouteNote) -} - -void RouteNote::InitAsDefaultInstance() { - _is_default_instance_ = true; - location_ = const_cast< ::examples::Point*>(&::examples::Point::default_instance()); -} - -RouteNote::RouteNote(const RouteNote& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL) { - SharedCtor(); - MergeFrom(from); - // @@protoc_insertion_point(copy_constructor:examples.RouteNote) -} - -void RouteNote::SharedCtor() { - _is_default_instance_ = false; - ::google::protobuf::internal::GetEmptyString(); - _cached_size_ = 0; - location_ = NULL; - message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - -RouteNote::~RouteNote() { - // @@protoc_insertion_point(destructor:examples.RouteNote) - SharedDtor(); -} - -void RouteNote::SharedDtor() { - message_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (this != default_instance_) { - delete location_; - } -} - -void RouteNote::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* RouteNote::descriptor() { - protobuf_AssignDescriptorsOnce(); - return RouteNote_descriptor_; -} - -const RouteNote& RouteNote::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_route_5fguide_2eproto(); - return *default_instance_; -} - -RouteNote* RouteNote::default_instance_ = NULL; - -RouteNote* RouteNote::New(::google::protobuf::Arena* arena) const { - RouteNote* n = new RouteNote; - if (arena != NULL) { - arena->Own(n); - } - return n; -} - -void RouteNote::Clear() { - if (location_ != NULL) delete location_; - location_ = NULL; - message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - -bool RouteNote::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:examples.RouteNote) - 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 .examples.Point location = 1; - case 1: { - if (tag == 10) { - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_location())); - } else { - goto handle_unusual; - } - if (input->ExpectTag(18)) goto parse_message; - break; - } - - // optional string message = 2; - case 2: { - if (tag == 18) { - parse_message: - 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, - "examples.RouteNote.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:examples.RouteNote) - return true; -failure: - // @@protoc_insertion_point(parse_failure:examples.RouteNote) - return false; -#undef DO_ -} - -void RouteNote::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:examples.RouteNote) - // optional .examples.Point location = 1; - if (this->has_location()) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 1, *this->location_, output); - } - - // optional string message = 2; - if (this->message().size() > 0) { - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->message().data(), this->message().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE, - "examples.RouteNote.message"); - ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( - 2, this->message(), output); - } - - // @@protoc_insertion_point(serialize_end:examples.RouteNote) -} - -::google::protobuf::uint8* RouteNote::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // @@protoc_insertion_point(serialize_to_array_start:examples.RouteNote) - // optional .examples.Point location = 1; - if (this->has_location()) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 1, *this->location_, target); - } - - // optional string message = 2; - if (this->message().size() > 0) { - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->message().data(), this->message().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE, - "examples.RouteNote.message"); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 2, this->message(), target); - } - - // @@protoc_insertion_point(serialize_to_array_end:examples.RouteNote) - return target; -} - -int RouteNote::ByteSize() const { - int total_size = 0; - - // optional .examples.Point location = 1; - if (this->has_location()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - *this->location_); - } - - // optional string message = 2; - 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 RouteNote::MergeFrom(const ::google::protobuf::Message& from) { - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const RouteNote* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void RouteNote::MergeFrom(const RouteNote& from) { - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - if (from.has_location()) { - mutable_location()->::examples::Point::MergeFrom(from.location()); - } - if (from.message().size() > 0) { - - message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_); - } -} - -void RouteNote::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void RouteNote::CopyFrom(const RouteNote& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool RouteNote::IsInitialized() const { - - return true; -} - -void RouteNote::Swap(RouteNote* other) { - if (other == this) return; - InternalSwap(other); -} -void RouteNote::InternalSwap(RouteNote* other) { - std::swap(location_, other->location_); - message_.Swap(&other->message_); - _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); -} - -::google::protobuf::Metadata RouteNote::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = RouteNote_descriptor_; - metadata.reflection = RouteNote_reflection_; - return metadata; -} - - -// =================================================================== - -#ifndef _MSC_VER -const int RouteSummary::kPointCountFieldNumber; -const int RouteSummary::kFeatureCountFieldNumber; -const int RouteSummary::kDistanceFieldNumber; -const int RouteSummary::kElapsedTimeFieldNumber; -#endif // !_MSC_VER - -RouteSummary::RouteSummary() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { - SharedCtor(); - // @@protoc_insertion_point(constructor:examples.RouteSummary) -} - -void RouteSummary::InitAsDefaultInstance() { - _is_default_instance_ = true; -} - -RouteSummary::RouteSummary(const RouteSummary& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL) { - SharedCtor(); - MergeFrom(from); - // @@protoc_insertion_point(copy_constructor:examples.RouteSummary) -} - -void RouteSummary::SharedCtor() { - _is_default_instance_ = false; - _cached_size_ = 0; - point_count_ = 0; - feature_count_ = 0; - distance_ = 0; - elapsed_time_ = 0; -} - -RouteSummary::~RouteSummary() { - // @@protoc_insertion_point(destructor:examples.RouteSummary) - SharedDtor(); -} - -void RouteSummary::SharedDtor() { - if (this != default_instance_) { - } -} - -void RouteSummary::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* RouteSummary::descriptor() { - protobuf_AssignDescriptorsOnce(); - return RouteSummary_descriptor_; -} - -const RouteSummary& RouteSummary::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_route_5fguide_2eproto(); - return *default_instance_; -} - -RouteSummary* RouteSummary::default_instance_ = NULL; - -RouteSummary* RouteSummary::New(::google::protobuf::Arena* arena) const { - RouteSummary* n = new RouteSummary; - if (arena != NULL) { - arena->Own(n); - } - return n; -} - -void RouteSummary::Clear() { -#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ - &reinterpret_cast(16)->f) - \ - reinterpret_cast(16)) - -#define ZR_(first, last) do { \ - size_t f = OFFSET_OF_FIELD_(first); \ - size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ - ::memset(&first, 0, n); \ - } while (0) - - ZR_(point_count_, elapsed_time_); - -#undef OFFSET_OF_FIELD_ -#undef ZR_ - -} - -bool RouteSummary::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:examples.RouteSummary) - 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 int32 point_count = 1; - case 1: { - if (tag == 8) { - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( - input, &point_count_))); - - } else { - goto handle_unusual; - } - if (input->ExpectTag(16)) goto parse_feature_count; - break; - } - - // optional int32 feature_count = 2; - case 2: { - if (tag == 16) { - parse_feature_count: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( - input, &feature_count_))); - - } else { - goto handle_unusual; - } - if (input->ExpectTag(24)) goto parse_distance; - break; - } - - // optional int32 distance = 3; - case 3: { - if (tag == 24) { - parse_distance: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( - input, &distance_))); - - } else { - goto handle_unusual; - } - if (input->ExpectTag(32)) goto parse_elapsed_time; - break; - } - - // optional int32 elapsed_time = 4; - case 4: { - if (tag == 32) { - parse_elapsed_time: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( - input, &elapsed_time_))); - - } 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:examples.RouteSummary) - return true; -failure: - // @@protoc_insertion_point(parse_failure:examples.RouteSummary) - return false; -#undef DO_ -} - -void RouteSummary::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:examples.RouteSummary) - // optional int32 point_count = 1; - if (this->point_count() != 0) { - ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->point_count(), output); - } - - // optional int32 feature_count = 2; - if (this->feature_count() != 0) { - ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->feature_count(), output); - } - - // optional int32 distance = 3; - if (this->distance() != 0) { - ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->distance(), output); - } - - // optional int32 elapsed_time = 4; - if (this->elapsed_time() != 0) { - ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->elapsed_time(), output); - } - - // @@protoc_insertion_point(serialize_end:examples.RouteSummary) -} - -::google::protobuf::uint8* RouteSummary::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // @@protoc_insertion_point(serialize_to_array_start:examples.RouteSummary) - // optional int32 point_count = 1; - if (this->point_count() != 0) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->point_count(), target); - } - - // optional int32 feature_count = 2; - if (this->feature_count() != 0) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->feature_count(), target); - } - - // optional int32 distance = 3; - if (this->distance() != 0) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->distance(), target); - } - - // optional int32 elapsed_time = 4; - if (this->elapsed_time() != 0) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->elapsed_time(), target); - } - - // @@protoc_insertion_point(serialize_to_array_end:examples.RouteSummary) - return target; -} - -int RouteSummary::ByteSize() const { - int total_size = 0; - - // optional int32 point_count = 1; - if (this->point_count() != 0) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size( - this->point_count()); - } - - // optional int32 feature_count = 2; - if (this->feature_count() != 0) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size( - this->feature_count()); - } - - // optional int32 distance = 3; - if (this->distance() != 0) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size( - this->distance()); - } - - // optional int32 elapsed_time = 4; - if (this->elapsed_time() != 0) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size( - this->elapsed_time()); - } - - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void RouteSummary::MergeFrom(const ::google::protobuf::Message& from) { - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const RouteSummary* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void RouteSummary::MergeFrom(const RouteSummary& from) { - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - if (from.point_count() != 0) { - set_point_count(from.point_count()); - } - if (from.feature_count() != 0) { - set_feature_count(from.feature_count()); - } - if (from.distance() != 0) { - set_distance(from.distance()); - } - if (from.elapsed_time() != 0) { - set_elapsed_time(from.elapsed_time()); - } -} - -void RouteSummary::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void RouteSummary::CopyFrom(const RouteSummary& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool RouteSummary::IsInitialized() const { - - return true; -} - -void RouteSummary::Swap(RouteSummary* other) { - if (other == this) return; - InternalSwap(other); -} -void RouteSummary::InternalSwap(RouteSummary* other) { - std::swap(point_count_, other->point_count_); - std::swap(feature_count_, other->feature_count_); - std::swap(distance_, other->distance_); - std::swap(elapsed_time_, other->elapsed_time_); - _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); -} - -::google::protobuf::Metadata RouteSummary::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = RouteSummary_descriptor_; - metadata.reflection = RouteSummary_reflection_; - return metadata; -} - - -static const char* RouteGuide_method_names[] = { - "/examples.RouteGuide/GetFeature", - "/examples.RouteGuide/ListFeatures", - "/examples.RouteGuide/RecordRoute", - "/examples.RouteGuide/RouteChat", -}; - -RouteGuide::Stub* RouteGuide::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel) { - RouteGuide::Stub* stub = new RouteGuide::Stub(); - stub->set_channel(channel); - return stub; -}; - -::grpc::Status RouteGuide::Stub::GetFeature(::grpc::ClientContext* context, const ::examples::Point& request, ::examples::Feature* response) { - return ::grpc::BlockingUnaryCall(channel(),::grpc::RpcMethod(RouteGuide_method_names[0]), context, request, response); -} - -::grpc::ClientAsyncResponseReader< ::examples::Feature>* RouteGuide::Stub::GetFeature(::grpc::ClientContext* context, const ::examples::Point& request, ::grpc::CompletionQueue* cq, void* tag) { - return new ::grpc::ClientAsyncResponseReader< ::examples::Feature>(channel(), cq, ::grpc::RpcMethod(RouteGuide_method_names[0]), context, request, tag); -} - -::grpc::ClientReader< ::examples::Feature>* RouteGuide::Stub::ListFeatures(::grpc::ClientContext* context, const ::examples::Rectangle& request) { - return new ::grpc::ClientReader< ::examples::Feature>(channel(),::grpc::RpcMethod(RouteGuide_method_names[1], ::grpc::RpcMethod::RpcType::SERVER_STREAMING), context, request); -} - -::grpc::ClientAsyncReader< ::examples::Feature>* RouteGuide::Stub::ListFeatures(::grpc::ClientContext* context, const ::examples::Rectangle& request, ::grpc::CompletionQueue* cq, void* tag) { - return new ::grpc::ClientAsyncReader< ::examples::Feature>(channel(), cq, ::grpc::RpcMethod(RouteGuide_method_names[1], ::grpc::RpcMethod::RpcType::SERVER_STREAMING), context, request, tag); -} - -::grpc::ClientWriter< ::examples::Point>* RouteGuide::Stub::RecordRoute(::grpc::ClientContext* context, ::examples::RouteSummary* response) { - return new ::grpc::ClientWriter< ::examples::Point>(channel(),::grpc::RpcMethod(RouteGuide_method_names[2], ::grpc::RpcMethod::RpcType::CLIENT_STREAMING), context, response); -} - -::grpc::ClientAsyncWriter< ::examples::Point>* RouteGuide::Stub::RecordRoute(::grpc::ClientContext* context, ::examples::RouteSummary* response, ::grpc::CompletionQueue* cq, void* tag) { - return new ::grpc::ClientAsyncWriter< ::examples::Point>(channel(), cq, ::grpc::RpcMethod(RouteGuide_method_names[2], ::grpc::RpcMethod::RpcType::CLIENT_STREAMING), context, response, tag); -} - -::grpc::ClientReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* RouteGuide::Stub::RouteChat(::grpc::ClientContext* context) { - return new ::grpc::ClientReaderWriter< ::examples::RouteNote, ::examples::RouteNote>(channel(),::grpc::RpcMethod(RouteGuide_method_names[3], ::grpc::RpcMethod::RpcType::BIDI_STREAMING), context); -} - -::grpc::ClientAsyncReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* RouteGuide::Stub::RouteChat(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) { - return new ::grpc::ClientAsyncReaderWriter< ::examples::RouteNote, ::examples::RouteNote>(channel(), cq, ::grpc::RpcMethod(RouteGuide_method_names[3], ::grpc::RpcMethod::RpcType::BIDI_STREAMING), context, tag); -} - -RouteGuide::AsyncService::AsyncService(::grpc::CompletionQueue* cq) : ::grpc::AsynchronousService(cq, RouteGuide_method_names, 4) {} - -RouteGuide::Service::~Service() { - delete service_; -} - -::grpc::Status RouteGuide::Service::GetFeature(::grpc::ServerContext* context, const ::examples::Point* request, ::examples::Feature* response) { - return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED); -} - -void RouteGuide::AsyncService::RequestGetFeature(::grpc::ServerContext* context, ::examples::Point* request, ::grpc::ServerAsyncResponseWriter< ::examples::Feature>* response, ::grpc::CompletionQueue* cq, void* tag) { - AsynchronousService::RequestAsyncUnary(0, context, request, response, cq, tag); -} - -::grpc::Status RouteGuide::Service::ListFeatures(::grpc::ServerContext* context, const ::examples::Rectangle* request, ::grpc::ServerWriter< ::examples::Feature>* writer) { - return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED); -} - -void RouteGuide::AsyncService::RequestListFeatures(::grpc::ServerContext* context, ::examples::Rectangle* request, ::grpc::ServerAsyncWriter< ::examples::Feature>* writer, ::grpc::CompletionQueue* cq, void* tag) { - AsynchronousService::RequestServerStreaming(1, context, request, writer, cq, tag); -} - -::grpc::Status RouteGuide::Service::RecordRoute(::grpc::ServerContext* context, ::grpc::ServerReader< ::examples::Point>* reader, ::examples::RouteSummary* response) { - return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED); -} - -void RouteGuide::AsyncService::RequestRecordRoute(::grpc::ServerContext* context, ::grpc::ServerAsyncReader< ::examples::RouteSummary, ::examples::Point>* reader, ::grpc::CompletionQueue* cq, void* tag) { - AsynchronousService::RequestClientStreaming(2, context, reader, cq, tag); -} - -::grpc::Status RouteGuide::Service::RouteChat(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* stream) { - return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED); -} - -void RouteGuide::AsyncService::RequestRouteChat(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* stream, ::grpc::CompletionQueue* cq, void *tag) { - AsynchronousService::RequestBidiStreaming(3, context, stream, cq, tag); -} - -::grpc::RpcService* RouteGuide::Service::service() { - if (service_ != nullptr) { - return service_; - } - service_ = new ::grpc::RpcService(); - service_->AddMethod(new ::grpc::RpcServiceMethod( - RouteGuide_method_names[0], - ::grpc::RpcMethod::NORMAL_RPC, - new ::grpc::RpcMethodHandler< RouteGuide::Service, ::examples::Point, ::examples::Feature>( - std::function< ::grpc::Status(RouteGuide::Service*, ::grpc::ServerContext*, const ::examples::Point*, ::examples::Feature*)>(&RouteGuide::Service::GetFeature), this), - new ::examples::Point, new ::examples::Feature)); - service_->AddMethod(new ::grpc::RpcServiceMethod( - RouteGuide_method_names[1], - ::grpc::RpcMethod::SERVER_STREAMING, - new ::grpc::ServerStreamingHandler< RouteGuide::Service, ::examples::Rectangle, ::examples::Feature>( - std::function< ::grpc::Status(RouteGuide::Service*, ::grpc::ServerContext*, const ::examples::Rectangle*, ::grpc::ServerWriter< ::examples::Feature>*)>(&RouteGuide::Service::ListFeatures), this), - new ::examples::Rectangle, new ::examples::Feature)); - service_->AddMethod(new ::grpc::RpcServiceMethod( - RouteGuide_method_names[2], - ::grpc::RpcMethod::CLIENT_STREAMING, - new ::grpc::ClientStreamingHandler< RouteGuide::Service, ::examples::Point, ::examples::RouteSummary>( - std::function< ::grpc::Status(RouteGuide::Service*, ::grpc::ServerContext*, ::grpc::ServerReader< ::examples::Point>*, ::examples::RouteSummary*)>(&RouteGuide::Service::RecordRoute), this), - new ::examples::Point, new ::examples::RouteSummary)); - service_->AddMethod(new ::grpc::RpcServiceMethod( - RouteGuide_method_names[3], - ::grpc::RpcMethod::BIDI_STREAMING, - new ::grpc::BidiStreamingHandler< RouteGuide::Service, ::examples::RouteNote, ::examples::RouteNote>( - std::function< ::grpc::Status(RouteGuide::Service*, ::grpc::ServerContext*, ::grpc::ServerReaderWriter< ::examples::RouteNote, ::examples::RouteNote>*)>(&RouteGuide::Service::RouteChat), this), - new ::examples::RouteNote, new ::examples::RouteNote)); - return service_; -} - - -// @@protoc_insertion_point(namespace_scope) - -} // namespace examples - -// @@protoc_insertion_point(global_scope) diff --git a/cpp/route_guide/route_guide.pb.h b/cpp/route_guide/route_guide.pb.h deleted file mode 100644 index 7689003f0a..0000000000 --- a/cpp/route_guide/route_guide.pb.h +++ /dev/null @@ -1,929 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: route_guide.proto - -#ifndef PROTOBUF_route_5fguide_2eproto__INCLUDED -#define PROTOBUF_route_5fguide_2eproto__INCLUDED - -#include - -#include - -#if GOOGLE_PROTOBUF_VERSION < 3000000 -#error This file was generated by a newer version of protoc which is -#error incompatible with your Protocol Buffer headers. Please update -#error your headers. -#endif -#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION -#error This file was generated by an older version of protoc which is -#error incompatible with your Protocol Buffer headers. Please -#error regenerate this file with a newer version of protoc. -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace grpc { -class CompletionQueue; -class ChannelInterface; -class RpcService; -class ServerContext; -template class ClientAsyncResponseReader; -template class ServerAsyncResponseWriter; -template class ClientWriter; -template class ServerReader; -template class ClientAsyncWriter; -template class ServerAsyncReader; -template class ClientReader; -template class ServerWriter; -template class ClientAsyncReader; -template class ServerAsyncWriter; -template -class ClientReaderWriter; -template -class ServerReaderWriter; -template -class ClientAsyncReaderWriter; -template -class ServerAsyncReaderWriter; -} // namespace grpc -// @@protoc_insertion_point(includes) - -namespace examples { - -// Internal implementation detail -- do not call these. -void protobuf_AddDesc_route_5fguide_2eproto(); -void protobuf_AssignDesc_route_5fguide_2eproto(); -void protobuf_ShutdownFile_route_5fguide_2eproto(); - -class Point; -class Rectangle; -class Feature; -class RouteNote; -class RouteSummary; - -// =================================================================== - -class Point : public ::google::protobuf::Message { - public: - Point(); - virtual ~Point(); - - Point(const Point& from); - - inline Point& operator=(const Point& from) { - CopyFrom(from); - return *this; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const Point& default_instance(); - - void Swap(Point* other); - - // implements Message ---------------------------------------------- - - inline Point* New() const { return New(NULL); } - - Point* New(::google::protobuf::Arena* arena) const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const Point& from); - void MergeFrom(const Point& 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(Point* 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 int32 latitude = 1; - inline void clear_latitude(); - static const int kLatitudeFieldNumber = 1; - inline ::google::protobuf::int32 latitude() const; - inline void set_latitude(::google::protobuf::int32 value); - - // optional int32 longitude = 2; - inline void clear_longitude(); - static const int kLongitudeFieldNumber = 2; - inline ::google::protobuf::int32 longitude() const; - inline void set_longitude(::google::protobuf::int32 value); - - // @@protoc_insertion_point(class_scope:examples.Point) - private: - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - bool _is_default_instance_; - ::google::protobuf::int32 latitude_; - ::google::protobuf::int32 longitude_; - mutable int _cached_size_; - friend void protobuf_AddDesc_route_5fguide_2eproto(); - friend void protobuf_AssignDesc_route_5fguide_2eproto(); - friend void protobuf_ShutdownFile_route_5fguide_2eproto(); - - void InitAsDefaultInstance(); - static Point* default_instance_; -}; -// ------------------------------------------------------------------- - -class Rectangle : public ::google::protobuf::Message { - public: - Rectangle(); - virtual ~Rectangle(); - - Rectangle(const Rectangle& from); - - inline Rectangle& operator=(const Rectangle& from) { - CopyFrom(from); - return *this; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const Rectangle& default_instance(); - - void Swap(Rectangle* other); - - // implements Message ---------------------------------------------- - - inline Rectangle* New() const { return New(NULL); } - - Rectangle* New(::google::protobuf::Arena* arena) const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const Rectangle& from); - void MergeFrom(const Rectangle& 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(Rectangle* 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 .examples.Point lo = 1; - inline bool has_lo() const; - inline void clear_lo(); - static const int kLoFieldNumber = 1; - inline const ::examples::Point& lo() const; - inline ::examples::Point* mutable_lo(); - inline ::examples::Point* release_lo(); - inline void set_allocated_lo(::examples::Point* lo); - - // optional .examples.Point hi = 2; - inline bool has_hi() const; - inline void clear_hi(); - static const int kHiFieldNumber = 2; - inline const ::examples::Point& hi() const; - inline ::examples::Point* mutable_hi(); - inline ::examples::Point* release_hi(); - inline void set_allocated_hi(::examples::Point* hi); - - // @@protoc_insertion_point(class_scope:examples.Rectangle) - private: - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - bool _is_default_instance_; - ::examples::Point* lo_; - ::examples::Point* hi_; - mutable int _cached_size_; - friend void protobuf_AddDesc_route_5fguide_2eproto(); - friend void protobuf_AssignDesc_route_5fguide_2eproto(); - friend void protobuf_ShutdownFile_route_5fguide_2eproto(); - - void InitAsDefaultInstance(); - static Rectangle* default_instance_; -}; -// ------------------------------------------------------------------- - -class Feature : public ::google::protobuf::Message { - public: - Feature(); - virtual ~Feature(); - - Feature(const Feature& from); - - inline Feature& operator=(const Feature& from) { - CopyFrom(from); - return *this; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const Feature& default_instance(); - - void Swap(Feature* other); - - // implements Message ---------------------------------------------- - - inline Feature* New() const { return New(NULL); } - - Feature* New(::google::protobuf::Arena* arena) const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const Feature& from); - void MergeFrom(const Feature& 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(Feature* 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); - - // optional .examples.Point location = 2; - inline bool has_location() const; - inline void clear_location(); - static const int kLocationFieldNumber = 2; - inline const ::examples::Point& location() const; - inline ::examples::Point* mutable_location(); - inline ::examples::Point* release_location(); - inline void set_allocated_location(::examples::Point* location); - - // @@protoc_insertion_point(class_scope:examples.Feature) - private: - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - bool _is_default_instance_; - ::google::protobuf::internal::ArenaStringPtr name_; - ::examples::Point* location_; - mutable int _cached_size_; - friend void protobuf_AddDesc_route_5fguide_2eproto(); - friend void protobuf_AssignDesc_route_5fguide_2eproto(); - friend void protobuf_ShutdownFile_route_5fguide_2eproto(); - - void InitAsDefaultInstance(); - static Feature* default_instance_; -}; -// ------------------------------------------------------------------- - -class RouteNote : public ::google::protobuf::Message { - public: - RouteNote(); - virtual ~RouteNote(); - - RouteNote(const RouteNote& from); - - inline RouteNote& operator=(const RouteNote& from) { - CopyFrom(from); - return *this; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const RouteNote& default_instance(); - - void Swap(RouteNote* other); - - // implements Message ---------------------------------------------- - - inline RouteNote* New() const { return New(NULL); } - - RouteNote* New(::google::protobuf::Arena* arena) const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const RouteNote& from); - void MergeFrom(const RouteNote& 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(RouteNote* 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 .examples.Point location = 1; - inline bool has_location() const; - inline void clear_location(); - static const int kLocationFieldNumber = 1; - inline const ::examples::Point& location() const; - inline ::examples::Point* mutable_location(); - inline ::examples::Point* release_location(); - inline void set_allocated_location(::examples::Point* location); - - // optional string message = 2; - inline void clear_message(); - static const int kMessageFieldNumber = 2; - 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:examples.RouteNote) - private: - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - bool _is_default_instance_; - ::examples::Point* location_; - ::google::protobuf::internal::ArenaStringPtr message_; - mutable int _cached_size_; - friend void protobuf_AddDesc_route_5fguide_2eproto(); - friend void protobuf_AssignDesc_route_5fguide_2eproto(); - friend void protobuf_ShutdownFile_route_5fguide_2eproto(); - - void InitAsDefaultInstance(); - static RouteNote* default_instance_; -}; -// ------------------------------------------------------------------- - -class RouteSummary : public ::google::protobuf::Message { - public: - RouteSummary(); - virtual ~RouteSummary(); - - RouteSummary(const RouteSummary& from); - - inline RouteSummary& operator=(const RouteSummary& from) { - CopyFrom(from); - return *this; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const RouteSummary& default_instance(); - - void Swap(RouteSummary* other); - - // implements Message ---------------------------------------------- - - inline RouteSummary* New() const { return New(NULL); } - - RouteSummary* New(::google::protobuf::Arena* arena) const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const RouteSummary& from); - void MergeFrom(const RouteSummary& 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(RouteSummary* 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 int32 point_count = 1; - inline void clear_point_count(); - static const int kPointCountFieldNumber = 1; - inline ::google::protobuf::int32 point_count() const; - inline void set_point_count(::google::protobuf::int32 value); - - // optional int32 feature_count = 2; - inline void clear_feature_count(); - static const int kFeatureCountFieldNumber = 2; - inline ::google::protobuf::int32 feature_count() const; - inline void set_feature_count(::google::protobuf::int32 value); - - // optional int32 distance = 3; - inline void clear_distance(); - static const int kDistanceFieldNumber = 3; - inline ::google::protobuf::int32 distance() const; - inline void set_distance(::google::protobuf::int32 value); - - // optional int32 elapsed_time = 4; - inline void clear_elapsed_time(); - static const int kElapsedTimeFieldNumber = 4; - inline ::google::protobuf::int32 elapsed_time() const; - inline void set_elapsed_time(::google::protobuf::int32 value); - - // @@protoc_insertion_point(class_scope:examples.RouteSummary) - private: - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - bool _is_default_instance_; - ::google::protobuf::int32 point_count_; - ::google::protobuf::int32 feature_count_; - ::google::protobuf::int32 distance_; - ::google::protobuf::int32 elapsed_time_; - mutable int _cached_size_; - friend void protobuf_AddDesc_route_5fguide_2eproto(); - friend void protobuf_AssignDesc_route_5fguide_2eproto(); - friend void protobuf_ShutdownFile_route_5fguide_2eproto(); - - void InitAsDefaultInstance(); - static RouteSummary* default_instance_; -}; -// =================================================================== - - -// =================================================================== - -// Point - -// optional int32 latitude = 1; -inline void Point::clear_latitude() { - latitude_ = 0; -} -inline ::google::protobuf::int32 Point::latitude() const { - // @@protoc_insertion_point(field_get:examples.Point.latitude) - return latitude_; -} -inline void Point::set_latitude(::google::protobuf::int32 value) { - - latitude_ = value; - // @@protoc_insertion_point(field_set:examples.Point.latitude) -} - -// optional int32 longitude = 2; -inline void Point::clear_longitude() { - longitude_ = 0; -} -inline ::google::protobuf::int32 Point::longitude() const { - // @@protoc_insertion_point(field_get:examples.Point.longitude) - return longitude_; -} -inline void Point::set_longitude(::google::protobuf::int32 value) { - - longitude_ = value; - // @@protoc_insertion_point(field_set:examples.Point.longitude) -} - -// ------------------------------------------------------------------- - -// Rectangle - -// optional .examples.Point lo = 1; -inline bool Rectangle::has_lo() const { - return !_is_default_instance_ && lo_ != NULL; -} -inline void Rectangle::clear_lo() { - if (lo_ != NULL) delete lo_; - lo_ = NULL; -} -inline const ::examples::Point& Rectangle::lo() const { - // @@protoc_insertion_point(field_get:examples.Rectangle.lo) - return lo_ != NULL ? *lo_ : *default_instance_->lo_; -} -inline ::examples::Point* Rectangle::mutable_lo() { - - if (lo_ == NULL) { - lo_ = new ::examples::Point; - } - // @@protoc_insertion_point(field_mutable:examples.Rectangle.lo) - return lo_; -} -inline ::examples::Point* Rectangle::release_lo() { - - ::examples::Point* temp = lo_; - lo_ = NULL; - return temp; -} -inline void Rectangle::set_allocated_lo(::examples::Point* lo) { - delete lo_; - lo_ = lo; - if (lo) { - - } else { - - } - // @@protoc_insertion_point(field_set_allocated:examples.Rectangle.lo) -} - -// optional .examples.Point hi = 2; -inline bool Rectangle::has_hi() const { - return !_is_default_instance_ && hi_ != NULL; -} -inline void Rectangle::clear_hi() { - if (hi_ != NULL) delete hi_; - hi_ = NULL; -} -inline const ::examples::Point& Rectangle::hi() const { - // @@protoc_insertion_point(field_get:examples.Rectangle.hi) - return hi_ != NULL ? *hi_ : *default_instance_->hi_; -} -inline ::examples::Point* Rectangle::mutable_hi() { - - if (hi_ == NULL) { - hi_ = new ::examples::Point; - } - // @@protoc_insertion_point(field_mutable:examples.Rectangle.hi) - return hi_; -} -inline ::examples::Point* Rectangle::release_hi() { - - ::examples::Point* temp = hi_; - hi_ = NULL; - return temp; -} -inline void Rectangle::set_allocated_hi(::examples::Point* hi) { - delete hi_; - hi_ = hi; - if (hi) { - - } else { - - } - // @@protoc_insertion_point(field_set_allocated:examples.Rectangle.hi) -} - -// ------------------------------------------------------------------- - -// Feature - -// optional string name = 1; -inline void Feature::clear_name() { - name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline const ::std::string& Feature::name() const { - // @@protoc_insertion_point(field_get:examples.Feature.name) - return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline void Feature::set_name(const ::std::string& value) { - - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:examples.Feature.name) -} -inline void Feature::set_name(const char* value) { - - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:examples.Feature.name) -} -inline void Feature::set_name(const char* value, size_t size) { - - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:examples.Feature.name) -} -inline ::std::string* Feature::mutable_name() { - - // @@protoc_insertion_point(field_mutable:examples.Feature.name) - return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline ::std::string* Feature::release_name() { - - return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline void Feature::set_allocated_name(::std::string* name) { - if (name != NULL) { - - } else { - - } - name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); - // @@protoc_insertion_point(field_set_allocated:examples.Feature.name) -} - -// optional .examples.Point location = 2; -inline bool Feature::has_location() const { - return !_is_default_instance_ && location_ != NULL; -} -inline void Feature::clear_location() { - if (location_ != NULL) delete location_; - location_ = NULL; -} -inline const ::examples::Point& Feature::location() const { - // @@protoc_insertion_point(field_get:examples.Feature.location) - return location_ != NULL ? *location_ : *default_instance_->location_; -} -inline ::examples::Point* Feature::mutable_location() { - - if (location_ == NULL) { - location_ = new ::examples::Point; - } - // @@protoc_insertion_point(field_mutable:examples.Feature.location) - return location_; -} -inline ::examples::Point* Feature::release_location() { - - ::examples::Point* temp = location_; - location_ = NULL; - return temp; -} -inline void Feature::set_allocated_location(::examples::Point* location) { - delete location_; - location_ = location; - if (location) { - - } else { - - } - // @@protoc_insertion_point(field_set_allocated:examples.Feature.location) -} - -// ------------------------------------------------------------------- - -// RouteNote - -// optional .examples.Point location = 1; -inline bool RouteNote::has_location() const { - return !_is_default_instance_ && location_ != NULL; -} -inline void RouteNote::clear_location() { - if (location_ != NULL) delete location_; - location_ = NULL; -} -inline const ::examples::Point& RouteNote::location() const { - // @@protoc_insertion_point(field_get:examples.RouteNote.location) - return location_ != NULL ? *location_ : *default_instance_->location_; -} -inline ::examples::Point* RouteNote::mutable_location() { - - if (location_ == NULL) { - location_ = new ::examples::Point; - } - // @@protoc_insertion_point(field_mutable:examples.RouteNote.location) - return location_; -} -inline ::examples::Point* RouteNote::release_location() { - - ::examples::Point* temp = location_; - location_ = NULL; - return temp; -} -inline void RouteNote::set_allocated_location(::examples::Point* location) { - delete location_; - location_ = location; - if (location) { - - } else { - - } - // @@protoc_insertion_point(field_set_allocated:examples.RouteNote.location) -} - -// optional string message = 2; -inline void RouteNote::clear_message() { - message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline const ::std::string& RouteNote::message() const { - // @@protoc_insertion_point(field_get:examples.RouteNote.message) - return message_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline void RouteNote::set_message(const ::std::string& value) { - - message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:examples.RouteNote.message) -} -inline void RouteNote::set_message(const char* value) { - - message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:examples.RouteNote.message) -} -inline void RouteNote::set_message(const char* value, size_t size) { - - message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:examples.RouteNote.message) -} -inline ::std::string* RouteNote::mutable_message() { - - // @@protoc_insertion_point(field_mutable:examples.RouteNote.message) - return message_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline ::std::string* RouteNote::release_message() { - - return message_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline void RouteNote::set_allocated_message(::std::string* message) { - if (message != NULL) { - - } else { - - } - message_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), message); - // @@protoc_insertion_point(field_set_allocated:examples.RouteNote.message) -} - -// ------------------------------------------------------------------- - -// RouteSummary - -// optional int32 point_count = 1; -inline void RouteSummary::clear_point_count() { - point_count_ = 0; -} -inline ::google::protobuf::int32 RouteSummary::point_count() const { - // @@protoc_insertion_point(field_get:examples.RouteSummary.point_count) - return point_count_; -} -inline void RouteSummary::set_point_count(::google::protobuf::int32 value) { - - point_count_ = value; - // @@protoc_insertion_point(field_set:examples.RouteSummary.point_count) -} - -// optional int32 feature_count = 2; -inline void RouteSummary::clear_feature_count() { - feature_count_ = 0; -} -inline ::google::protobuf::int32 RouteSummary::feature_count() const { - // @@protoc_insertion_point(field_get:examples.RouteSummary.feature_count) - return feature_count_; -} -inline void RouteSummary::set_feature_count(::google::protobuf::int32 value) { - - feature_count_ = value; - // @@protoc_insertion_point(field_set:examples.RouteSummary.feature_count) -} - -// optional int32 distance = 3; -inline void RouteSummary::clear_distance() { - distance_ = 0; -} -inline ::google::protobuf::int32 RouteSummary::distance() const { - // @@protoc_insertion_point(field_get:examples.RouteSummary.distance) - return distance_; -} -inline void RouteSummary::set_distance(::google::protobuf::int32 value) { - - distance_ = value; - // @@protoc_insertion_point(field_set:examples.RouteSummary.distance) -} - -// optional int32 elapsed_time = 4; -inline void RouteSummary::clear_elapsed_time() { - elapsed_time_ = 0; -} -inline ::google::protobuf::int32 RouteSummary::elapsed_time() const { - // @@protoc_insertion_point(field_get:examples.RouteSummary.elapsed_time) - return elapsed_time_; -} -inline void RouteSummary::set_elapsed_time(::google::protobuf::int32 value) { - - elapsed_time_ = value; - // @@protoc_insertion_point(field_set:examples.RouteSummary.elapsed_time) -} - - -class RouteGuide final { - public: - class Stub final : public ::grpc::InternalStub { - public: - ::grpc::Status GetFeature(::grpc::ClientContext* context, const ::examples::Point& request, ::examples::Feature* response); - ::grpc::ClientAsyncResponseReader< ::examples::Feature>* GetFeature(::grpc::ClientContext* context, const ::examples::Point& request, ::grpc::CompletionQueue* cq, void* tag); - ::grpc::ClientReader< ::examples::Feature>* ListFeatures(::grpc::ClientContext* context, const ::examples::Rectangle& request); - ::grpc::ClientAsyncReader< ::examples::Feature>* ListFeatures(::grpc::ClientContext* context, const ::examples::Rectangle& request, ::grpc::CompletionQueue* cq, void* tag); - ::grpc::ClientWriter< ::examples::Point>* RecordRoute(::grpc::ClientContext* context, ::examples::RouteSummary* response); - ::grpc::ClientAsyncWriter< ::examples::Point>* RecordRoute(::grpc::ClientContext* context, ::examples::RouteSummary* response, ::grpc::CompletionQueue* cq, void* tag); - ::grpc::ClientReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* RouteChat(::grpc::ClientContext* context); - ::grpc::ClientAsyncReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* RouteChat(::grpc::ClientContext* context, ::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 GetFeature(::grpc::ServerContext* context, const ::examples::Point* request, ::examples::Feature* response); - virtual ::grpc::Status ListFeatures(::grpc::ServerContext* context, const ::examples::Rectangle* request, ::grpc::ServerWriter< ::examples::Feature>* writer); - virtual ::grpc::Status RecordRoute(::grpc::ServerContext* context, ::grpc::ServerReader< ::examples::Point>* reader, ::examples::RouteSummary* response); - virtual ::grpc::Status RouteChat(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* stream); - ::grpc::RpcService* service() override final; - private: - ::grpc::RpcService* service_; - }; - class AsyncService final : public ::grpc::AsynchronousService { - public: - explicit AsyncService(::grpc::CompletionQueue* cq); - ~AsyncService() {}; - void RequestGetFeature(::grpc::ServerContext* context, ::examples::Point* request, ::grpc::ServerAsyncResponseWriter< ::examples::Feature>* response, ::grpc::CompletionQueue* cq, void *tag); - void RequestListFeatures(::grpc::ServerContext* context, ::examples::Rectangle* request, ::grpc::ServerAsyncWriter< ::examples::Feature>* writer, ::grpc::CompletionQueue* cq, void *tag); - void RequestRecordRoute(::grpc::ServerContext* context, ::grpc::ServerAsyncReader< ::examples::RouteSummary, ::examples::Point>* reader, ::grpc::CompletionQueue* cq, void *tag); - void RequestRouteChat(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::examples::RouteNote, ::examples::RouteNote>* stream, ::grpc::CompletionQueue* cq, void *tag); - }; -}; - -// @@protoc_insertion_point(namespace_scope) - -} // namespace examples - -#ifndef SWIG -namespace google { -namespace protobuf { - - -} // namespace protobuf -} // namespace google -#endif // SWIG - -// @@protoc_insertion_point(global_scope) - -#endif // PROTOBUF_route_5fguide_2eproto__INCLUDED diff --git a/cpp/route_guide/route_guide_client.cc b/cpp/route_guide/route_guide_client.cc index 4a51f5eb38..65ca3af7d4 100644 --- a/cpp/route_guide/route_guide_client.cc +++ b/cpp/route_guide/route_guide_client.cc @@ -41,51 +41,110 @@ #include #include #include -#include "helloworld.pb.h" +#include +#include "route_guide.pb.h" using grpc::ChannelArguments; using grpc::ChannelInterface; using grpc::ClientContext; +using grpc::ClientReader; +using grpc::ClientReaderWriter; +using grpc::ClientWriter; using grpc::Status; -using helloworld::HelloRequest; -using helloworld::HelloReply; -using helloworld::Greeter; +using examples::Point; +using examples::Feature; +using examples::Rectangle; +using examples::RouteSummary; +using examples::RouteNote; +using examples::RouteGuide; -class GreeterClient { +class RouteGuideClient { public: - GreeterClient(std::shared_ptr channel) - : stub_(Greeter::NewStub(channel)) {} + RouteGuideClient(std::shared_ptr channel) + : stub_(RouteGuide::NewStub(channel)) {} - std::string SayHello(const std::string& user) { - HelloRequest request; - request.set_name(user); - HelloReply reply; + void GetFeature() { + Point point; + Feature feature; ClientContext context; - Status status = stub_->sayHello(&context, request, &reply); + Status status = stub_->GetFeature(&context, point, &feature); if (status.IsOk()) { - return reply.message(); + std::cout << "GetFeature rpc succeeded." << std::endl; } else { - return "Rpc failed"; + std::cout << "GetFeature rpc failed." << std::endl; + } + } + + void ListFeatures() { + Rectangle rect; + Feature feature; + ClientContext context; + + std::unique_ptr > reader( + stub_->ListFeatures(&context, rect)); + while (reader->Read(&feature)) { + std::cout << "Received feature" << std::endl; + } + Status status = reader->Finish(); + if (status.IsOk()) { + std::cout << "ListFeatures rpc succeeded." << std::endl; + } else { + std::cout << "ListFeatures rpc failed." << std::endl; + } + } + + void RecordRoute() { + Point point; + RouteSummary summary; + ClientContext context; + + std::unique_ptr > writer( + stub_->RecordRoute(&context, &summary)); + writer->WritesDone(); + Status status = writer->Finish(); + if (status.IsOk()) { + std::cout << "RecordRoute rpc succeeded." << std::endl; + } else { + std::cout << "RecordRoute rpc failed." << std::endl; + } + } + + void RouteChat() { + RouteNote server_note; + ClientContext context; + + std::unique_ptr > stream( + stub_->RouteChat(&context)); + stream->WritesDone(); + while (stream->Read(&server_note)) { + } + Status status = stream->Finish(); + if (status.IsOk()) { + std::cout << "RouteChat rpc succeeded." << std::endl; + } else { + std::cout << "RouteChat rpc failed." << std::endl; } } void Shutdown() { stub_.reset(); } private: - std::unique_ptr stub_; + std::unique_ptr stub_; }; int main(int argc, char** argv) { grpc_init(); - GreeterClient greeter( + RouteGuideClient guide( grpc::CreateChannel("localhost:50051", ChannelArguments())); - std::string user("world"); - std::string reply = greeter.SayHello(user); - std::cout << "Greeter received: " << reply << std::endl; - greeter.Shutdown(); + guide.GetFeature(); + guide.ListFeatures(); + guide.RecordRoute(); + guide.RouteChat(); + + guide.Shutdown(); grpc_shutdown(); } diff --git a/cpp/route_guide/route_guide_server.cc b/cpp/route_guide/route_guide_server.cc index 3a2ab60e89..718afbae2a 100644 --- a/cpp/route_guide/route_guide_server.cc +++ b/cpp/route_guide/route_guide_server.cc @@ -41,28 +41,45 @@ #include #include #include -#include "helloworld.pb.h" +#include +#include "route_guide.pb.h" using grpc::Server; using grpc::ServerBuilder; using grpc::ServerContext; +using grpc::ServerReader; +using grpc::ServerReaderWriter; +using grpc::ServerWriter; using grpc::Status; -using helloworld::HelloRequest; -using helloworld::HelloReply; -using helloworld::Greeter; +using examples::Point; +using examples::Feature; +using examples::Rectangle; +using examples::RouteSummary; +using examples::RouteNote; +using examples::RouteGuide; -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()); +class RouteGuideImpl final : public RouteGuide::Service { + Status GetFeature(ServerContext* context, const Point* point, + Feature* feature) override { + return Status::OK; + } + Status ListFeatures(ServerContext* context, const Rectangle* rectangle, + ServerWriter* writer) override { + return Status::OK; + } + Status RecordRoute(ServerContext* context, ServerReader* reader, + RouteSummary* summary) override { + return Status::OK; + } + Status RouteChat(ServerContext* context, + ServerReaderWriter* stream) override { return Status::OK; } }; void RunServer() { std::string server_address("0.0.0.0:50051"); - GreeterServiceImpl service; + RouteGuideImpl service; ServerBuilder builder; builder.AddPort(server_address); -- cgit v1.2.3 From 2f22e84f725b2aa90c203410dff0b75c8ec25599 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 20 Feb 2015 16:39:32 -0800 Subject: Created helloworld tutorial outline --- cpp/helloworld/README.md | 95 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 cpp/helloworld/README.md diff --git a/cpp/helloworld/README.md b/cpp/helloworld/README.md new file mode 100644 index 0000000000..952325b446 --- /dev/null +++ b/cpp/helloworld/README.md @@ -0,0 +1,95 @@ +# gRPC C++ Hello World Tutorial + +### Install gRPC +Make sure you have installed gRPC on your system. Follow the instructions here: +[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). + +### Get the tutorial source code + +The example code for this and our other examples lives in the `grpc-common` +GitHub repository. Clone this repository to your local machine by running the +following command: + + +```sh +$ git clone https://github.com/google/grpc-common.git +``` + +Change your current directory to grpc-common/cpp/helloworld + +```sh +$ cd grpc-common/cpp/helloworld/ +``` + +### Defining a service + +The first step in creating our example is to define a *service*: an RPC +service specifies the methods that can be called remotely with their parameters +and return types. As you saw in the +[overview](#protocolbuffers) above, gRPC does this using [protocol +buffers](https://developers.google.com/protocol-buffers/docs/overview). We +use the protocol buffers interface definition language (IDL) to define our +service methods, and define the parameters and return +types as protocol buffer message types. Both the client and the +server use interface code generated from the service definition. + +Here's our example service definition, defined using protocol buffers IDL in +[helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). The `Greeting` +service has one method, `hello`, that lets the server receive a single +`HelloRequest` +message from the remote client containing the user's name, then send back +a greeting in a single `HelloReply`. This is the simplest type of RPC you +can specify in gRPC - we'll look at some other types later in this document. + +``` +syntax = "proto3"; + +option java_package = "ex.grpc"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} + +``` + + +### Generating gRPC code + +Once we've defined our service, we use the protocol buffer compiler +`protoc` to generate the special client and server code we need to create +our application. The generated code contains both stub code for clients to +use and an abstract interface for servers to implement, both with the method +defined in our `Greeting` service. + +To generate the client and server side interfaces: + +```sh +$ make helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + +```sh +$protoc -I ../../protos/ --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin helloworld.proto +``` + +### Writing a client + +This is an incomplete tutorial. For now the reader should refer to [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). + +### Writing a server + +This is an incomplete tutorial. For now the reader should refer to [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). -- cgit v1.2.3 From ca8c87738c5eb2c40173506131997efb03a30cde Mon Sep 17 00:00:00 2001 From: David Symonds Date: Sat, 21 Feb 2015 12:11:55 +1100 Subject: Tidy up README.md. Simply Go version requirement. Use `go get` instead of `go install`. Don't mention $GOBIN, which is irrelevant for most people. Fix a couple of typos. --- go/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/go/README.md b/go/README.md index d464b45d36..5d837f969d 100644 --- a/go/README.md +++ b/go/README.md @@ -4,7 +4,7 @@ gRPC in 3 minutes (Go) PREREQUISITES ------------- -- This requires Go 1.4.x +- This requires Go 1.4 - Requires that [GOPATH is set](https://golang.org/doc/code.html#GOPATH) ```sh $ go help gopath @@ -42,10 +42,10 @@ OPTIONAL - Rebuilding the generated code - This is will change once proto3 is officially released 2 Install the protoc Go plugin. ```sh -$ go install -a github.com/golang/protobuf/protoc-gen-go -$ # ensure the PATH contains $GOPATH/bin or $GOBIN -$ export PATH=PATH: +$ go get -a github.com/golang/protobuf/protoc-gen-go +$ # ensure the PATH contains $GOPATH/bin +$ export PATH=PATH:$GOPATH/bin $ -$ # from ths dir; invoke protoc +$ # from this dir; invoke protoc $ protoc -I ../protos ../protos/helloworld.proto --go_out=plugins=grpc:. ``` -- cgit v1.2.3 From 8169a6876245770f453e2cfe2517be91315bcf07 Mon Sep 17 00:00:00 2001 From: David Symonds Date: Sat, 21 Feb 2015 12:23:36 +1100 Subject: Update to match standard Go style. Remove completely unused dial options, and reorder a bit of code to match what real code would look like. --- go/greeter_client/main.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/go/greeter_client/main.go b/go/greeter_client/main.go index abe33c0e2a..3398040d7e 100644 --- a/go/greeter_client/main.go +++ b/go/greeter_client/main.go @@ -49,19 +49,18 @@ const ( func main() { // Set up a connection to the server. - var opts []grpc.DialOption - conn, err := grpc.Dial(address, opts...) + conn, err := grpc.Dial(address) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() + c := pb.NewGreeterClient(conn) // Contact the server and print out its response. name := defaultName if len(os.Args) > 1 { name = os.Args[1] } - c := pb.NewGreeterClient(conn) r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name}) if err != nil { log.Fatalf("could not greet: %v", err) -- cgit v1.2.3 From 051969c36a39221578a5346c99130802a56b5da0 Mon Sep 17 00:00:00 2001 From: David Symonds Date: Sat, 21 Feb 2015 12:27:23 +1100 Subject: More README.md improvements. Suggest the standard `go get` for downloading the demo. Remove instruction to set GOPATH during install flow, since the prerequisites section already does that. --- go/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/go/README.md b/go/README.md index 5d837f969d..7b90157043 100644 --- a/go/README.md +++ b/go/README.md @@ -16,9 +16,8 @@ INSTALL ------- ```sh -$ export GOPATH= -$ go install -u github.com/grpc-common/go/greeter_client -$ go install -u github.com/grpc-common/go/greeter_server +$ go get -u github.com/grpc-common/go/greeter_client +$ go get -u github.com/grpc-common/go/greeter_server ``` TRY IT! -- cgit v1.2.3 From 6c359b36cd9f940d913d428bbaeb38a07806c4ce Mon Sep 17 00:00:00 2001 From: Qi Zhao Date: Fri, 20 Feb 2015 17:33:15 -0800 Subject: make the format correct. --- go/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/go/README.md b/go/README.md index 7b90157043..2cab9092ae 100644 --- a/go/README.md +++ b/go/README.md @@ -39,6 +39,7 @@ OPTIONAL - Rebuilding the generated code 1 First [install protoc](https://github.com/google/protobuf/blob/master/INSTALL.txt) - For now, this needs to be installed from source - This is will change once proto3 is officially released + 2 Install the protoc Go plugin. ```sh $ go get -a github.com/golang/protobuf/protoc-gen-go -- cgit v1.2.3 From d314cd2e884dc3730c879e7a2b7e1c84538cdeaa Mon Sep 17 00:00:00 2001 From: Qi Zhao Date: Fri, 20 Feb 2015 17:54:59 -0800 Subject: Improve README.md --- go/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/go/README.md b/go/README.md index 2cab9092ae..bf5d6c8cf4 100644 --- a/go/README.md +++ b/go/README.md @@ -8,8 +8,8 @@ PREREQUISITES - Requires that [GOPATH is set](https://golang.org/doc/code.html#GOPATH) ```sh $ go help gopath -$ # ensure the PATH contains $GOPATH/bin or $GOBIN -$ export PATH=PATH: +$ # ensure the PATH contains $GOPATH/bin +$ export PATH=$PATH:$GOPATH/bin ``` INSTALL @@ -43,8 +43,6 @@ OPTIONAL - Rebuilding the generated code 2 Install the protoc Go plugin. ```sh $ go get -a github.com/golang/protobuf/protoc-gen-go -$ # ensure the PATH contains $GOPATH/bin -$ export PATH=PATH:$GOPATH/bin $ $ # from this dir; invoke protoc $ protoc -I ../protos ../protos/helloworld.proto --go_out=plugins=grpc:. -- cgit v1.2.3 From 29bfc13ddae6c4d143519e01d5cc970b75168869 Mon Sep 17 00:00:00 2001 From: Jayant Kolhe Date: Fri, 20 Feb 2015 17:55:23 -0800 Subject: Update README.md Fix broken link --- cpp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/README.md b/cpp/README.md index a95bd3c8f0..84fa34e705 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -3,6 +3,6 @@ First you need to install gRPC on your system. Follow the instructions here: [https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). -After installing, you can proceed to the [gRPC C++ Hello World tutorial](https://github.com/grpc/grpc-common/cpp/helloworld). +After installing, you can proceed to the [gRPC C++ Hello World tutorial](helloworld/README.md). A more detailed tutorial is coming soon. -- cgit v1.2.3 From eb158ffb584e5067460e812a058b46ea517a1de2 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Sat, 21 Feb 2015 06:29:53 -0800 Subject: Update README.md --- ruby/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ruby/README.md b/ruby/README.md index 668baf3eb7..1fc19a4f24 100644 --- a/ruby/README.md +++ b/ruby/README.md @@ -1,26 +1,26 @@ -gRPC Ruby Helloworld -==================== +gRPC in 3 minutes (Ruby) +======================== -INSTALLATION PREREQUISITES --------------------------- +PREREQUISITES +------------- -This requires Ruby 2.x, as the gRPC API surface uses keyword args. +This requires Ruby 2.1, as the gRPC API surface uses keyword args. INSTALL ------- - Clone this repository. - Follow the instructions in [INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL) to install the gRPC C core. -- *Temporary* Install gRPC for Ruby from source on your local machine and update path: to refer to it [Gemfile]. - - this is needed until the gRPC ruby gem is published +- *Temporary* Install the full gRPC distribution from source on your local machine and update path: in [Gemfile] to refer src/ruby within it. + - this is necessary until the gRPC ruby gem is published - Use bundler to install ```sh $ # from this directory $ gem install bundler && bundle install ``` -USAGE ------ +Try it! +------- - Run the server ```sh -- cgit v1.2.3 From 6b3df7da6a468313c2220315d1d141d9fe9353b0 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Mon, 23 Feb 2015 00:54:35 -0800 Subject: client impl except db_parser --- cpp/route_guide/route_guide_client.cc | 169 ++++++++++++++++++++++++++++++---- 1 file changed, 150 insertions(+), 19 deletions(-) diff --git a/cpp/route_guide/route_guide_client.cc b/cpp/route_guide/route_guide_client.cc index 65ca3af7d4..6dbe6b8730 100644 --- a/cpp/route_guide/route_guide_client.cc +++ b/cpp/route_guide/route_guide_client.cc @@ -31,9 +31,14 @@ * */ +#include +#include #include #include +#include +#include #include +#include #include #include @@ -58,6 +63,33 @@ using examples::RouteSummary; using examples::RouteNote; using examples::RouteGuide; +Point MakePoint(long latitude, long longitude) { + Point p; + p.set_latitude(latitude); + p.set_longitude(longitude); + return p; +} + +Feature MakeFeature(const std::string& name, + long latitude, long longitude) { + Feature f; + f.set_name(name); + f.mutable_location()->CopyFrom(MakePoint(latitude, longitude)); + return f; +} + +RouteNote MakeRouteNote(const std::string& message, + long latitude, long longitude) { + RouteNote n; + n.set_message(message); + n.mutable_location()->CopyFrom(MakePoint(latitude, longitude)); + return n; +} + +bool ParseDb(stringstream stream, std::vector* feature_list) { + // TODO +} + class RouteGuideClient { public: RouteGuideClient(std::shared_ptr channel) @@ -66,14 +98,10 @@ class RouteGuideClient { void GetFeature() { Point point; Feature feature; - ClientContext context; - - Status status = stub_->GetFeature(&context, point, &feature); - if (status.IsOk()) { - std::cout << "GetFeature rpc succeeded." << std::endl; - } else { - std::cout << "GetFeature rpc failed." << std::endl; - } + point = MakePoint(409146138, -746188906); + GetOneFeature(point, &feature); + point = MakePoint(0, 0); + GetOneFeature(point, &feature); } void ListFeatures() { @@ -81,10 +109,20 @@ class RouteGuideClient { Feature feature; ClientContext context; + rect.mutable_lo()->set_latitude(400000000); + rect.mutable_lo()->set_longitude(-750000000); + rect.mutable_hi()->set_latitude(420000000); + rect.mutable_hi()->set_longitude(-730000000); + std::cout << "Looking for features between 40, -75 and 42, -73" + << std::endl; + std::unique_ptr > reader( stub_->ListFeatures(&context, rect)); while (reader->Read(&feature)) { - std::cout << "Received feature" << std::endl; + std::cout << "Found feature called " + << feature.name() << " at " + << feature.location().latitude()/kCoordFactor_ << ", " + << feature.location().latitude()/kCoordFactor_ << std::endl; } Status status = reader->Finish(); if (status.IsOk()) { @@ -96,41 +134,120 @@ class RouteGuideClient { void RecordRoute() { Point point; - RouteSummary summary; + RouteSummary stats; ClientContext context; + const int kPoints = 10; + std::default_random_engine generator; + std::uniform_int_distribution feature_distribution( + 0, feature_list_.size() - 1); + std::uniform_int_distribution delay_distribution( + 500, 1500); std::unique_ptr > writer( - stub_->RecordRoute(&context, &summary)); + stub_->RecordRoute(&context, &stats)); + for (int i = 0; i < kPoints; i++) { + const Feature& f = feature_list_[feature_distribution(generator)]; + std::cout << "Visiting point " + << f.location().latitude()/kCoordFactor_ << ", " + << f.location().longitude()/kCoordFactor_ << std::endl; + if (!writer->Write(f.location())) { + // Broken stream. + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds( + delay_distribution(generator))); + } writer->WritesDone(); Status status = writer->Finish(); if (status.IsOk()) { - std::cout << "RecordRoute rpc succeeded." << std::endl; + std::cout << "Finished trip with " << stats.point_count() << " points\n" + << "Passed " << stats.feature_count() << " features\n" + << "Travelled " << stats.distance() << " meters\n" + << "It took " << stats.elapsed_time() << " seconds" + << std::endl; } else { std::cout << "RecordRoute rpc failed." << std::endl; } } void RouteChat() { - RouteNote server_note; ClientContext context; - std::unique_ptr > stream( - stub_->RouteChat(&context)); - stream->WritesDone(); + ClientReaderWriter* stream = + stub_->RouteChat(&context); + + std::thread writer([stream]() { + std::vector notes{ + MakeRouteNote("First message", 0, 0), + MakeRouteNote("Second message", 0, 1), + MakeRouteNote("Third message", 1, 0), + MakeRouteNote("Fourth message", 0, 0)}; + for (const RouteNote& note : notes) { + std::cout << "Sending message " << note.message() + << " at " << note.location().latitude() << ", " + << note.location().longitude() << std::endl; + stream->Write(note); + } + stream->WritesDone(); + }); + + RouteNote server_note; while (stream->Read(&server_note)) { + std::cout << "Got message " << server_note.message() + << " at " << server_note.location().latitude() << ", " + << server_note.location().longitude() << std::endl; } + writer.join(); Status status = stream->Finish(); - if (status.IsOk()) { - std::cout << "RouteChat rpc succeeded." << std::endl; - } else { + if (!status.IsOk()) { std::cout << "RouteChat rpc failed." << std::endl; } + delete stream; } void Shutdown() { stub_.reset(); } + void FillFeatureList(const std::string& db_path) { + if (db_path.empty()) { + return; + } + std::ifstream db_file(db_path); + if (!db_file.is_open()) { + std::cout << "Failed to open " << db_path << std::endl; + } + std::stringstream db; + db << db_file.rdbuf(); + ParseDb(db, &feature_list_); + } + private: + + bool GetOneFeature(const Point& point, Feature* feature) { + ClientContext context; + Status status = stub_->GetFeature(&context, point, feature); + if (!status.IsOk()) { + std::cout << "GetFeature rpc failed." << std::endl; + return false; + } + if (!feature->has_location()) { + std::cout << "Server returns incomplete feature." << std::endl; + return false; + } + if (feature->name().empty()) { + std::cout << "Found no feature at " + << feature->location().latitude()/kCoordFactor_ << ", " + << feature->location().longitude()/kCoordFactor_ << std::endl; + } else { + std::cout << "Found feature called " << feature->name() << " at " + << feature->location().latitude()/kCoordFactor_ << ", " + << feature->location().longitude()/kCoordFactor_ << std::endl; + } + return true; + } + + const float kCoordFactor_ = 10000000.0; std::unique_ptr stub_; + std::vector feature_list_; }; int main(int argc, char** argv) { @@ -138,6 +255,20 @@ int main(int argc, char** argv) { RouteGuideClient guide( grpc::CreateChannel("localhost:50051", ChannelArguments())); + std::string db_path; + std::string arg_str("--db_path"); + if (argc > 1) { + std::string argv_1 = argv[1]; + size_t start_position = argv_1.find(arg_str); + if (start_position != std::string::npos) { + start_position += arg_str.size(); + if (argv_1[start_position] == ' ' || + argv_1[start_position] == '=') { + db_path = argv_1.substr(start_position + 1); + } + } + } + guide.FillFeatureList(db_path); guide.GetFeature(); guide.ListFeatures(); -- cgit v1.2.3 From 9b3b2a23c15e39b1d8bd8f3b2416ff5ea59f3d77 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 23 Feb 2015 13:36:27 +0000 Subject: Added Go client example section, more tidying up of general info including protobuf. --- README.md | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 3a2fb8d7d1..cb30f7d3c3 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,12 @@ platform-neutral remote procedure call (RPC) system developed at Google. This document introduces you to gRPC with a quick overview and a simple Hello World example. More documentation is coming soon! +## What's in this repository? + +The `grpc-common` repository contains documentation, resources, and examples for all gRPC users + +You can find out about the gRPC source code repositories in [`grpc`](https://github.com/grpc/grpc). + ## What is gRPC? In gRPC a *client* application can directly call @@ -69,23 +75,18 @@ a single Hello World method. - Create a Java server that implements this interface. - Create a Java client that accesses the Java server. -- Create a [probably need a different language now] client that accesses +- Create a Go client that accesses the same Java server. -- Update the service with more advanced features like RPC streaming. +- Update the service with a streaming RPC. The complete code for the example is available in the `grpc-common` GitHub -repository. You can -work along with the example and hack on the code in the comfort of your own -computer, giving you hands-on practice of really writing -gRPC code. We use the Git versioning system for source code management: +repository. We use the Git versioning system for source code management: however, you don't need to know anything about Git to follow along other than how to install and run a few git commands. This is an introductory example rather than a comprehensive tutorial, so don't worry if you're not a Go or -Java developer - the concepts introduced here are similar for all languages, -and complete tutorials and reference documentation for all gRPC -languages are coming soon. +Java developer - the concepts are similar for all languages, and you can find more implementations of our Hello World example in other languages in the language-specific folders in this repository. Complete tutorials and reference documentation for all gRPC languages are coming soon. ### Setup @@ -170,7 +171,7 @@ types as protocol buffer message types. Both the client and the server use interface code generated from the service definition. Here's our example service definition, defined using protocol buffers IDL in -[helloworld.proto](java/src/main/proto/helloworld.proto). The `Greeting` +[helloworld.proto](protos/helloworld.proto). The `Greeting` service has one method, `hello`, that lets the server receive a single `HelloRequest` message from the remote client containing the user's name, then send back @@ -223,13 +224,7 @@ classes. By default `protoc` just generates code for reading and writing protocol buffers, so you need to use plugins to add additional features to generated code. As we're creating Java code, we use the gRPC Java plugin. -To build the plugin: - -```sh -$ pushd external/grpc_java -$ make java_plugin -$ popd -``` +To build the plugin, follow the instructions in the relevant repo: for Java, the instructions are in [`grpc-java1](https://github.com/grpc/grpc-java). To use it to generate the code: @@ -440,6 +435,7 @@ and in another terminal window confirm that it receives a message. $ ./run_greeter_client.sh ``` + ### Adding another client -- cgit v1.2.3 From 683232652ecb6cb86cea2e743e69f009bfe39de9 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 23 Feb 2015 13:37:41 +0000 Subject: More tidying up --- README.md | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index cb30f7d3c3..edb2b9daf8 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,14 @@ Hello World example. More documentation is coming soon! ## What's in this repository? -The `grpc-common` repository contains documentation, resources, and examples for all gRPC users +The `grpc-common` repository contains documentation, resources, and examples +for all gRPC users. You can find examples and instructions specific to your +favourite language in the relevant subdirectory. + +You can find out about the gRPC source code repositories in +[`grpc`](https://github.com/grpc/grpc). Each repository provides instructions +for building the appropriate libraries for your language. -You can find out about the gRPC source code repositories in [`grpc`](https://github.com/grpc/grpc). ## What is gRPC? @@ -51,7 +56,11 @@ While protocol buffers have been available for open source users for some time, our examples use a new flavour of protocol buffers called proto3, which has a slightly simplified syntax, some useful new features, and supports lots more languages. This is currently available as an alpha release in -[languages] from [wherever it's going], with more languages in development. +Java, C++ from [the protocol buffers Github +repo](https://github.com/google/protobuf/releases), as well as a Go language +generator [wherever that is](), with more languages in development. Full +documentation for proto3 is currently in development but you can see +the major differences from the current default version in the [release notes](https://github.com/google/protobuf/releases). In general, we recommend that you use proto3 with gRPC as it lets you use the full range of gRPC-supported languages, as well as avoiding compatibility @@ -86,7 +95,10 @@ than how to install and run a few git commands. This is an introductory example rather than a comprehensive tutorial, so don't worry if you're not a Go or -Java developer - the concepts are similar for all languages, and you can find more implementations of our Hello World example in other languages in the language-specific folders in this repository. Complete tutorials and reference documentation for all gRPC languages are coming soon. +Java developer - the concepts are similar for all languages, and you can +find more implementations of our Hello World example in other languages in +the language-specific folders in this repository. Complete tutorials and +reference documentation for all gRPC languages are coming soon. ### Setup @@ -224,7 +236,8 @@ classes. By default `protoc` just generates code for reading and writing protocol buffers, so you need to use plugins to add additional features to generated code. As we're creating Java code, we use the gRPC Java plugin. -To build the plugin, follow the instructions in the relevant repo: for Java, the instructions are in [`grpc-java1](https://github.com/grpc/grpc-java). +To build the plugin, follow the instructions in the relevant repo: for Java, +the instructions are in [`grpc-java1](https://github.com/grpc/grpc-java). To use it to generate the code: @@ -236,6 +249,8 @@ $ protoc -I . helloworld.proto --java_out=src/main/java ``` +[need to update this once I get the plugin built] + This generates the following classes, which contain all the generated code we need to create our example: @@ -435,12 +450,60 @@ and in another terminal window confirm that it receives a message. $ ./run_greeter_client.sh ``` - ### Adding another client - Finally, let's look at one of gRPC's most useful features - interoperability -between code in different languages. So far, we've just generated Java code -from our `Greeter` service definition.... +between code in different languages. So far, we've just looked at Java code +generated from and implementing our `Greeter` service definition. However, +as you'll see if you look at the language-specific subdirectories +in this repository, we've also generated and implemented `Greeter` +in some of gRPC's other supported languages. Each service +and client uses interface code generated from [exactly the same +.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto) +that we used for the Java example. + +So, for example, if we visit the [`go` +directory](https://github.com/grpc/grpc-common/tree/master/go) and look at the +[`greeter_client`](https://github.com/grpc/grpc-common/blob/master/go/greeter_client/main.go), +we can see that like the Java client, it connects to a `Greeter` service +at `localhost:50051` and uses a stub to call the `SayHello` method with a +`HelloRequest`: + +```go +const ( + address = "localhost:50051" + defaultName = "world" +) + +func main() { + // Set up a connection to the server. + conn, err := grpc.Dial(address) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + defer conn.Close() + c := pb.NewGreeterClient(conn) + + // Contact the server and print out its response. + name := defaultName + if len(os.Args) > 1 { + name = os.Args[1] + } + r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: + name}) + if err != nil { + log.Fatalf("could not greet: %v", err) + } + log.Printf("Greeting: %s", r.Message) +} +``` + + +If we run the Java server from earlier in another terminal window, we can +run the Go client and connect to it just like the Java client, even though +it's written in a different language. + +``` +$ greeter_client +``` -###TODO: Section on Go client for same server -- cgit v1.2.3 From 5279a5f7ae94077948d74127a46af5201770075e Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 23 Feb 2015 13:39:16 +0000 Subject: Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index edb2b9daf8..7f695cab90 100644 --- a/README.md +++ b/README.md @@ -237,7 +237,7 @@ protocol buffers, so you need to use plugins to add additional features to generated code. As we're creating Java code, we use the gRPC Java plugin. To build the plugin, follow the instructions in the relevant repo: for Java, -the instructions are in [`grpc-java1](https://github.com/grpc/grpc-java). +the instructions are in [`grpc-java`](https://github.com/grpc/grpc-java). To use it to generate the code: -- cgit v1.2.3 From 54e0c6d4121e986b3b1acd35cbc74cba3bde4a72 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 23 Feb 2015 16:00:38 +0000 Subject: Starting the C++ Route Guide tutorial... --- cpp/cpptutorial.md | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 cpp/cpptutorial.md diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md new file mode 100644 index 0000000000..d6c38f4f9b --- /dev/null +++ b/cpp/cpptutorial.md @@ -0,0 +1,108 @@ +#gRPC Basics: C++ + +This tutorial provides a basic C++ programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate server and client code using the protocol buffer compiler. +- Use the C++ gRPC API to write a simple client and server for your service. + +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. + +This isn't a comprehensive guide to using gRPC in C++: more reference documentation is coming soon. + +## Why use gRPC? + +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +With gRPC we can define our service once in a .proto file and implement clients and servers in , which in turn - all the complexity of communication between different languages and environments is handled for you by gRPC. gRPC also + +We also get all the advantages of working with protocol buffers + +[possibly insert more advantages here] + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/cpp/route_guide](https://github.com/grpc/grpc-common/cpp/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/google/grpc-common.git +``` + +Then change your current directory to `grpc-common/cpp/route_guide`: +```shell +$ cd grpc-common/cpp/route_guide +``` + +Although we've provided the complete example so you don't need to generate the gRPC code yourself, if you want to try generating your own server and client interface code you can follow the setup instructions for the C++ gRPC libraries in [grpc/grpc/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). + + +## Defining the service + +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +``` +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +``` + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. +``` + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} +``` + +- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. +``` + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. +``` + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +``` + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + + +## Generating client and server code + +Now we need to ... + + +## Creating the server + +First let's look at implementing our R + +There are two parts to making our `RouteGuide` service work: +- + + +## Creating the client + + + + + + -- cgit v1.2.3 From 450d112c02270149222578ec2238cca6516be285 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 23 Feb 2015 16:05:25 +0000 Subject: Small fixes in snippets. --- cpp/cpptutorial.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index d6c38f4f9b..6f3f330c2c 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -55,7 +55,7 @@ Then you define `rpc` methods inside your service definition, specifying their r rpc GetFeature(Point) returns (Feature) {} ``` -- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. +- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. ``` // Obtains the Features available within the given Rectangle. Results are // streamed rather than returned at once (e.g. in a response message with a @@ -64,25 +64,30 @@ Then you define `rpc` methods inside your service definition, specifying their r rpc ListFeatures(Rectangle) returns (stream Feature) {} ``` -- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. +- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. ``` // Accepts a stream of Points on a route being traversed, returning a // RouteSummary when traversal is completed. rpc RecordRoute(stream Point) returns (RouteSummary) {} ``` -- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. +- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. ``` - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} ``` Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: ``` - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} +// Points are represented as latitude-longitude pairs in the E7 representation +// (degrees multiplied by 10**7 and rounded to the nearest integer). +// Latitudes should be in the range +/- 90 degrees and longitude should be in +// the range +/- 180 degrees (inclusive). +message Point { + int32 latitude = 1; + int32 longitude = 2; +} ``` -- cgit v1.2.3 From 7a21966ee7e0c4487887d34dda969e8b3457edf9 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 23 Feb 2015 16:42:21 +0000 Subject: More tutorial.. --- cpp/cpptutorial.md | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index 6f3f330c2c..ade134c86b 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -14,9 +14,7 @@ This isn't a comprehensive guide to using gRPC in C++: more reference documentat Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. -With gRPC we can define our service once in a .proto file and implement clients and servers in , which in turn - all the complexity of communication between different languages and environments is handled for you by gRPC. gRPC also - -We also get all the advantages of working with protocol buffers +With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. [possibly insert more advantages here] @@ -93,15 +91,32 @@ message Point { ## Generating client and server code -Now we need to ... +Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. + +For simplicity, we've provided a [makefile](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've followed the [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): + +```shell +$ make route_guide.pb.cc +``` + +which actually runs: + +[actual command] + +Running this command generates the following files: +- `route_guide.pb.h` +- `route_guide.pb.cc` + +These contain ## Creating the server -First let's look at implementing our R +First let's look at how we create a `RouteGuide` server. There are two parts to making our `RouteGuide` service work: -- +- Implementing the service interface generated from our service definition: doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and return the service responses ## Creating the client -- cgit v1.2.3 From 453eca38bb747d09a6ee0feaa97d6d8e9feaa68d Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Mon, 23 Feb 2015 16:58:19 +0000 Subject: Generating code... --- cpp/cpptutorial.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index ade134c86b..2102678163 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -104,10 +104,12 @@ which actually runs: [actual command] Running this command generates the following files: -- `route_guide.pb.h` -- `route_guide.pb.cc` +- `route_guide.pb.h`, the header which declares your generated classes +- `route_guide.pb.cc`, which contains the implementation of your classes -These contain +These contain: +- All the protocol buffer code to populate, serialize, and retrieve our request and response message types +- A class called `RouteGuide` that contains both a remote interface type (or *stub*) for clients to call and an abstract interface for servers to implement, both with the methods defined in the `RouteGuide` service. ## Creating the server -- cgit v1.2.3 From 10135581963735854ed4918f805ab0c10f7a95d3 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Mon, 23 Feb 2015 09:22:26 -0800 Subject: Update README.md --- cpp/README.md | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/cpp/README.md b/cpp/README.md index 84fa34e705..c1c79b592b 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -3,6 +3,100 @@ First you need to install gRPC on your system. Follow the instructions here: [https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). -After installing, you can proceed to the [gRPC C++ Hello World tutorial](helloworld/README.md). +# gRPC C++ Hello World Tutorial + +### Install gRPC +Make sure you have installed gRPC on your system. Follow the instructions here: +[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). + +### Get the tutorial source code + +The example code for this and our other examples lives in the `grpc-common` +GitHub repository. Clone this repository to your local machine by running the +following command: + + +```sh +$ git clone https://github.com/google/grpc-common.git +``` + +Change your current directory to grpc-common/cpp/helloworld + +```sh +$ cd grpc-common/cpp/helloworld/ +``` + +### Defining a service + +The first step in creating our example is to define a *service*: an RPC +service specifies the methods that can be called remotely with their parameters +and return types. As you saw in the +[overview](#protocolbuffers) above, gRPC does this using [protocol +buffers](https://developers.google.com/protocol-buffers/docs/overview). We +use the protocol buffers interface definition language (IDL) to define our +service methods, and define the parameters and return +types as protocol buffer message types. Both the client and the +server use interface code generated from the service definition. + +Here's our example service definition, defined using protocol buffers IDL in +[helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). The `Greeting` +service has one method, `hello`, that lets the server receive a single +`HelloRequest` +message from the remote client containing the user's name, then send back +a greeting in a single `HelloReply`. This is the simplest type of RPC you +can specify in gRPC - we'll look at some other types later in this document. + +``` +syntax = "proto3"; + +option java_package = "ex.grpc"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} + +``` + + +### Generating gRPC code + +Once we've defined our service, we use the protocol buffer compiler +`protoc` to generate the special client and server code we need to create +our application. The generated code contains both stub code for clients to +use and an abstract interface for servers to implement, both with the method +defined in our `Greeting` service. + +To generate the client and server side interfaces: + +```sh +$ make helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + +```sh +$protoc -I ../../protos/ --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin helloworld.proto +``` + +### Writing a client + +This is an incomplete tutorial. For now the reader should refer to [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). + +### Writing a server + +This is an incomplete tutorial. For now the reader should refer to [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). A more detailed tutorial is coming soon. -- cgit v1.2.3 From 9f5d6f64511a59efa374ae7920f266ffca391a38 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Mon, 23 Feb 2015 09:25:14 -0800 Subject: Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index c123ba0a5a..df3108d839 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,11 @@ +# Please pick your language to proceed: +* [C++](https://github.com/grpc/grpc-common/tree/master/cpp) +* [Java](https://github.com/grpc/grpc-common/tree/master/java) +* [Python](https://github.com/grpc/grpc-common/tree/master/python) +* [Go](https://github.com/grpc/grpc-common/tree/master/go) +* [ruby](https://github.com/grpc/grpc-common/tree/master/ruby) +* [Node.js](https://github.com/grpc/grpc-common/tree/master/node) + # Getting started Welcome to the developer documentation for gRPC, a language-neutral, -- cgit v1.2.3 From 686042c703f367f4cc3351179bfd8de2b52e3727 Mon Sep 17 00:00:00 2001 From: Mugur Marculescu Date: Mon, 23 Feb 2015 09:30:21 -0800 Subject: Delete README_NEW.md Content links moved to main README.md --- README_NEW.md | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 README_NEW.md diff --git a/README_NEW.md b/README_NEW.md deleted file mode 100644 index 583136bc0d..0000000000 --- a/README_NEW.md +++ /dev/null @@ -1,8 +0,0 @@ - -# Please pick your language to proceed: -### [C++](https://github.com/grpc/grpc-common/tree/master/cpp) -### [Java](https://github.com/grpc/grpc-common/tree/master/java) -### [Python](https://github.com/grpc/grpc-common/tree/master/python) -### [Go](https://github.com/grpc/grpc-common/tree/master/go) -### [ruby](https://github.com/grpc/grpc-common/tree/master/ruby) -### [Node.js](https://github.com/grpc/grpc-common/tree/master/node) -- cgit v1.2.3 From d1e11e74939dded780bdaf1693451002d4059c3f Mon Sep 17 00:00:00 2001 From: LisaFC Date: Mon, 23 Feb 2015 18:16:08 +0000 Subject: Update README.md --- cpp/README.md | 79 ++++++++++++----------------------------------------------- 1 file changed, 15 insertions(+), 64 deletions(-) diff --git a/cpp/README.md b/cpp/README.md index c1c79b592b..fe9b71620e 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -1,15 +1,13 @@ -#gRPC C++ Getting started +#gRPC in 3 minutes (C++) -First you need to install gRPC on your system. Follow the instructions here: -[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). - -# gRPC C++ Hello World Tutorial +## Installation -### Install gRPC -Make sure you have installed gRPC on your system. Follow the instructions here: +To install gRPC on your system, follow the instructions here: [https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). -### Get the tutorial source code +## Hello C++ gRPC! + +Here's how to build and run the C++ implementation of the [Hello World](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto) example used in [Getting started](https://github.com/grpc/grpc-common). The example code for this and our other examples lives in the `grpc-common` GitHub repository. Clone this repository to your local machine by running the @@ -26,60 +24,9 @@ Change your current directory to grpc-common/cpp/helloworld $ cd grpc-common/cpp/helloworld/ ``` -### Defining a service - -The first step in creating our example is to define a *service*: an RPC -service specifies the methods that can be called remotely with their parameters -and return types. As you saw in the -[overview](#protocolbuffers) above, gRPC does this using [protocol -buffers](https://developers.google.com/protocol-buffers/docs/overview). We -use the protocol buffers interface definition language (IDL) to define our -service methods, and define the parameters and return -types as protocol buffer message types. Both the client and the -server use interface code generated from the service definition. - -Here's our example service definition, defined using protocol buffers IDL in -[helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). The `Greeting` -service has one method, `hello`, that lets the server receive a single -`HelloRequest` -message from the remote client containing the user's name, then send back -a greeting in a single `HelloReply`. This is the simplest type of RPC you -can specify in gRPC - we'll look at some other types later in this document. - -``` -syntax = "proto3"; - -option java_package = "ex.grpc"; - -package helloworld; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} - -``` - - ### Generating gRPC code -Once we've defined our service, we use the protocol buffer compiler -`protoc` to generate the special client and server code we need to create -our application. The generated code contains both stub code for clients to -use and an abstract interface for servers to implement, both with the method -defined in our `Greeting` service. - To generate the client and server side interfaces: ```sh @@ -91,12 +38,16 @@ Which internally invokes the proto-compiler as: $protoc -I ../../protos/ --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin helloworld.proto ``` -### Writing a client +### Client and server implementations + +The client implementation is at [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). + +The server implementation is at [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). -This is an incomplete tutorial. For now the reader should refer to [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). +### Try it! -### Writing a server +###TODO: instructions to run server and client -This is an incomplete tutorial. For now the reader should refer to [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). +## Tutorial -A more detailed tutorial is coming soon. +You can find a more detailed tutorial in [gRPC Basics: C++](https://github.com/grpc/grpc-common/blob/master/cpp/cpptutorial.md) -- cgit v1.2.3 From 613a1f32c2760bb7836dd1b2aafbb2d960189a99 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Mon, 23 Feb 2015 18:18:46 +0000 Subject: Update README.md --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index df3108d839..a1a3c4b973 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,3 @@ -# Please pick your language to proceed: -* [C++](https://github.com/grpc/grpc-common/tree/master/cpp) -* [Java](https://github.com/grpc/grpc-common/tree/master/java) -* [Python](https://github.com/grpc/grpc-common/tree/master/python) -* [Go](https://github.com/grpc/grpc-common/tree/master/go) -* [ruby](https://github.com/grpc/grpc-common/tree/master/ruby) -* [Node.js](https://github.com/grpc/grpc-common/tree/master/node) # Getting started @@ -14,6 +7,15 @@ platform-neutral remote procedure call (RPC) system developed at Google. This document introduces you to gRPC with a quick overview and a simple Hello World example. More documentation is coming soon! +## Quick start +You can find quick start guides for each language, including installation instructions and examples here: +* [C++](https://github.com/grpc/grpc-common/tree/master/cpp) +* [Java](https://github.com/grpc/grpc-common/tree/master/java) +* [Python](https://github.com/grpc/grpc-common/tree/master/python) +* [Go](https://github.com/grpc/grpc-common/tree/master/go) +* [ruby](https://github.com/grpc/grpc-common/tree/master/ruby) +* [Node.js](https://github.com/grpc/grpc-common/tree/master/node) + ## What's in this repository? The `grpc-common` repository contains documentation, resources, and examples -- cgit v1.2.3 From 3906f35c453e9219bc1f7be0705ad0092d1e7044 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Mon, 23 Feb 2015 10:44:44 -0800 Subject: make things compile --- cpp/route_guide/route_guide_client.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/cpp/route_guide/route_guide_client.cc b/cpp/route_guide/route_guide_client.cc index 6dbe6b8730..86f603f5b4 100644 --- a/cpp/route_guide/route_guide_client.cc +++ b/cpp/route_guide/route_guide_client.cc @@ -86,7 +86,7 @@ RouteNote MakeRouteNote(const std::string& message, return n; } -bool ParseDb(stringstream stream, std::vector* feature_list) { +bool ParseDb(const std::string& stream, std::vector* feature_list) { // TODO } @@ -173,8 +173,8 @@ class RouteGuideClient { void RouteChat() { ClientContext context; - ClientReaderWriter* stream = - stub_->RouteChat(&context); + std::shared_ptr > stream( + stub_->RouteChat(&context)); std::thread writer([stream]() { std::vector notes{ @@ -202,7 +202,6 @@ class RouteGuideClient { if (!status.IsOk()) { std::cout << "RouteChat rpc failed." << std::endl; } - delete stream; } void Shutdown() { stub_.reset(); } @@ -217,7 +216,7 @@ class RouteGuideClient { } std::stringstream db; db << db_file.rdbuf(); - ParseDb(db, &feature_list_); + ParseDb(db.str(), &feature_list_); } private: -- cgit v1.2.3 From 09275f0be4e8c282d2febe3a983fd5632d89cbcc Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 23 Feb 2015 11:08:42 -0800 Subject: Added route guide example --- node/package.json | 5 +- node/route_guide/route_guide.proto | 120 +++++++ node/route_guide/route_guide_client.js | 231 +++++++++++++ node/route_guide/route_guide_db.json | 601 +++++++++++++++++++++++++++++++++ node/route_guide/route_guide_server.js | 249 ++++++++++++++ 5 files changed, 1205 insertions(+), 1 deletion(-) create mode 100644 node/route_guide/route_guide.proto create mode 100644 node/route_guide/route_guide_client.js create mode 100644 node/route_guide/route_guide_db.json create mode 100644 node/route_guide/route_guide_server.js diff --git a/node/package.json b/node/package.json index 435654034f..a669dec8f1 100644 --- a/node/package.json +++ b/node/package.json @@ -2,6 +2,9 @@ "name": "grpc-greeter", "version": "0.1.0", "dependencies": { - "grpc" : "~0.2.0" + "async": "^0.9.0", + "grpc": "~0.2.0", + "minimist": "^1.1.0", + "underscore": "^1.8.2" } } diff --git a/node/route_guide/route_guide.proto b/node/route_guide/route_guide.proto new file mode 100644 index 0000000000..442112823e --- /dev/null +++ b/node/route_guide/route_guide.proto @@ -0,0 +1,120 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "io.grpc.examples"; + +package examples; + +// Interface exported by the server. +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} + + // A server-to-client streaming RPC. + // + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} + + // A client-to-server streaming RPC. + // + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} + + // A Bidirectional streaming RPC. + // + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +} + +// Points are represented as latitude-longitude pairs in the E7 representation +// (degrees multiplied by 10**7 and rounded to the nearest integer). +// Latitudes should be in the range +/- 90 degrees and longitude should be in +// the range +/- 180 degrees (inclusive). +message Point { + optional int32 latitude = 1; + optional int32 longitude = 2; +} + +// A latitude-longitude rectangle, represented as two diagonally opposite +// points "lo" and "hi". +message Rectangle { + // One corner of the rectangle. + optional Point lo = 1; + + // The other corner of the rectangle. + optional Point hi = 2; +} + +// A feature names something at a given point. +// +// If a feature could not be named, the name is empty. +message Feature { + // The name of the feature. + optional string name = 1; + + // The point where the feature is detected. + optional Point location = 2; +} + +// A RouteNote is a message sent while at a given point. +message RouteNote { + // The location from which the message is sent. + optional Point location = 1; + + // The message to be sent. + optional string message = 2; +} + +// A RouteSummary is received in response to a RecordRoute rpc. +// +// It contains the number of individual points received, the number of +// detected features, and the total distance covered as the cumulative sum of +// the distance between each point. +message RouteSummary { + // The number of points received. + optional int32 point_count = 1; + + // The number of known features passed while traversing the route. + optional int32 feature_count = 2; + + // The distance covered in metres. + optional int32 distance = 3; + + // The duration of the traversal in seconds. + optional int32 elapsed_time = 4; +} diff --git a/node/route_guide/route_guide_client.js b/node/route_guide/route_guide_client.js new file mode 100644 index 0000000000..60c47a429d --- /dev/null +++ b/node/route_guide/route_guide_client.js @@ -0,0 +1,231 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +var async = require('async'); +var fs = require('fs'); +var parseArgs = require('minimist'); +var path = require('path'); +var _ = require('underscore'); +var grpc = require('grpc'); +var examples = grpc.load(__dirname + '/route_guide.proto').examples; +var client = new examples.RouteGuide('localhost:50051'); + +var COORD_FACTOR = 1e7; + +/** + * Run the getFeature demo. Calls getFeature with a point known to have a + * feature and a point known not to have a feature. + * @param {function} callback Called when this demo is complete + */ +function runGetFeature(callback) { + var next = _.after(2, callback); + function featureCallback(error, feature) { + if (error) { + callback(error); + } + if (feature.name === '') { + console.log('Found no feature at ' + + feature.location.latitude/COORD_FACTOR + ', ' + + feature.location.longitude/COORD_FACTOR); + } else { + console.log('Found feature called "' + feature.name + '" at ' + + feature.location.latitude/COORD_FACTOR + ', ' + + feature.location.longitude/COORD_FACTOR); + } + next(); + } + var point1 = { + latitude: 409146138, + longitude: -746188906 + }; + var point2 = { + latitude: 0, + longitude: 0 + }; + client.getFeature(point1, featureCallback); + client.getFeature(point2, featureCallback); +} + +/** + * Run the listFeatures demo. Calls listFeatures with a rectangle containing all + * of the features in the pre-generated database. Prints each response as it + * comes in. + * @param {function} callback Called when this demo is complete + */ +function runListFeatures(callback) { + var rectangle = { + lo: { + latitude: 400000000, + longitude: -750000000 + }, + hi: { + latitude: 420000000, + longitude: -730000000 + } + }; + console.log('Looking for features between 40, -75 and 42, -73'); + var call = client.listFeatures(rectangle); + call.on('data', function(feature) { + console.log('Found feature called "' + feature.name + '" at ' + + feature.location.latitude/COORD_FACTOR + ', ' + + feature.location.longitude/COORD_FACTOR); + }); + call.on('end', callback); +} + +/** + * Run the recordRoute demo. Sends several randomly chosen points from the + * pre-generated feature database with a variable delay in between. Prints the + * statistics when they are sent from the server. + * @param {function} callback Called when this demo is complete + */ +function runRecordRoute(callback) { + var argv = parseArgs(process.argv, { + string: 'db_path' + }); + fs.readFile(path.resolve(argv.db_path), function(err, data) { + if (err) callback(err); + var feature_list = JSON.parse(data); + + var num_points = 10; + var call = client.recordRoute(function(error, stats) { + if (error) { + callback(error); + } + console.log('Finished trip with', stats.point_count, 'points'); + console.log('Passed', stats.feature_count, 'features'); + console.log('Travelled', stats.distance, 'meters'); + console.log('It took', stats.elapsed_time, 'seconds'); + callback(); + }); + /** + * Constructs a function that asynchronously sends the given point and then + * delays sending its callback + * @param {number} lat The latitude to send + * @param {number} lng The longitude to send + * @return {function(function)} The function that sends the point + */ + function pointSender(lat, lng) { + /** + * Sends the point, then calls the callback after a delay + * @param {function} callback Called when complete + */ + return function(callback) { + console.log('Visiting point ' + lat/COORD_FACTOR + ', ' + + lng/COORD_FACTOR); + call.write({ + latitude: lat, + longitude: lng + }); + _.delay(callback, _.random(500, 1500)); + }; + } + var point_senders = []; + for (var i = 0; i < num_points; i++) { + var rand_point = feature_list[_.random(0, feature_list.length - 1)]; + point_senders[i] = pointSender(rand_point.location.latitude, + rand_point.location.longitude); + } + async.series(point_senders, function() { + call.end(); + }); + }); +} + +/** + * Run the routeChat demo. Send some chat messages, and print any chat messages + * that are sent from the server. + * @param {function} callback Called when the demo is complete + */ +function runRouteChat(callback) { + var call = client.routeChat(); + call.on('data', function(note) { + console.log('Got message "' + note.message + '" at ' + + note.location.latitude + ', ' + note.location.longitude); + }); + + call.on('end', callback); + + var notes = [{ + location: { + latitude: 0, + longitude: 0 + }, + message: 'First message' + }, { + location: { + latitude: 0, + longitude: 1 + }, + message: 'Second message' + }, { + location: { + latitude: 1, + longitude: 0 + }, + message: 'Third message' + }, { + location: { + latitude: 0, + longitude: 0 + }, + message: 'Fourth message' + }]; + for (var i = 0; i < notes.length; i++) { + var note = notes[i]; + console.log('Sending message "' + note.message + '" at ' + + note.location.latitude + ', ' + note.location.longitude); + call.write(note); + } + call.end(); +} + +/** + * Run all of the demos in order + */ +function main() { + async.series([ + runGetFeature, + runListFeatures, + runRecordRoute, + runRouteChat + ]); +} + +if (require.main === module) { + main(); +} + +exports.runGetFeature = runGetFeature; + +exports.runListFeatures = runListFeatures; + +exports.runRecordRoute = runRecordRoute; + +exports.runRouteChat = runRouteChat; diff --git a/node/route_guide/route_guide_db.json b/node/route_guide/route_guide_db.json new file mode 100644 index 0000000000..9d6a980ab7 --- /dev/null +++ b/node/route_guide/route_guide_db.json @@ -0,0 +1,601 @@ +[{ + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" +}, { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" +}, { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" +}, { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" +}, { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" +}, { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" +}, { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" +}, { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" +}, { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" +}, { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" +}, { + "location": { + "latitude": 415736605, + "longitude": -742847522 + }, + "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" +}, { + "location": { + "latitude": 413843930, + "longitude": -740501726 + }, + "name": "162 Merrill Road, Highland Mills, NY 10930, USA" +}, { + "location": { + "latitude": 410873075, + "longitude": -744459023 + }, + "name": "Clinton Road, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 412346009, + "longitude": -744026814 + }, + "name": "16 Old Brook Lane, Warwick, NY 10990, USA" +}, { + "location": { + "latitude": 402948455, + "longitude": -747903913 + }, + "name": "3 Drake Lane, Pennington, NJ 08534, USA" +}, { + "location": { + "latitude": 406337092, + "longitude": -740122226 + }, + "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" +}, { + "location": { + "latitude": 406421967, + "longitude": -747727624 + }, + "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" +}, { + "location": { + "latitude": 416318082, + "longitude": -749677716 + }, + "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" +}, { + "location": { + "latitude": 415301720, + "longitude": -748416257 + }, + "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" +}, { + "location": { + "latitude": 402647019, + "longitude": -747071791 + }, + "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" +}, { + "location": { + "latitude": 412567807, + "longitude": -741058078 + }, + "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" +}, { + "location": { + "latitude": 416855156, + "longitude": -744420597 + }, + "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" +}, { + "location": { + "latitude": 404663628, + "longitude": -744820157 + }, + "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" +}, { + "location": { + "latitude": 407113723, + "longitude": -749746483 + }, + "name": "" +}, { + "location": { + "latitude": 402133926, + "longitude": -743613249 + }, + "name": "" +}, { + "location": { + "latitude": 400273442, + "longitude": -741220915 + }, + "name": "" +}, { + "location": { + "latitude": 411236786, + "longitude": -744070769 + }, + "name": "" +}, { + "location": { + "latitude": 411633782, + "longitude": -746784970 + }, + "name": "211-225 Plains Road, Augusta, NJ 07822, USA" +}, { + "location": { + "latitude": 415830701, + "longitude": -742952812 + }, + "name": "" +}, { + "location": { + "latitude": 413447164, + "longitude": -748712898 + }, + "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" +}, { + "location": { + "latitude": 405047245, + "longitude": -749800722 + }, + "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" +}, { + "location": { + "latitude": 418858923, + "longitude": -746156790 + }, + "name": "" +}, { + "location": { + "latitude": 417951888, + "longitude": -748484944 + }, + "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" +}, { + "location": { + "latitude": 407033786, + "longitude": -743977337 + }, + "name": "26 East 3rd Street, New Providence, NJ 07974, USA" +}, { + "location": { + "latitude": 417548014, + "longitude": -740075041 + }, + "name": "" +}, { + "location": { + "latitude": 410395868, + "longitude": -744972325 + }, + "name": "" +}, { + "location": { + "latitude": 404615353, + "longitude": -745129803 + }, + "name": "" +}, { + "location": { + "latitude": 406589790, + "longitude": -743560121 + }, + "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" +}, { + "location": { + "latitude": 414653148, + "longitude": -740477477 + }, + "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" +}, { + "location": { + "latitude": 405957808, + "longitude": -743255336 + }, + "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" +}, { + "location": { + "latitude": 411733589, + "longitude": -741648093 + }, + "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" +}, { + "location": { + "latitude": 412676291, + "longitude": -742606606 + }, + "name": "1270 Lakes Road, Monroe, NY 10950, USA" +}, { + "location": { + "latitude": 409224445, + "longitude": -748286738 + }, + "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" +}, { + "location": { + "latitude": 406523420, + "longitude": -742135517 + }, + "name": "652 Garden Street, Elizabeth, NJ 07202, USA" +}, { + "location": { + "latitude": 401827388, + "longitude": -740294537 + }, + "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" +}, { + "location": { + "latitude": 410564152, + "longitude": -743685054 + }, + "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 408472324, + "longitude": -740726046 + }, + "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" +}, { + "location": { + "latitude": 412452168, + "longitude": -740214052 + }, + "name": "5 White Oak Lane, Stony Point, NY 10980, USA" +}, { + "location": { + "latitude": 409146138, + "longitude": -746188906 + }, + "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" +}, { + "location": { + "latitude": 404701380, + "longitude": -744781745 + }, + "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 409642566, + "longitude": -746017679 + }, + "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" +}, { + "location": { + "latitude": 408031728, + "longitude": -748645385 + }, + "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" +}, { + "location": { + "latitude": 413700272, + "longitude": -742135189 + }, + "name": "367 Prospect Road, Chester, NY 10918, USA" +}, { + "location": { + "latitude": 404310607, + "longitude": -740282632 + }, + "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" +}, { + "location": { + "latitude": 409319800, + "longitude": -746201391 + }, + "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" +}, { + "location": { + "latitude": 406685311, + "longitude": -742108603 + }, + "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" +}, { + "location": { + "latitude": 419018117, + "longitude": -749142781 + }, + "name": "43 Dreher Road, Roscoe, NY 12776, USA" +}, { + "location": { + "latitude": 412856162, + "longitude": -745148837 + }, + "name": "Swan Street, Pine Island, NY 10969, USA" +}, { + "location": { + "latitude": 416560744, + "longitude": -746721964 + }, + "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" +}, { + "location": { + "latitude": 405314270, + "longitude": -749836354 + }, + "name": "" +}, { + "location": { + "latitude": 414219548, + "longitude": -743327440 + }, + "name": "" +}, { + "location": { + "latitude": 415534177, + "longitude": -742900616 + }, + "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" +}, { + "location": { + "latitude": 406898530, + "longitude": -749127080 + }, + "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" +}, { + "location": { + "latitude": 407586880, + "longitude": -741670168 + }, + "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" +}, { + "location": { + "latitude": 400106455, + "longitude": -742870190 + }, + "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" +}, { + "location": { + "latitude": 400066188, + "longitude": -746793294 + }, + "name": "" +}, { + "location": { + "latitude": 418803880, + "longitude": -744102673 + }, + "name": "40 Mountain Road, Napanoch, NY 12458, USA" +}, { + "location": { + "latitude": 414204288, + "longitude": -747895140 + }, + "name": "" +}, { + "location": { + "latitude": 414777405, + "longitude": -740615601 + }, + "name": "" +}, { + "location": { + "latitude": 415464475, + "longitude": -747175374 + }, + "name": "48 North Road, Forestburgh, NY 12777, USA" +}, { + "location": { + "latitude": 404062378, + "longitude": -746376177 + }, + "name": "" +}, { + "location": { + "latitude": 405688272, + "longitude": -749285130 + }, + "name": "" +}, { + "location": { + "latitude": 400342070, + "longitude": -748788996 + }, + "name": "" +}, { + "location": { + "latitude": 401809022, + "longitude": -744157964 + }, + "name": "" +}, { + "location": { + "latitude": 404226644, + "longitude": -740517141 + }, + "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" +}, { + "location": { + "latitude": 410322033, + "longitude": -747871659 + }, + "name": "" +}, { + "location": { + "latitude": 407100674, + "longitude": -747742727 + }, + "name": "" +}, { + "location": { + "latitude": 418811433, + "longitude": -741718005 + }, + "name": "213 Bush Road, Stone Ridge, NY 12484, USA" +}, { + "location": { + "latitude": 415034302, + "longitude": -743850945 + }, + "name": "" +}, { + "location": { + "latitude": 411349992, + "longitude": -743694161 + }, + "name": "" +}, { + "location": { + "latitude": 404839914, + "longitude": -744759616 + }, + "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 414638017, + "longitude": -745957854 + }, + "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" +}, { + "location": { + "latitude": 412127800, + "longitude": -740173578 + }, + "name": "" +}, { + "location": { + "latitude": 401263460, + "longitude": -747964303 + }, + "name": "" +}, { + "location": { + "latitude": 412843391, + "longitude": -749086026 + }, + "name": "" +}, { + "location": { + "latitude": 418512773, + "longitude": -743067823 + }, + "name": "" +}, { + "location": { + "latitude": 404318328, + "longitude": -740835638 + }, + "name": "42-102 Main Street, Belford, NJ 07718, USA" +}, { + "location": { + "latitude": 419020746, + "longitude": -741172328 + }, + "name": "" +}, { + "location": { + "latitude": 404080723, + "longitude": -746119569 + }, + "name": "" +}, { + "location": { + "latitude": 401012643, + "longitude": -744035134 + }, + "name": "" +}, { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" +}, { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" +}, { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" +}, { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" +}, { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" +}, { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" +}, { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" +}, { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" +}, { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" +}, { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" +}] diff --git a/node/route_guide/route_guide_server.js b/node/route_guide/route_guide_server.js new file mode 100644 index 0000000000..5dd8412654 --- /dev/null +++ b/node/route_guide/route_guide_server.js @@ -0,0 +1,249 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +var fs = require('fs'); +var parseArgs = require('minimist'); +var path = require('path'); +var _ = require('underscore'); +var grpc = require('grpc'); +var examples = grpc.load(__dirname + '/route_guide.proto').examples; + +var Server = grpc.buildServer([examples.RouteGuide.service]); + +var COORD_FACTOR = 1e7; + +/** + * For simplicity, a point is a record type that looks like + * {latitude: number, longitude: number}, and a feature is a record type that + * looks like {name: string, location: point}. feature objects with name==='' + * are points with no feature. + */ + +/** + * List of feature objects at points that have been requested so far. + */ +var feature_list = []; + +/** + * Get a feature object at the given point, or creates one if it does not exist. + * @param {point} point The point to check + * @return {feature} The feature object at the point. Note that an empty name + * indicates no feature + */ +function checkFeature(point) { + var feature; + // Check if there is already a feature object for the given point + for (var i = 0; i < feature_list.length; i++) { + feature = feature_list[i]; + if (feature.location.latitude === point.latitude && + feature.location.longitude === point.longitude) { + return feature; + } + } + var name = ''; + feature = { + name: name, + location: point + }; + return feature; +} + +/** + * getFeature request handler. Gets a request with a point, and responds with a + * feature object indicating whether there is a feature at that point. + * @param {EventEmitter} call Call object for the handler to process + * @param {function(Error, feature)} callback Response callback + */ +function getFeature(call, callback) { + callback(null, checkFeature(call.request)); +} + +/** + * listFeatures request handler. Gets a request with two points, and responds + * with a stream of all features in the bounding box defined by those points. + * @param {Writable} call Writable stream for responses with an additional + * request property for the request value. + */ +function listFeatures(call) { + var lo = call.request.lo; + var hi = call.request.hi; + var left = _.min([lo.longitude, hi.longitude]); + var right = _.max([lo.longitude, hi.longitude]); + var top = _.max([lo.latitude, hi.latitude]); + var bottom = _.min([lo.latitude, hi.latitude]); + // For each feature, check if it is in the given bounding box + _.each(feature_list, function(feature) { + if (feature.name === '') { + return; + } + if (feature.location.longitude >= left && + feature.location.longitude <= right && + feature.location.latitude >= bottom && + feature.location.latitude <= top) { + call.write(feature); + } + }); + call.end(); +} + +/** + * Calculate the distance between two points using the "haversine" formula. + * This code was taken from http://www.movable-type.co.uk/scripts/latlong.html. + * @param start The starting point + * @param end The end point + * @return The distance between the points in meters + */ +function getDistance(start, end) { + function toRadians(num) { + return num * Math.PI / 180; + } + var lat1 = start.latitude / COORD_FACTOR; + var lat2 = end.latitude / COORD_FACTOR; + var lon1 = start.longitude / COORD_FACTOR; + var lon2 = end.longitude / COORD_FACTOR; + var R = 6371000; // metres + var φ1 = toRadians(lat1); + var φ2 = toRadians(lat2); + var Δφ = toRadians(lat2-lat1); + var Δλ = toRadians(lon2-lon1); + + var a = Math.sin(Δφ/2) * Math.sin(Δφ/2) + + Math.cos(φ1) * Math.cos(φ2) * + Math.sin(Δλ/2) * Math.sin(Δλ/2); + var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); + + return R * c; +} + +/** + * recordRoute handler. Gets a stream of points, and responds with statistics + * about the "trip": number of points, number of known features visited, total + * distance traveled, and total time spent. + * @param {Readable} call The request point stream. + * @param {function(Error, routeSummary)} callback The callback to pass the + * response to + */ +function recordRoute(call, callback) { + var point_count = 0; + var feature_count = 0; + var distance = 0; + var previous = null; + // Start a timer + var start_time = process.hrtime(); + call.on('data', function(point) { + point_count += 1; + if (checkFeature(point).name !== '') { + feature_count += 1; + } + /* For each point after the first, add the incremental distance from the + * previous point to the total distance value */ + if (previous != null) { + distance += getDistance(previous, point); + } + previous = point; + }); + call.on('end', function() { + callback(null, { + point_count: point_count, + feature_count: feature_count, + // Cast the distance to an integer + distance: distance|0, + // End the timer + elapsed_time: process.hrtime(start_time)[0] + }); + }); +} + +var route_notes = {}; + +/** + * Turn the point into a dictionary key. + * @param {point} point The point to use + * @return {string} The key for an object + */ +function pointKey(point) { + return point.latitude + ' ' + point.longitude; +} + +/** + * routeChat handler. Receives a stream of message/location pairs, and responds + * with a stream of all previous messages at each of those locations. + * @param {Duplex} call The stream for incoming and outgoing messages + */ +function routeChat(call) { + call.on('data', function(note) { + var key = pointKey(note.location); + /* For each note sent, respond with all previous notes that correspond to + * the same point */ + if (route_notes.hasOwnProperty(key)) { + _.each(route_notes[key], function(note) { + call.write(note); + }); + } else { + route_notes[key] = []; + } + // Then add the new note to the list + route_notes[key].push(JSON.parse(JSON.stringify(note))); + }); + call.on('end', function() { + call.end(); + }); +} + +/** + * Get a new server with the handler functions in this file bound to the methods + * it serves. + * @return {Server} The new server object + */ +function getServer() { + return new Server({ + 'examples.RouteGuide' : { + getFeature: getFeature, + listFeatures: listFeatures, + recordRoute: recordRoute, + routeChat: routeChat + } + }); +} + +if (require.main === module) { + // If this is run as a script, start a server on an unused port + var routeServer = getServer(); + routeServer.bind('0.0.0.0:50051'); + var argv = parseArgs(process.argv, { + string: 'db_path' + }); + fs.readFile(path.resolve(argv.db_path), function(err, data) { + if (err) throw err; + feature_list = JSON.parse(data); + routeServer.listen(); + }); +} + +exports.getServer = getServer; -- cgit v1.2.3 From ea33d60f71980f53e20c245768efe50683170e24 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Mon, 23 Feb 2015 13:55:33 -0800 Subject: Server impl. Status: builds. Missing db parsing logic --- cpp/route_guide/route_guide_client.cc | 24 +++--- cpp/route_guide/route_guide_server.cc | 143 +++++++++++++++++++++++++++++++++- 2 files changed, 154 insertions(+), 13 deletions(-) diff --git a/cpp/route_guide/route_guide_client.cc b/cpp/route_guide/route_guide_client.cc index 86f603f5b4..8b4a532327 100644 --- a/cpp/route_guide/route_guide_client.cc +++ b/cpp/route_guide/route_guide_client.cc @@ -90,6 +90,19 @@ bool ParseDb(const std::string& stream, std::vector* feature_list) { // TODO } +void FillFeatureList(const std::string& db_path, std::vector* feature_list) { + if (db_path.empty()) { + return; + } + std::ifstream db_file(db_path); + if (!db_file.is_open()) { + std::cout << "Failed to open " << db_path << std::endl; + } + std::stringstream db; + db << db_file.rdbuf(); + ParseDb(db.str(), feature_list); +} + class RouteGuideClient { public: RouteGuideClient(std::shared_ptr channel) @@ -207,16 +220,7 @@ class RouteGuideClient { void Shutdown() { stub_.reset(); } void FillFeatureList(const std::string& db_path) { - if (db_path.empty()) { - return; - } - std::ifstream db_file(db_path); - if (!db_file.is_open()) { - std::cout << "Failed to open " << db_path << std::endl; - } - std::stringstream db; - db << db_file.rdbuf(); - ParseDb(db.str(), &feature_list_); + ::FillFeatureList(db_path, &feature_list_); } private: diff --git a/cpp/route_guide/route_guide_server.cc b/cpp/route_guide/route_guide_server.cc index 718afbae2a..d4ecded69b 100644 --- a/cpp/route_guide/route_guide_server.cc +++ b/cpp/route_guide/route_guide_server.cc @@ -31,8 +31,13 @@ * */ +#include +#include +#include +#include #include #include +#include #include #include @@ -57,29 +62,148 @@ using examples::Rectangle; using examples::RouteSummary; using examples::RouteNote; using examples::RouteGuide; +using std::chrono::system_clock; + +const float kCoordFactor = 10000000.0; + +bool ParseDb(const std::string& stream, std::vector* feature_list) { + // TODO +} + +float ConvertToRadians(float num) { + return num * 3.1415926 /180; +} + +float GetDistance(const Point& start, const Point& end) { + + float lat_1 = start.latitude() / kCoordFactor; + float lat_2 = end.latitude() / kCoordFactor; + float lon_1 = start.longitude() / kCoordFactor; + float lon_2 = end.longitude() / kCoordFactor; + float lat_rad_1 = ConvertToRadians(lat_1); + float lat_rad_2 = ConvertToRadians(lat_2); + float delta_lat_rad = ConvertToRadians(lat_2-lat_1); + float delta_lon_rad = ConvertToRadians(lon_2-lon_1); + + float a = pow(sin(delta_lat_rad/2), 2) + cos(lat_rad_1) * cos(lat_rad_2) * + pow(sin(delta_lon_rad/2), 2); + float c = 2 * atan2(sqrt(a), sqrt(1-a)); + int R = 6371000; // metres + + return R * c; +} + +void FillFeatureList(const std::string& db_path, std::vector* feature_list) { + if (db_path.empty()) { + return; + } + std::ifstream db_file(db_path); + if (!db_file.is_open()) { + std::cout << "Failed to open " << db_path << std::endl; + } + std::stringstream db; + db << db_file.rdbuf(); + ParseDb(db.str(), feature_list); +} + +std::string GetFeatureName(const Point& point, + const std::vector& feature_list) { + for (const Feature& f : feature_list) { + if (f.location().latitude() == point.latitude() && + f.location().longitude() == point.longitude()) { + return f.name(); + } + } + return ""; +} class RouteGuideImpl final : public RouteGuide::Service { + public: + RouteGuideImpl(const std::string& db_path) { + FillFeatureList(db_path, &feature_list_); + } + Status GetFeature(ServerContext* context, const Point* point, Feature* feature) override { + feature->set_name(GetFeatureName(*point, feature_list_)); + feature->mutable_location()->CopyFrom(*point); return Status::OK; } + Status ListFeatures(ServerContext* context, const Rectangle* rectangle, ServerWriter* writer) override { + auto lo = rectangle->lo(); + auto hi = rectangle->hi(); + long left = std::min(lo.longitude(), hi.longitude()); + long right = std::max(lo.longitude(), hi.longitude()); + long top = std::max(lo.latitude(), hi.latitude()); + long bottom = std::min(lo.latitude(), hi.latitude()); + for (const Feature& f : feature_list_) { + if (f.location().longitude() >= left && + f.location().longitude() <= right && + f.location().latitude() >= bottom && + f.location().latitude() <= top) { + writer->Write(f); + } + } return Status::OK; } + Status RecordRoute(ServerContext* context, ServerReader* reader, RouteSummary* summary) override { + Point point; + int point_count = 0; + int feature_count = 0; + float distance = 0.0; + Point previous; + + system_clock::time_point start_time = system_clock::now(); + while (reader->Read(&point)) { + point_count++; + if (!GetFeatureName(point, feature_list_).empty()) { + feature_count++; + } + if (point_count != 1) { + distance += GetDistance(previous, point); + } + previous = point; + } + system_clock::time_point end_time = system_clock::now(); + summary->set_point_count(point_count); + summary->set_feature_count(feature_count); + summary->set_distance(static_cast(distance)); + auto secs = std::chrono::duration_cast( + end_time - start_time); + summary->set_elapsed_time(secs.count()); + return Status::OK; } + Status RouteChat(ServerContext* context, ServerReaderWriter* stream) override { + std::vector received_notes; + RouteNote note; + while (stream->Read(¬e)) { + for (const RouteNote& n : received_notes) { + if (n.location().latitude() == note.location().latitude() && + n.location().longitude() == note.location().longitude()) { + stream->Write(n); + } + } + received_notes.push_back(note); + } + return Status::OK; } + + private: + + std::vector feature_list_; }; -void RunServer() { +void RunServer(const std::string& db_path) { std::string server_address("0.0.0.0:50051"); - RouteGuideImpl service; + RouteGuideImpl service(db_path); ServerBuilder builder; builder.AddPort(server_address); @@ -94,7 +218,20 @@ void RunServer() { int main(int argc, char** argv) { grpc_init(); - RunServer(); + std::string db_path; + std::string arg_str("--db_path"); + if (argc > 1) { + std::string argv_1 = argv[1]; + size_t start_position = argv_1.find(arg_str); + if (start_position != std::string::npos) { + start_position += arg_str.size(); + if (argv_1[start_position] == ' ' || + argv_1[start_position] == '=') { + db_path = argv_1.substr(start_position + 1); + } + } + } + RunServer(db_path); grpc_shutdown(); return 0; -- cgit v1.2.3 From 178fdf82e1538d3c2c34181cc66d7cb25d29096e Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Mon, 23 Feb 2015 14:16:01 -0800 Subject: clean up a bit --- cpp/route_guide/Makefile | 4 +- cpp/route_guide/helper.cc | 73 +++++++++++++++++++++++++++++++++++ cpp/route_guide/helper.h | 50 ++++++++++++++++++++++++ cpp/route_guide/route_guide_client.cc | 40 +++---------------- cpp/route_guide/route_guide_server.cc | 43 +++------------------ 5 files changed, 136 insertions(+), 74 deletions(-) create mode 100644 cpp/route_guide/helper.cc create mode 100644 cpp/route_guide/helper.h diff --git a/cpp/route_guide/Makefile b/cpp/route_guide/Makefile index fae9a9d284..131956296c 100644 --- a/cpp/route_guide/Makefile +++ b/cpp/route_guide/Makefile @@ -43,10 +43,10 @@ vpath %.proto $(PROTOS_PATH) all: system-check route_guide_client route_guide_server -route_guide_client: route_guide.pb.o route_guide_client.o +route_guide_client: route_guide.pb.o route_guide_client.o helper.o $(CXX) $^ $(LDFLAGS) -o $@ -route_guide_server: route_guide.pb.o route_guide_server.o +route_guide_server: route_guide.pb.o route_guide_server.o helper.o $(CXX) $^ $(LDFLAGS) -o $@ %.pb.cc: %.proto diff --git a/cpp/route_guide/helper.cc b/cpp/route_guide/helper.cc new file mode 100644 index 0000000000..a4be8bfc6c --- /dev/null +++ b/cpp/route_guide/helper.cc @@ -0,0 +1,73 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include "route_guide.pb.h" + +namespace examples { + +std::string GetDbFileContent(int argc, char** argv) { + std::string db_path; + std::string arg_str("--db_path"); + if (argc > 1) { + std::string argv_1 = argv[1]; + size_t start_position = argv_1.find(arg_str); + if (start_position != std::string::npos) { + start_position += arg_str.size(); + if (argv_1[start_position] == ' ' || + argv_1[start_position] == '=') { + db_path = argv_1.substr(start_position + 1); + } + } + } + std::ifstream db_file(db_path); + if (!db_file.is_open()) { + std::cout << "Failed to open " << db_path << std::endl; + return ""; + } + std::stringstream db; + db << db_file.rdbuf(); + return db.str(); +} + +void ParseDb(const std::string& db, std::vector* feature_list) { + +} + + +} // namespace examples + diff --git a/cpp/route_guide/helper.h b/cpp/route_guide/helper.h new file mode 100644 index 0000000000..65c93c1d34 --- /dev/null +++ b/cpp/route_guide/helper.h @@ -0,0 +1,50 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_ +#define GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_ + +#include +#include + +namespace examples { +class Feature; + +std::string GetDbFileContent(int argc, char** argv); + +void ParseDb(const std::string& db, std::vector* feature_list); + +} // namespace examples + +#endif // GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_ + diff --git a/cpp/route_guide/route_guide_client.cc b/cpp/route_guide/route_guide_client.cc index 8b4a532327..fd3d98e30a 100644 --- a/cpp/route_guide/route_guide_client.cc +++ b/cpp/route_guide/route_guide_client.cc @@ -32,11 +32,9 @@ */ #include -#include #include #include #include -#include #include #include @@ -47,6 +45,7 @@ #include #include #include +#include "helper.h" #include "route_guide.pb.h" using grpc::ChannelArguments; @@ -86,23 +85,6 @@ RouteNote MakeRouteNote(const std::string& message, return n; } -bool ParseDb(const std::string& stream, std::vector* feature_list) { - // TODO -} - -void FillFeatureList(const std::string& db_path, std::vector* feature_list) { - if (db_path.empty()) { - return; - } - std::ifstream db_file(db_path); - if (!db_file.is_open()) { - std::cout << "Failed to open " << db_path << std::endl; - } - std::stringstream db; - db << db_file.rdbuf(); - ParseDb(db.str(), feature_list); -} - class RouteGuideClient { public: RouteGuideClient(std::shared_ptr channel) @@ -219,8 +201,8 @@ class RouteGuideClient { void Shutdown() { stub_.reset(); } - void FillFeatureList(const std::string& db_path) { - ::FillFeatureList(db_path, &feature_list_); + void FillFeatureList(const std::string& db) { + examples::ParseDb(db, &feature_list_); } private: @@ -258,20 +240,8 @@ int main(int argc, char** argv) { RouteGuideClient guide( grpc::CreateChannel("localhost:50051", ChannelArguments())); - std::string db_path; - std::string arg_str("--db_path"); - if (argc > 1) { - std::string argv_1 = argv[1]; - size_t start_position = argv_1.find(arg_str); - if (start_position != std::string::npos) { - start_position += arg_str.size(); - if (argv_1[start_position] == ' ' || - argv_1[start_position] == '=') { - db_path = argv_1.substr(start_position + 1); - } - } - } - guide.FillFeatureList(db_path); + std::string db = examples::GetDbFileContent(argc, argv); + guide.FillFeatureList(db); guide.GetFeature(); guide.ListFeatures(); diff --git a/cpp/route_guide/route_guide_server.cc b/cpp/route_guide/route_guide_server.cc index d4ecded69b..38cd64be94 100644 --- a/cpp/route_guide/route_guide_server.cc +++ b/cpp/route_guide/route_guide_server.cc @@ -34,10 +34,8 @@ #include #include #include -#include #include #include -#include #include #include @@ -47,6 +45,7 @@ #include #include #include +#include "helper.h" #include "route_guide.pb.h" using grpc::Server; @@ -64,18 +63,13 @@ using examples::RouteNote; using examples::RouteGuide; using std::chrono::system_clock; -const float kCoordFactor = 10000000.0; - -bool ParseDb(const std::string& stream, std::vector* feature_list) { - // TODO -} float ConvertToRadians(float num) { return num * 3.1415926 /180; } float GetDistance(const Point& start, const Point& end) { - + const float kCoordFactor = 10000000.0; float lat_1 = start.latitude() / kCoordFactor; float lat_2 = end.latitude() / kCoordFactor; float lon_1 = start.longitude() / kCoordFactor; @@ -93,19 +87,6 @@ float GetDistance(const Point& start, const Point& end) { return R * c; } -void FillFeatureList(const std::string& db_path, std::vector* feature_list) { - if (db_path.empty()) { - return; - } - std::ifstream db_file(db_path); - if (!db_file.is_open()) { - std::cout << "Failed to open " << db_path << std::endl; - } - std::stringstream db; - db << db_file.rdbuf(); - ParseDb(db.str(), feature_list); -} - std::string GetFeatureName(const Point& point, const std::vector& feature_list) { for (const Feature& f : feature_list) { @@ -119,8 +100,8 @@ std::string GetFeatureName(const Point& point, class RouteGuideImpl final : public RouteGuide::Service { public: - RouteGuideImpl(const std::string& db_path) { - FillFeatureList(db_path, &feature_list_); + RouteGuideImpl(const std::string& db) { + examples::ParseDb(db, &feature_list_); } Status GetFeature(ServerContext* context, const Point* point, @@ -218,20 +199,8 @@ void RunServer(const std::string& db_path) { int main(int argc, char** argv) { grpc_init(); - std::string db_path; - std::string arg_str("--db_path"); - if (argc > 1) { - std::string argv_1 = argv[1]; - size_t start_position = argv_1.find(arg_str); - if (start_position != std::string::npos) { - start_position += arg_str.size(); - if (argv_1[start_position] == ' ' || - argv_1[start_position] == '=') { - db_path = argv_1.substr(start_position + 1); - } - } - } - RunServer(db_path); + std::string db = examples::GetDbFileContent(argc, argv); + RunServer(db); grpc_shutdown(); return 0; -- cgit v1.2.3 From dbc06dd84c80d0f2211f24d65d786367e140e1cb Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Mon, 23 Feb 2015 14:26:28 -0800 Subject: more cleanup --- cpp/route_guide/helper.cc | 1 + cpp/route_guide/route_guide_client.cc | 17 ++++++++--------- cpp/route_guide/route_guide_server.cc | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cpp/route_guide/helper.cc b/cpp/route_guide/helper.cc index a4be8bfc6c..8c04489837 100644 --- a/cpp/route_guide/helper.cc +++ b/cpp/route_guide/helper.cc @@ -65,6 +65,7 @@ std::string GetDbFileContent(int argc, char** argv) { } void ParseDb(const std::string& db, std::vector* feature_list) { + feature_list->clear(); } diff --git a/cpp/route_guide/route_guide_client.cc b/cpp/route_guide/route_guide_client.cc index fd3d98e30a..01c48c9e16 100644 --- a/cpp/route_guide/route_guide_client.cc +++ b/cpp/route_guide/route_guide_client.cc @@ -87,8 +87,11 @@ RouteNote MakeRouteNote(const std::string& message, class RouteGuideClient { public: - RouteGuideClient(std::shared_ptr channel) - : stub_(RouteGuide::NewStub(channel)) {} + RouteGuideClient(std::shared_ptr channel, + const std::string& db) + : stub_(RouteGuide::NewStub(channel)) { + examples::ParseDb(db, &feature_list_); + } void GetFeature() { Point point; @@ -201,10 +204,6 @@ class RouteGuideClient { void Shutdown() { stub_.reset(); } - void FillFeatureList(const std::string& db) { - examples::ParseDb(db, &feature_list_); - } - private: bool GetOneFeature(const Point& point, Feature* feature) { @@ -238,10 +237,10 @@ class RouteGuideClient { int main(int argc, char** argv) { grpc_init(); - RouteGuideClient guide( - grpc::CreateChannel("localhost:50051", ChannelArguments())); std::string db = examples::GetDbFileContent(argc, argv); - guide.FillFeatureList(db); + RouteGuideClient guide( + grpc::CreateChannel("localhost:50051", ChannelArguments()), + db); guide.GetFeature(); guide.ListFeatures(); diff --git a/cpp/route_guide/route_guide_server.cc b/cpp/route_guide/route_guide_server.cc index 38cd64be94..62fee245d0 100644 --- a/cpp/route_guide/route_guide_server.cc +++ b/cpp/route_guide/route_guide_server.cc @@ -100,7 +100,7 @@ std::string GetFeatureName(const Point& point, class RouteGuideImpl final : public RouteGuide::Service { public: - RouteGuideImpl(const std::string& db) { + explicit RouteGuideImpl(const std::string& db) { examples::ParseDb(db, &feature_list_); } -- cgit v1.2.3 From 9b7f104ee3ed7a7514f1aa887147df76497f585b Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Mon, 23 Feb 2015 17:00:07 -0800 Subject: Add a simple parser --- cpp/route_guide/helper.cc | 102 ++++++ cpp/route_guide/route_guide_db.json | 601 ++++++++++++++++++++++++++++++++++++ 2 files changed, 703 insertions(+) create mode 100644 cpp/route_guide/route_guide_db.json diff --git a/cpp/route_guide/helper.cc b/cpp/route_guide/helper.cc index 8c04489837..3e10496317 100644 --- a/cpp/route_guide/helper.cc +++ b/cpp/route_guide/helper.cc @@ -31,6 +31,8 @@ * */ +#include +#include #include #include #include @@ -64,9 +66,109 @@ std::string GetDbFileContent(int argc, char** argv) { return db.str(); } +// A simple parser for the json db file. It requires the db file to have the +// exact form of [{"location": { "latitude": 123, "longitude": 456}, "name": +// "the name can be empty" }, { ... } ... The spaces will be stripped. +class Parser { + public: + explicit Parser(const std::string& db) : db_(db) { + // Remove all spaces. + db_.erase( + std::remove_if(db_.begin(), db_.end(), isspace), + db_.end()); + if (!Match("[")) { + SetFailedAndReturnFalse(); + } + } + + bool Finished() { + return current_ >= db_.size(); + } + + bool TryParseOne(Feature* feature) { + if (failed_ || Finished() || !Match("{")) { + return SetFailedAndReturnFalse(); + } + if (!Match(location_) || !Match("{") || !Match(latitude_)) { + return SetFailedAndReturnFalse(); + } + long temp = 0; + ReadLong(&temp); + feature->mutable_location()->set_latitude(temp); + if (!Match(",") || !Match(longitude_)) { + return SetFailedAndReturnFalse(); + } + ReadLong(&temp); + feature->mutable_location()->set_longitude(temp); + if (!Match("},") || !Match(name_) || !Match("\"")) { + return SetFailedAndReturnFalse(); + } + size_t name_start = current_; + while (current_ != db_.size() && db_[current_++] != '"') { + } + if (current_ == db_.size()) { + return SetFailedAndReturnFalse(); + } + feature->set_name(db_.substr(name_start, current_-name_start-1)); + if (!Match("},")) { + if (db_[current_ - 1] == ']' && current_ == db_.size()) { + return true; + } + return SetFailedAndReturnFalse(); + } + return true; + } + + private: + + bool SetFailedAndReturnFalse() { + failed_ = true; + return false; + } + + bool Match(const std::string& prefix) { + bool eq = db_.substr(current_, prefix.size()) == prefix; + current_ += prefix.size(); + return eq; + } + + void ReadLong(long* l) { + size_t start = current_; + while (current_ != db_.size() && db_[current_] != ',' && db_[current_] != '}') { + current_++; + } + // It will throw an exception if fails. + *l = std::stol(db_.substr(start, current_ - start)); + } + + bool failed_ = false; + std::string db_; + size_t current_ = 0; + const std::string location_ = "\"location\":"; + const std::string latitude_ = "\"latitude\":"; + const std::string longitude_ = "\"longitude\":"; + const std::string name_ = "\"name\":"; +}; + void ParseDb(const std::string& db, std::vector* feature_list) { feature_list->clear(); + std::string db_content(db); + db_content.erase( + std::remove_if(db_content.begin(), db_content.end(), isspace), + db_content.end()); + Parser parser(db_content); + Feature feature; + while (!parser.Finished()) { + feature_list->push_back(Feature()); + if (!parser.TryParseOne(&feature_list->back())) { + std::cout << "Error parsing the db file"; + feature_list->clear(); + break; + } + } + std::cout << "DB parsed, loaded " << feature_list->size() + << " features." << std::endl; } diff --git a/cpp/route_guide/route_guide_db.json b/cpp/route_guide/route_guide_db.json new file mode 100644 index 0000000000..9d6a980ab7 --- /dev/null +++ b/cpp/route_guide/route_guide_db.json @@ -0,0 +1,601 @@ +[{ + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" +}, { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" +}, { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" +}, { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" +}, { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" +}, { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" +}, { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" +}, { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" +}, { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" +}, { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" +}, { + "location": { + "latitude": 415736605, + "longitude": -742847522 + }, + "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" +}, { + "location": { + "latitude": 413843930, + "longitude": -740501726 + }, + "name": "162 Merrill Road, Highland Mills, NY 10930, USA" +}, { + "location": { + "latitude": 410873075, + "longitude": -744459023 + }, + "name": "Clinton Road, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 412346009, + "longitude": -744026814 + }, + "name": "16 Old Brook Lane, Warwick, NY 10990, USA" +}, { + "location": { + "latitude": 402948455, + "longitude": -747903913 + }, + "name": "3 Drake Lane, Pennington, NJ 08534, USA" +}, { + "location": { + "latitude": 406337092, + "longitude": -740122226 + }, + "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" +}, { + "location": { + "latitude": 406421967, + "longitude": -747727624 + }, + "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" +}, { + "location": { + "latitude": 416318082, + "longitude": -749677716 + }, + "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" +}, { + "location": { + "latitude": 415301720, + "longitude": -748416257 + }, + "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" +}, { + "location": { + "latitude": 402647019, + "longitude": -747071791 + }, + "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" +}, { + "location": { + "latitude": 412567807, + "longitude": -741058078 + }, + "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" +}, { + "location": { + "latitude": 416855156, + "longitude": -744420597 + }, + "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" +}, { + "location": { + "latitude": 404663628, + "longitude": -744820157 + }, + "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" +}, { + "location": { + "latitude": 407113723, + "longitude": -749746483 + }, + "name": "" +}, { + "location": { + "latitude": 402133926, + "longitude": -743613249 + }, + "name": "" +}, { + "location": { + "latitude": 400273442, + "longitude": -741220915 + }, + "name": "" +}, { + "location": { + "latitude": 411236786, + "longitude": -744070769 + }, + "name": "" +}, { + "location": { + "latitude": 411633782, + "longitude": -746784970 + }, + "name": "211-225 Plains Road, Augusta, NJ 07822, USA" +}, { + "location": { + "latitude": 415830701, + "longitude": -742952812 + }, + "name": "" +}, { + "location": { + "latitude": 413447164, + "longitude": -748712898 + }, + "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" +}, { + "location": { + "latitude": 405047245, + "longitude": -749800722 + }, + "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" +}, { + "location": { + "latitude": 418858923, + "longitude": -746156790 + }, + "name": "" +}, { + "location": { + "latitude": 417951888, + "longitude": -748484944 + }, + "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" +}, { + "location": { + "latitude": 407033786, + "longitude": -743977337 + }, + "name": "26 East 3rd Street, New Providence, NJ 07974, USA" +}, { + "location": { + "latitude": 417548014, + "longitude": -740075041 + }, + "name": "" +}, { + "location": { + "latitude": 410395868, + "longitude": -744972325 + }, + "name": "" +}, { + "location": { + "latitude": 404615353, + "longitude": -745129803 + }, + "name": "" +}, { + "location": { + "latitude": 406589790, + "longitude": -743560121 + }, + "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" +}, { + "location": { + "latitude": 414653148, + "longitude": -740477477 + }, + "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" +}, { + "location": { + "latitude": 405957808, + "longitude": -743255336 + }, + "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" +}, { + "location": { + "latitude": 411733589, + "longitude": -741648093 + }, + "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" +}, { + "location": { + "latitude": 412676291, + "longitude": -742606606 + }, + "name": "1270 Lakes Road, Monroe, NY 10950, USA" +}, { + "location": { + "latitude": 409224445, + "longitude": -748286738 + }, + "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" +}, { + "location": { + "latitude": 406523420, + "longitude": -742135517 + }, + "name": "652 Garden Street, Elizabeth, NJ 07202, USA" +}, { + "location": { + "latitude": 401827388, + "longitude": -740294537 + }, + "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" +}, { + "location": { + "latitude": 410564152, + "longitude": -743685054 + }, + "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 408472324, + "longitude": -740726046 + }, + "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" +}, { + "location": { + "latitude": 412452168, + "longitude": -740214052 + }, + "name": "5 White Oak Lane, Stony Point, NY 10980, USA" +}, { + "location": { + "latitude": 409146138, + "longitude": -746188906 + }, + "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" +}, { + "location": { + "latitude": 404701380, + "longitude": -744781745 + }, + "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 409642566, + "longitude": -746017679 + }, + "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" +}, { + "location": { + "latitude": 408031728, + "longitude": -748645385 + }, + "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" +}, { + "location": { + "latitude": 413700272, + "longitude": -742135189 + }, + "name": "367 Prospect Road, Chester, NY 10918, USA" +}, { + "location": { + "latitude": 404310607, + "longitude": -740282632 + }, + "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" +}, { + "location": { + "latitude": 409319800, + "longitude": -746201391 + }, + "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" +}, { + "location": { + "latitude": 406685311, + "longitude": -742108603 + }, + "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" +}, { + "location": { + "latitude": 419018117, + "longitude": -749142781 + }, + "name": "43 Dreher Road, Roscoe, NY 12776, USA" +}, { + "location": { + "latitude": 412856162, + "longitude": -745148837 + }, + "name": "Swan Street, Pine Island, NY 10969, USA" +}, { + "location": { + "latitude": 416560744, + "longitude": -746721964 + }, + "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" +}, { + "location": { + "latitude": 405314270, + "longitude": -749836354 + }, + "name": "" +}, { + "location": { + "latitude": 414219548, + "longitude": -743327440 + }, + "name": "" +}, { + "location": { + "latitude": 415534177, + "longitude": -742900616 + }, + "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" +}, { + "location": { + "latitude": 406898530, + "longitude": -749127080 + }, + "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" +}, { + "location": { + "latitude": 407586880, + "longitude": -741670168 + }, + "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" +}, { + "location": { + "latitude": 400106455, + "longitude": -742870190 + }, + "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" +}, { + "location": { + "latitude": 400066188, + "longitude": -746793294 + }, + "name": "" +}, { + "location": { + "latitude": 418803880, + "longitude": -744102673 + }, + "name": "40 Mountain Road, Napanoch, NY 12458, USA" +}, { + "location": { + "latitude": 414204288, + "longitude": -747895140 + }, + "name": "" +}, { + "location": { + "latitude": 414777405, + "longitude": -740615601 + }, + "name": "" +}, { + "location": { + "latitude": 415464475, + "longitude": -747175374 + }, + "name": "48 North Road, Forestburgh, NY 12777, USA" +}, { + "location": { + "latitude": 404062378, + "longitude": -746376177 + }, + "name": "" +}, { + "location": { + "latitude": 405688272, + "longitude": -749285130 + }, + "name": "" +}, { + "location": { + "latitude": 400342070, + "longitude": -748788996 + }, + "name": "" +}, { + "location": { + "latitude": 401809022, + "longitude": -744157964 + }, + "name": "" +}, { + "location": { + "latitude": 404226644, + "longitude": -740517141 + }, + "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" +}, { + "location": { + "latitude": 410322033, + "longitude": -747871659 + }, + "name": "" +}, { + "location": { + "latitude": 407100674, + "longitude": -747742727 + }, + "name": "" +}, { + "location": { + "latitude": 418811433, + "longitude": -741718005 + }, + "name": "213 Bush Road, Stone Ridge, NY 12484, USA" +}, { + "location": { + "latitude": 415034302, + "longitude": -743850945 + }, + "name": "" +}, { + "location": { + "latitude": 411349992, + "longitude": -743694161 + }, + "name": "" +}, { + "location": { + "latitude": 404839914, + "longitude": -744759616 + }, + "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 414638017, + "longitude": -745957854 + }, + "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" +}, { + "location": { + "latitude": 412127800, + "longitude": -740173578 + }, + "name": "" +}, { + "location": { + "latitude": 401263460, + "longitude": -747964303 + }, + "name": "" +}, { + "location": { + "latitude": 412843391, + "longitude": -749086026 + }, + "name": "" +}, { + "location": { + "latitude": 418512773, + "longitude": -743067823 + }, + "name": "" +}, { + "location": { + "latitude": 404318328, + "longitude": -740835638 + }, + "name": "42-102 Main Street, Belford, NJ 07718, USA" +}, { + "location": { + "latitude": 419020746, + "longitude": -741172328 + }, + "name": "" +}, { + "location": { + "latitude": 404080723, + "longitude": -746119569 + }, + "name": "" +}, { + "location": { + "latitude": 401012643, + "longitude": -744035134 + }, + "name": "" +}, { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" +}, { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" +}, { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" +}, { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" +}, { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" +}, { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" +}, { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" +}, { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" +}, { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" +}, { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" +}] -- cgit v1.2.3 From bc69d72f91a6dbed2d665145859ca991db12ad1a Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Mon, 23 Feb 2015 19:15:09 -0800 Subject: Adds a quickstart README for java with working instructions --- java/README.md | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 java/README.md diff --git a/java/README.md b/java/README.md new file mode 100644 index 0000000000..8cd0e59896 --- /dev/null +++ b/java/README.md @@ -0,0 +1,59 @@ +gRPC in 3 minutes (Java) +======================== + +PREREQUISITES +------------- + +- [Java 8](http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html) + +- [Maven 2.3](http://maven.apache.org/users/index.html). + - this is needed to install Netty5, a dependency of gRPC, and to build this sample + +- [Latest version of google-protobuf](https://github.com/google/protobuf/tree/master/java) + - to generate java code from proto files + - to install the base Java proto3 library + + +INSTALL +------- + +1 Clone the gRPC Java git repo +```sh +$ cd +$ git clone https://github.com/grpc/grpc-java +``` + +2 Install gRPC Java, as described in [How to Build](https://github.com/grpc/grpc-java#how-to-build) +```sh +$ # from this dir +$ cd grpc-java +$ # follow the instructions in 'How to Build' +``` + +3 Clone this repo, if you've not already done so. +```sh +$ cd +$ git clone https://github.com/grpc/grpc-common +$ cd grpc-common/java # switch to this directory +``` + +4 Build the samples +```sh +$ # from this directory +$ mvn package +``` + +TRY IT! +------- + +- Run the server +```sh +$ # from this directory +$ ./run_greeter_server.sh & +``` + +- Run the client +```sh +$ # from this directory +$ ./run_greeter_client.sh +``` -- cgit v1.2.3 From f65c93abde35c9999096812b60cb891eb965ef50 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Mon, 23 Feb 2015 22:01:56 -0800 Subject: Add more logs --- cpp/route_guide/route_guide_client.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cpp/route_guide/route_guide_client.cc b/cpp/route_guide/route_guide_client.cc index 01c48c9e16..5fb1697934 100644 --- a/cpp/route_guide/route_guide_client.cc +++ b/cpp/route_guide/route_guide_client.cc @@ -242,9 +242,13 @@ int main(int argc, char** argv) { grpc::CreateChannel("localhost:50051", ChannelArguments()), db); + std::cout << "-------------- GetFeature --------------" << std::endl; guide.GetFeature(); + std::cout << "-------------- ListFeatures --------------" << std::endl; guide.ListFeatures(); + std::cout << "-------------- RecordRoute --------------" << std::endl; guide.RecordRoute(); + std::cout << "-------------- RouteChat --------------" << std::endl; guide.RouteChat(); guide.Shutdown(); -- cgit v1.2.3 From 57d306e78ef329842d89bfe9a1aee6583241c0be Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Mon, 23 Feb 2015 22:40:19 -0800 Subject: Sync-up API change and seed the random generator --- cpp/route_guide/route_guide_client.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cpp/route_guide/route_guide_client.cc b/cpp/route_guide/route_guide_client.cc index 5fb1697934..acb8dd489d 100644 --- a/cpp/route_guide/route_guide_client.cc +++ b/cpp/route_guide/route_guide_client.cc @@ -135,7 +135,9 @@ class RouteGuideClient { RouteSummary stats; ClientContext context; const int kPoints = 10; - std::default_random_engine generator; + unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); + + std::default_random_engine generator(seed); std::uniform_int_distribution feature_distribution( 0, feature_list_.size() - 1); std::uniform_int_distribution delay_distribution( @@ -239,7 +241,7 @@ int main(int argc, char** argv) { std::string db = examples::GetDbFileContent(argc, argv); RouteGuideClient guide( - grpc::CreateChannel("localhost:50051", ChannelArguments()), + grpc::CreateChannelDeprecated("localhost:50051", ChannelArguments()), db); std::cout << "-------------- GetFeature --------------" << std::endl; -- cgit v1.2.3 From 9f392590bba5b517fc82f7b25b9de71c4c707d6b Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Mon, 23 Feb 2015 22:51:14 -0800 Subject: Add default json path --- cpp/route_guide/helper.cc | 2 ++ cpp/route_guide/route_guide_client.cc | 1 + cpp/route_guide/route_guide_server.cc | 1 + 3 files changed, 4 insertions(+) diff --git a/cpp/route_guide/helper.cc b/cpp/route_guide/helper.cc index 3e10496317..d147846463 100644 --- a/cpp/route_guide/helper.cc +++ b/cpp/route_guide/helper.cc @@ -55,6 +55,8 @@ std::string GetDbFileContent(int argc, char** argv) { db_path = argv_1.substr(start_position + 1); } } + } else { + db_path = "route_guide_db.json"; } std::ifstream db_file(db_path); if (!db_file.is_open()) { diff --git a/cpp/route_guide/route_guide_client.cc b/cpp/route_guide/route_guide_client.cc index acb8dd489d..cbf420780d 100644 --- a/cpp/route_guide/route_guide_client.cc +++ b/cpp/route_guide/route_guide_client.cc @@ -239,6 +239,7 @@ class RouteGuideClient { int main(int argc, char** argv) { grpc_init(); + // Expect only arg: --db_path=path/to/route_guide_db.json. std::string db = examples::GetDbFileContent(argc, argv); RouteGuideClient guide( grpc::CreateChannelDeprecated("localhost:50051", ChannelArguments()), diff --git a/cpp/route_guide/route_guide_server.cc b/cpp/route_guide/route_guide_server.cc index 62fee245d0..2699330e4c 100644 --- a/cpp/route_guide/route_guide_server.cc +++ b/cpp/route_guide/route_guide_server.cc @@ -199,6 +199,7 @@ void RunServer(const std::string& db_path) { int main(int argc, char** argv) { grpc_init(); + // Expect only arg: --db_path=path/to/route_guide_db.json. std::string db = examples::GetDbFileContent(argc, argv); RunServer(db); -- cgit v1.2.3 From 7c968086a99e3eff9d0bb1604f7a63600e606309 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Mon, 23 Feb 2015 22:59:58 -0800 Subject: CreateChannel API change syncup and regenerate files --- cpp/helloworld/greeter_client.cc | 2 +- cpp/helloworld/helloworld.pb.cc | 8 ++++---- cpp/helloworld/helloworld.pb.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cpp/helloworld/greeter_client.cc b/cpp/helloworld/greeter_client.cc index 3c2bbc2074..0eb4746c65 100644 --- a/cpp/helloworld/greeter_client.cc +++ b/cpp/helloworld/greeter_client.cc @@ -80,7 +80,7 @@ int main(int argc, char** argv) { grpc_init(); GreeterClient greeter( - grpc::CreateChannel("localhost:50051", ChannelArguments())); + grpc::CreateChannelDeprecated("localhost:50051", ChannelArguments())); std::string user("world"); std::string reply = greeter.SayHello(user); std::cout << "Greeter received: " << reply << std::endl; diff --git a/cpp/helloworld/helloworld.pb.cc b/cpp/helloworld/helloworld.pb.cc index 9540f2c94c..3675f5f857 100644 --- a/cpp/helloworld/helloworld.pb.cc +++ b/cpp/helloworld/helloworld.pb.cc @@ -590,8 +590,8 @@ 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(); +std::unique_ptr< Greeter::Stub> Greeter::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel) { + std::unique_ptr< Greeter::Stub> stub(new Greeter::Stub()); stub->set_channel(channel); return stub; }; @@ -600,8 +600,8 @@ Greeter::Stub* Greeter::NewStub(const std::shared_ptr< ::grpc::ChannelInterface> 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); +std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>> Greeter::Stub::SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>>(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) {} diff --git a/cpp/helloworld/helloworld.pb.h b/cpp/helloworld/helloworld.pb.h index 1eb870166a..67ec7a2969 100644 --- a/cpp/helloworld/helloworld.pb.h +++ b/cpp/helloworld/helloworld.pb.h @@ -320,9 +320,9 @@ class Greeter final { 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); + std::unique_ptr< ::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); + static std::unique_ptr NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); class Service : public ::grpc::SynchronousService { public: -- cgit v1.2.3 From c23768547439d67dc41390635bc824b187738f26 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Tue, 24 Feb 2015 10:18:50 +0000 Subject: Update README.md Added link to golang/protobuf repo --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a1a3c4b973..92377b04b2 100644 --- a/README.md +++ b/README.md @@ -66,10 +66,9 @@ While protocol buffers have been available for open source users for some time, our examples use a new flavour of protocol buffers called proto3, which has a slightly simplified syntax, some useful new features, and supports lots more languages. This is currently available as an alpha release in -Java, C++ from [the protocol buffers Github +Java, C++, Java_nano (Android Java), Python, and Ruby from [the protocol buffers Github repo](https://github.com/google/protobuf/releases), as well as a Go language -generator [wherever that is](), with more languages in development. Full -documentation for proto3 is currently in development but you can see +generator from [the golang/protobuf Github repo](https://github.com/golang/protobuf), with more languages in development. Full documentation for proto3 is currently in development, but you can see the major differences from the current default version in the [release notes](https://github.com/google/protobuf/releases). In general, we recommend that you use proto3 with gRPC as it lets you use the -- cgit v1.2.3 From 2eadf58ab63a4ddfa7a4a82a32feda448cfb2e03 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Tue, 24 Feb 2015 10:20:33 +0000 Subject: Update README.md --- README.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 92377b04b2..acea9289a7 100644 --- a/README.md +++ b/README.md @@ -71,15 +71,8 @@ repo](https://github.com/google/protobuf/releases), as well as a Go language generator from [the golang/protobuf Github repo](https://github.com/golang/protobuf), with more languages in development. Full documentation for proto3 is currently in development, but you can see the major differences from the current default version in the [release notes](https://github.com/google/protobuf/releases). -In general, we recommend that you use proto3 with gRPC as it lets you use the -full range of gRPC-supported languages, as well as avoiding compatibility -issues with proto2 clients talking to proto3 servers and vice versa. You -can find out more about these potential issues in [where should we put this -info? It's important but not really part of an overview]. If you need to -continue using proto2 for Java, C++, or Python but want -to try gRPC, you can see an example using a proto2 gRPC client and server -[wherever we put it]. - +In general, while you *can* use proto2 (the current default protocol buffers version), we recommend that you use proto3 with gRPC as it lets you use the full range of gRPC-supported languages, as well as avoiding compatibility +issues with proto2 clients talking to proto3 servers and vice versa. ## Hello gRPC! -- cgit v1.2.3 From 21b7fd30cb5a9bcbc6f15bf7fc5ea8a0c78a493d Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 03:58:40 -0800 Subject: Fixed Maven version --- java/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/README.md b/java/README.md index 8cd0e59896..35c9db3192 100644 --- a/java/README.md +++ b/java/README.md @@ -6,7 +6,7 @@ PREREQUISITES - [Java 8](http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html) -- [Maven 2.3](http://maven.apache.org/users/index.html). +- [Maven 3.2](http://maven.apache.org/users/index.html). - this is needed to install Netty5, a dependency of gRPC, and to build this sample - [Latest version of google-protobuf](https://github.com/google/protobuf/tree/master/java) -- cgit v1.2.3 From f3e73a487129c1a971aa7e298a9433c6e60befeb Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 04:09:51 -0800 Subject: Updates the Node.js README to match the common template --- node/README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/node/README.md b/node/README.md index 57dc83ee3f..f9df3b0a81 100644 --- a/node/README.md +++ b/node/README.md @@ -1,17 +1,21 @@ -# gRPC Node.js Helloworld +gRPC in 3 minutes (Node.js) +=========================== -## INSTALLATION REQUIREMENTS +PREREQUISITES +------------- This requires Node 10.x or greater. -## INSTALL +INSTALL +------- - Clone this repository - Follow the instructions in [INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL) to install the gRPC C core. - Run `npm install` to install dependencies - If `grpc` is not found, clone the [gRPC](https://github.com/grpc/grpc) repository and run `npm install path/to/grpc/src/node`. -## USAGE +Try it! +------- - Run the server @@ -27,7 +31,8 @@ This requires Node 10.x or greater. $ nodejs ./greeter_client.js ``` -## NOTE +Note +---- This directory has a copy of `helloworld.proto` because it currently depends on some Protocol Buffer 2.0 syntax that is deprecated in Protocol Buffer 3.0. -- cgit v1.2.3 From 43f3841063f56455b3db0ab3c6fb0cdbcd8c2521 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 07:42:14 -0800 Subject: rename the gem to reflect the fact that it contains two samples --- ruby/greeter.gemspec | 23 ----------------------- ruby/grpc-demo.gemspec | 23 +++++++++++++++++++++++ 2 files changed, 23 insertions(+), 23 deletions(-) delete mode 100644 ruby/greeter.gemspec create mode 100644 ruby/grpc-demo.gemspec diff --git a/ruby/greeter.gemspec b/ruby/greeter.gemspec deleted file mode 100644 index 795c84c0f5..0000000000 --- a/ruby/greeter.gemspec +++ /dev/null @@ -1,23 +0,0 @@ -# -*- 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/grpc-demo.gemspec b/ruby/grpc-demo.gemspec new file mode 100644 index 0000000000..d4e2ec7a26 --- /dev/null +++ b/ruby/grpc-demo.gemspec @@ -0,0 +1,23 @@ +# -*- ruby -*- +# encoding: utf-8 + +Gem::Specification.new do |s| + s.name = 'grpc-demo' + 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/*client.rb ruby/*server.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 -- cgit v1.2.3 From 56dff9f757f5b36ffa7073a7bd22acc968bcee74 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 07:43:10 -0800 Subject: Adds the generated code for the route_guide example --- ruby/lib/route_guide.rb | 37 +++++++++++++++++++++++++++++++++++++ ruby/lib/route_guide_services.rb | 27 +++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 ruby/lib/route_guide.rb create mode 100644 ruby/lib/route_guide_services.rb diff --git a/ruby/lib/route_guide.rb b/ruby/lib/route_guide.rb new file mode 100644 index 0000000000..98bac8395c --- /dev/null +++ b/ruby/lib/route_guide.rb @@ -0,0 +1,37 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: route_guide.proto + +require 'google/protobuf' + +Google::Protobuf::DescriptorPool.generated_pool.build do + add_message "examples.Point" do + optional :latitude, :int32, 1 + optional :longitude, :int32, 2 + end + add_message "examples.Rectangle" do + optional :lo, :message, 1, "examples.Point" + optional :hi, :message, 2, "examples.Point" + end + add_message "examples.Feature" do + optional :name, :string, 1 + optional :location, :message, 2, "examples.Point" + end + add_message "examples.RouteNote" do + optional :location, :message, 1, "examples.Point" + optional :message, :string, 2 + end + add_message "examples.RouteSummary" do + optional :point_count, :int32, 1 + optional :feature_count, :int32, 2 + optional :distance, :int32, 3 + optional :elapsed_time, :int32, 4 + end +end + +module Examples + Point = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.Point").msgclass + Rectangle = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.Rectangle").msgclass + Feature = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.Feature").msgclass + RouteNote = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.RouteNote").msgclass + RouteSummary = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.RouteSummary").msgclass +end diff --git a/ruby/lib/route_guide_services.rb b/ruby/lib/route_guide_services.rb new file mode 100644 index 0000000000..6e07653c42 --- /dev/null +++ b/ruby/lib/route_guide_services.rb @@ -0,0 +1,27 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# Source: route_guide.proto for package 'examples' + +require 'grpc' +require 'route_guide' + +module Examples + module RouteGuide + + # TODO: add proto service documentation here + class Service + + include GRPC::GenericService + + self.marshal_class_method = :encode + self.unmarshal_class_method = :decode + self.service_name = 'examples.RouteGuide' + + rpc :GetFeature, Point, Feature + rpc :ListFeatures, Rectangle, stream(Feature) + rpc :RecordRoute, stream(Point), RouteSummary + rpc :RouteChat, stream(RouteNote), stream(RouteNote) + end + + Stub = Service.rpc_stub_class + end +end -- cgit v1.2.3 From 14184fafc99d858786766f5c3d3e22123cab87af Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Tue, 24 Feb 2015 16:56:30 +0000 Subject: First go of service and client impl stuff --- cpp/cpptutorial.md | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 173 insertions(+), 6 deletions(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index 2102678163..8fa1b6df65 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -30,7 +30,7 @@ Then change your current directory to `grpc-common/cpp/route_guide`: $ cd grpc-common/cpp/route_guide ``` -Although we've provided the complete example so you don't need to generate the gRPC code yourself, if you want to try generating your own server and client interface code you can follow the setup instructions for the C++ gRPC libraries in [grpc/grpc/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). +Although we've provided the complete example so you don't need to generate the gRPC code yourself, if you want to try generating your own server and client interface code you can follow the setup instructions in [the C++ quick start guide](https://github.com/grpc/grpc-common/tree/master/cpp). ## Defining the service @@ -93,7 +93,7 @@ message Point { Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. -For simplicity, we've provided a [makefile](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've followed the [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): +For simplicity, we've provided a [makefile](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): ```shell $ make route_guide.pb.cc @@ -109,22 +109,189 @@ Running this command generates the following files: These contain: - All the protocol buffer code to populate, serialize, and retrieve our request and response message types -- A class called `RouteGuide` that contains both a remote interface type (or *stub*) for clients to call and an abstract interface for servers to implement, both with the methods defined in the `RouteGuide` service. +- A class called `RouteGuide` that contains + - a remote interface type (or *stub*) for clients to call with the methods defined in the `RouteGuide` service. + - two abstract interfaces for servers to implement, also with the methods defined in the `RouteGuide` service. + ## Creating the server -First let's look at how we create a `RouteGuide` server. +First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). -There are two parts to making our `RouteGuide` service work: +There are two parts to making our `RouteGuide` service do its job: - Implementing the service interface generated from our service definition: doing the actual "work" of our service. -- Running a gRPC server to listen for requests from clients and return the service responses +- Running a gRPC server to listen for requests from clients and return the service responses. +You can find our example `RouteGuide` server in [grpc-common/cpp/route_guide/route_guide_server.cc]((https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_server.cc). Let's take a closer look at how it works. +### Implementing RouteGuide + +As you can see, our server has a `RouteGuideImpl` class that implements the generated `RouteGuide::Service` interface: + +```cpp +class RouteGuideImpl final : public RouteGuide::Service { +... +} +``` +In this case we're implementing the *synchronous* version of `RouteGuide`, where... It's also possible to implement an asynchronous interface, `RouteGuide::AsyncService`... + +`RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. + +```cpp + Status GetFeature(ServerContext* context, const Point* point, + Feature* feature) override { + feature->set_name(GetFeatureName(*point, feature_list_)); + feature->mutable_location()->CopyFrom(*point); + return Status::OK; + } +``` + +The method is passed a context object for the RPC, the client's `Point` protocol buffer request, and a `Feature` protocol buffer to fill in with the response information. In the method we populate the `Feature` with the appropriate information, and then `return` with an `OK` status to tell gRPC that we've finished dealing with the RPC and that the `Feature` can be returned to the client. + +Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. + +```cpp + Status ListFeatures(ServerContext* context, const Rectangle* rectangle, + ServerWriter* writer) override { + auto lo = rectangle->lo(); + auto hi = rectangle->hi(); + long left = std::min(lo.longitude(), hi.longitude()); + long right = std::max(lo.longitude(), hi.longitude()); + long top = std::max(lo.latitude(), hi.latitude()); + long bottom = std::min(lo.latitude(), hi.latitude()); + for (const Feature& f : feature_list_) { + if (f.location().longitude() >= left && + f.location().longitude() <= right && + f.location().latitude() >= bottom && + f.location().latitude() <= top) { + writer->Write(f); + } + } + return Status::OK; + } +``` + +As you can see, instead of getting simple request and response objects in our method parameters, this time we get a request object (the `Rectangle` in which our client wants to find `Feature`s) and a special `ServerWriter` object. In the method, we populate as many `Feature` objects as we need to return, writing them to the `ServerWriter` using its `Write()` method. Finally, as in our simple RPC, we `return Status::OK` to tell gRPC that we've finished writing responses. + +If you look at the client-side streaming method `RecordRoute` you'll see it's quite similar, except this time we get a `ServerReader` instead of a request object and a single response. We use the `ServerReader`s `Read()` method to repeatedly read in our client's requests to a request object (in this case a `Point`) until there are no more messages: the server needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. + +```cpp +while (stream->Read(&point)) { + ...//process client input +} +``` +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. + +```cpp + Status RouteChat(ServerContext* context, + ServerReaderWriter* stream) override { + std::vector received_notes; + RouteNote note; + while (stream->Read(¬e)) { + for (const RouteNote& n : received_notes) { + if (n.location().latitude() == note.location().latitude() && + n.location().longitude() == note.location().longitude()) { + stream->Write(n); + } + } + received_notes.push_back(note); + } + + return Status::OK; + } +``` + +This time we get a `ServerReaderWriter` that can be used to read *and* write messages. The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + +### Starting the server + +Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: + +```cpp +void RunServer(const std::string& db_path) { + std::string server_address("0.0.0.0:50051"); + RouteGuideImpl service(db_path); + + ServerBuilder builder; + builder.AddPort(server_address); + builder.RegisterService(&service); + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + while (true) { + std::this_thread::sleep_for(std::chrono::seconds(5)); + } +} +``` +As you can see, we build and start our server using a `ServerBuilder`. To do this, we: + +1. Create an instance of our service implementation class `RouteGuideImpl`. +2. Create an instance of the factory `ServerBuilder` class. +3. Specify the address and port we want to use to listen for client requests using the builder's `AddPort()` method. +4. Register our service implementation with the builder. +5. Call `BuildAndStart()` on the builder to create and start an RPC server for our service. + +_[is there no equivalent of the Stubby4 wait() method, ie do you have to do the while(true) loop to keep the server running?]_ + + ## Creating the client +In this section, we'll look at creating a C++ client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/cpp/route_guide/route_guide_client.cc]((https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_client.cc). + +### Creating a stub + +To call service methods, we first need to create a *stub*. + +First we need to create a gRPC *channel* for our stub, specifying the server address and port we want to connect to and any special channel arguments - in our case we'll use the default `ChannelArguments`: + +```cpp +grpc::CreateChannelDeprecated("localhost:50051", ChannelArguments()); +``` + +Now we can use the channel to create our stub using the `NewStub` method provided in the `RouteGuide` class we generated from our .proto. + +```cpp + public: + RouteGuideClient(std::shared_ptr channel, + const std::string& db) + : stub_(RouteGuide::NewStub(channel)) { + ... + } +``` + +### Calling service methods + +Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. + +```cpp + Point point; + Feature feature; + point = MakePoint(409146138, -746188906); + GetOneFeature(point, &feature); + +... + + bool GetOneFeature(const Point& point, Feature* feature) { + ClientContext context; + Status status = stub_->GetFeature(&context, point, feature); + ... + } +``` + +As you can see, you create and populate a request protocol buffer object (in our case `Point`), and create a response protocol buffer object for the server to fill in. You also create a `ClientContext` object for your call. Finally, you call the method on the stub, passing it the context, request, and response. If the method returns `OK`, then you can read your response information from the server from your response object. + +```cpp + std::cout << "Found feature called " << feature->name() << " at " + << feature->location().latitude()/kCoordFactor_ << ", " + << feature->location().longitude()/kCoordFactor_ << std::endl; +``` + +Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. + +## Try it out! +_[need build and run instructions here]_ -- cgit v1.2.3 From 18e24c8cca29d3864f9cf6bc75d6041cec915a85 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Tue, 24 Feb 2015 09:19:31 -0800 Subject: Create AUTH.md An overview auth document using c++ code exampoles. The code will be translated to other languages in subsequet pull requests. --- AUTH.md | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 AUTH.md diff --git a/AUTH.md b/AUTH.md new file mode 100644 index 0000000000..9850b8b24e --- /dev/null +++ b/AUTH.md @@ -0,0 +1,88 @@ +#gRPC Authentication support + +gRPC is designed to plug-in a number of authentication mechanisms. We provide an overview +of the various auth mechanisms supported, discuss the API and demonstrate usage through +code examples, and conclude with a discussion of extensibility. + +###SSL/TLS +gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the server, +and encrypt all the data exchanged between the client and the server. Optional +mechanisms are available for clients to provide certificates to accomplish mutual +authentication. + +###OAuth 2.0 +gRPC provides a generic mechanism (described below) to attach metadata to requests +and responses. This mechanism can be used to attach OAuth 2.0 Access Tokens to +RPCs being made at a client. Additional support for acquiring Access Tokens while +accessing Google APIs through gRPC is provided for certain auth flows, demonstrated +through code examples below. + +###API +To reduce complexity and minimize API clutter, gRPC works with a unified concept of +a Credentials object. Users construct gRPC credentials using corresponding bootstrap +credentials (e.g., SSL client certs or Service Account Keys), and use the +credentials while creating a gRPC channel to any server. Depending on the type of +credential supplied, the channel uses the credentials during the initial SSL/TLS +handshake with the server, or uses the credential to generate and attach Access +Tokens to each request being made on the channel. + +###Code Examples + +####SSL/TLS for server authentication and encryption +This is the simplest authentication scenario, where a client just wants to +authenticate the server and encrypt all data. + +``` +SslCredentialsOptions ssl_opts; // Options to override SSL params, empty by default +// Create the credentials object by providing service account key in constructor +std::unique_ptr creds = CredentialsFactory::SslCredentials(ssl_opts); +// Create a channel using the credentials created in the previous step +std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); +// Create a stub on the channel +std::unique_ptr stub(Greeter::NewStub(channel)); +// Make actual RPC calls on the stub. +grpc::Status s = stub->sayHello(&context, *request, response); +``` + +For advanced use cases such as modifying the root CA or using client certs, +the corresponding options can be set in the SslCredentialsOptions parameter +passed to the factory method. + + +###Authenticating with Google + +gRPC applications can use a simple API to create a credential that works in various deployment scenarios. + +``` +std::unique_ptr creds = CredentialsFactory::DefaultGoogleCredentials(); +// Create a channel, stub and make RPC calls (same as in the previous example) +std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); +std::unique_ptr stub(Greeter::NewStub(channel)); +grpc::Status s = stub->sayHello(&context, *request, response); +``` + +This credential works for applications using Service Accounts as well as for +applications running in Google Compute Engine (GCE). In the former case, the +service account’s private keys are expected in file located at [TODO: well +known file fath for service account keys] or in the file named in the environment +variable [TODO: add the env var name here]. The keys are used at run-time to +generate bearer tokens that are attached to each outgoing RPC on the +corresponding channel. + +For applications running in GCE, a default service account and corresponding +OAuth scopes can be configured during VM setup. At run-time, this credential +handles communication with the authentication systems to obtain OAuth2 access +tokens and attaches them to each outgoing RPC on the corresponding channel. +Extending gRPC to support other authentication mechanisms +The gRPC protocol is designed with a general mechanism for sending metadata +associated with RPC. Clients can send metadata at the beginning of an RPC and +servers can send back metadata at the beginning and end of the RPC. This +provides a natural mechanism to support OAuth2 and other authentication +mechanisms that need attach bearer tokens to individual request. + +In the simplest case, there is a single line of code required on the client +to add a specific token as metadata to an RPC and a corresponding access on +the server to retrieve this piece of metadata. The generation of the token +on the client side and its verification at the server can be done separately. + +A deeper integration can be achieved by plugging in a gRPC credentials implementation for any custom authentication mechanism that needs to attach per-request tokens. gRPC internals also allow switching out SSL/TLS with other encryption mechanisms. -- cgit v1.2.3 From fea9152c99566fd7ac8e471c63e0111efe455e01 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Tue, 24 Feb 2015 18:07:45 +0000 Subject: Finished client side --- cpp/cpptutorial.md | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index 8fa1b6df65..2c9eea68cc 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -134,7 +134,7 @@ class RouteGuideImpl final : public RouteGuide::Service { ... } ``` -In this case we're implementing the *synchronous* version of `RouteGuide`, where... It's also possible to implement an asynchronous interface, `RouteGuide::AsyncService`... +In this case we're implementing the *synchronous* version of `RouteGuide`, which provides our default gRPC server behaviour. It's also possible to implement an asynchronous interface, `RouteGuide::AsyncService`, which allows you to further customize your server's threading behaviour, though we won't look at this in this tutorial. `RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. @@ -261,6 +261,8 @@ Now we can use the channel to create our stub using the `NewStub` method provide ### Calling service methods +Now let's look at how we call our service methods. Note that in this tutorial we're calling the *blocking/synchronous* versions of each method: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception. + Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. ```cpp @@ -278,7 +280,7 @@ Calling the simple RPC `GetFeature` is nearly as straightforward as calling a lo } ``` -As you can see, you create and populate a request protocol buffer object (in our case `Point`), and create a response protocol buffer object for the server to fill in. You also create a `ClientContext` object for your call. Finally, you call the method on the stub, passing it the context, request, and response. If the method returns `OK`, then you can read your response information from the server from your response object. +As you can see, we create and populate a request protocol buffer object (in our case `Point`), and create a response protocol buffer object for the server to fill in. We also create a `ClientContext` object for our call - you can optionally set RPC configuration values on this object, such as deadlines, though for now we'll use the default settings. Note that you cannot reuse this object between calls. Finally, we call the method on the stub, passing it the context, request, and response. If the method returns `OK`, then we can read the response information from the server from our response object. ```cpp std::cout << "Found feature called " << feature->name() << " at " @@ -286,8 +288,62 @@ As you can see, you create and populate a request protocol buffer object (in our << feature->location().longitude()/kCoordFactor_ << std::endl; ``` -Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. +Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: + +```cpp + std::unique_ptr > reader( + stub_->ListFeatures(&context, rect)); + while (reader->Read(&feature)) { + std::cout << "Found feature called " + << feature.name() << " at " + << feature.location().latitude()/kCoordFactor_ << ", " + << feature.location().latitude()/kCoordFactor_ << std::endl; + } + Status status = reader->Finish(); +``` + +Instead of passing the method a context, request, and response, we pass it a context and request and get a `ClientReader` object back. The client can use the `ClientReader` to read the server's responses. We use the `ClientReader`s `Read()` method to repeatedly read in the server's responses to a response protocol buffer object (in this case a `Feature`) until there are no more messages: the client needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. Finally, we call `Finish()` on the stream to complete the call and get our RPC status. + +The client-side streaming method `RecordRoute` is similar, except there we pass the method a context and response object and get back a `ClientWriter`. + +```cpp + std::unique_ptr > writer( + stub_->RecordRoute(&context, &stats)); + for (int i = 0; i < kPoints; i++) { + const Feature& f = feature_list_[feature_distribution(generator)]; + std::cout << "Visiting point " + << f.location().latitude()/kCoordFactor_ << ", " + << f.location().longitude()/kCoordFactor_ << std::endl; + if (!writer->Write(f.location())) { + // Broken stream. + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds( + delay_distribution(generator))); + } + writer->WritesDone(); + Status status = writer->Finish(); + if (status.IsOk()) { + std::cout << "Finished trip with " << stats.point_count() << " points\n" + << "Passed " << stats.feature_count() << " features\n" + << "Travelled " << stats.distance() << " meters\n" + << "It took " << stats.elapsed_time() << " seconds" + << std::endl; + } else { + std::cout << "RecordRoute rpc failed." << std::endl; + } +``` + +Once we've finished writing our client's requests to the stream using `Write()`, we need to call `WritesDone()` on the stream to let gRPC know that we've finished writing, then `Finish()` to complete the call and get our RPC status. If the status is `OK`, our response object that we initially passed to `RecordRoute()` will be populated with the server's response. + +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. In this case, we just pass a context to the method and get back a `ClientReaderWriter`, which we can use to both write and read messages. + +```cpp + std::shared_ptr > stream( + stub_->RouteChat(&context)); +``` +The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. ## Try it out! -- cgit v1.2.3 From 88a49f65d05e51eeedb33341800fbe3576dff097 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Tue, 24 Feb 2015 18:09:38 +0000 Subject: Added a couple more headings --- cpp/cpptutorial.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index 2c9eea68cc..069ca4ea09 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -263,6 +263,8 @@ Now we can use the channel to create our stub using the `NewStub` method provide Now let's look at how we call our service methods. Note that in this tutorial we're calling the *blocking/synchronous* versions of each method: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception. +#### Simple RPC + Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. ```cpp @@ -288,6 +290,8 @@ As you can see, we create and populate a request protocol buffer object (in our << feature->location().longitude()/kCoordFactor_ << std::endl; ``` +#### Streaming RPCs + Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: ```cpp -- cgit v1.2.3 From f0db7b70f39c3c61d258c610704680177997041a Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Tue, 24 Feb 2015 18:10:40 +0000 Subject: Fixed typo --- cpp/cpptutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index 069ca4ea09..af6b6b1a65 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -236,7 +236,7 @@ _[is there no equivalent of the Stubby4 wait() method, ie do you have to do the ## Creating the client -In this section, we'll look at creating a C++ client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/cpp/route_guide/route_guide_client.cc]((https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_client.cc). +In this section, we'll look at creating a C++ client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/cpp/route_guide/route_guide_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_client.cc). ### Creating a stub -- cgit v1.2.3 From d475445b1b192aae2d1d1ee279b76f38e5946e65 Mon Sep 17 00:00:00 2001 From: Jayant Kolhe Date: Tue, 24 Feb 2015 11:02:23 -0800 Subject: Rename AUTH.md to grpc-auth-support.md --- AUTH.md | 88 ---------------------------------------------------- grpc-auth-support.md | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 88 deletions(-) delete mode 100644 AUTH.md create mode 100644 grpc-auth-support.md diff --git a/AUTH.md b/AUTH.md deleted file mode 100644 index 9850b8b24e..0000000000 --- a/AUTH.md +++ /dev/null @@ -1,88 +0,0 @@ -#gRPC Authentication support - -gRPC is designed to plug-in a number of authentication mechanisms. We provide an overview -of the various auth mechanisms supported, discuss the API and demonstrate usage through -code examples, and conclude with a discussion of extensibility. - -###SSL/TLS -gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the server, -and encrypt all the data exchanged between the client and the server. Optional -mechanisms are available for clients to provide certificates to accomplish mutual -authentication. - -###OAuth 2.0 -gRPC provides a generic mechanism (described below) to attach metadata to requests -and responses. This mechanism can be used to attach OAuth 2.0 Access Tokens to -RPCs being made at a client. Additional support for acquiring Access Tokens while -accessing Google APIs through gRPC is provided for certain auth flows, demonstrated -through code examples below. - -###API -To reduce complexity and minimize API clutter, gRPC works with a unified concept of -a Credentials object. Users construct gRPC credentials using corresponding bootstrap -credentials (e.g., SSL client certs or Service Account Keys), and use the -credentials while creating a gRPC channel to any server. Depending on the type of -credential supplied, the channel uses the credentials during the initial SSL/TLS -handshake with the server, or uses the credential to generate and attach Access -Tokens to each request being made on the channel. - -###Code Examples - -####SSL/TLS for server authentication and encryption -This is the simplest authentication scenario, where a client just wants to -authenticate the server and encrypt all data. - -``` -SslCredentialsOptions ssl_opts; // Options to override SSL params, empty by default -// Create the credentials object by providing service account key in constructor -std::unique_ptr creds = CredentialsFactory::SslCredentials(ssl_opts); -// Create a channel using the credentials created in the previous step -std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); -// Create a stub on the channel -std::unique_ptr stub(Greeter::NewStub(channel)); -// Make actual RPC calls on the stub. -grpc::Status s = stub->sayHello(&context, *request, response); -``` - -For advanced use cases such as modifying the root CA or using client certs, -the corresponding options can be set in the SslCredentialsOptions parameter -passed to the factory method. - - -###Authenticating with Google - -gRPC applications can use a simple API to create a credential that works in various deployment scenarios. - -``` -std::unique_ptr creds = CredentialsFactory::DefaultGoogleCredentials(); -// Create a channel, stub and make RPC calls (same as in the previous example) -std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); -std::unique_ptr stub(Greeter::NewStub(channel)); -grpc::Status s = stub->sayHello(&context, *request, response); -``` - -This credential works for applications using Service Accounts as well as for -applications running in Google Compute Engine (GCE). In the former case, the -service account’s private keys are expected in file located at [TODO: well -known file fath for service account keys] or in the file named in the environment -variable [TODO: add the env var name here]. The keys are used at run-time to -generate bearer tokens that are attached to each outgoing RPC on the -corresponding channel. - -For applications running in GCE, a default service account and corresponding -OAuth scopes can be configured during VM setup. At run-time, this credential -handles communication with the authentication systems to obtain OAuth2 access -tokens and attaches them to each outgoing RPC on the corresponding channel. -Extending gRPC to support other authentication mechanisms -The gRPC protocol is designed with a general mechanism for sending metadata -associated with RPC. Clients can send metadata at the beginning of an RPC and -servers can send back metadata at the beginning and end of the RPC. This -provides a natural mechanism to support OAuth2 and other authentication -mechanisms that need attach bearer tokens to individual request. - -In the simplest case, there is a single line of code required on the client -to add a specific token as metadata to an RPC and a corresponding access on -the server to retrieve this piece of metadata. The generation of the token -on the client side and its verification at the server can be done separately. - -A deeper integration can be achieved by plugging in a gRPC credentials implementation for any custom authentication mechanism that needs to attach per-request tokens. gRPC internals also allow switching out SSL/TLS with other encryption mechanisms. diff --git a/grpc-auth-support.md b/grpc-auth-support.md new file mode 100644 index 0000000000..9850b8b24e --- /dev/null +++ b/grpc-auth-support.md @@ -0,0 +1,88 @@ +#gRPC Authentication support + +gRPC is designed to plug-in a number of authentication mechanisms. We provide an overview +of the various auth mechanisms supported, discuss the API and demonstrate usage through +code examples, and conclude with a discussion of extensibility. + +###SSL/TLS +gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the server, +and encrypt all the data exchanged between the client and the server. Optional +mechanisms are available for clients to provide certificates to accomplish mutual +authentication. + +###OAuth 2.0 +gRPC provides a generic mechanism (described below) to attach metadata to requests +and responses. This mechanism can be used to attach OAuth 2.0 Access Tokens to +RPCs being made at a client. Additional support for acquiring Access Tokens while +accessing Google APIs through gRPC is provided for certain auth flows, demonstrated +through code examples below. + +###API +To reduce complexity and minimize API clutter, gRPC works with a unified concept of +a Credentials object. Users construct gRPC credentials using corresponding bootstrap +credentials (e.g., SSL client certs or Service Account Keys), and use the +credentials while creating a gRPC channel to any server. Depending on the type of +credential supplied, the channel uses the credentials during the initial SSL/TLS +handshake with the server, or uses the credential to generate and attach Access +Tokens to each request being made on the channel. + +###Code Examples + +####SSL/TLS for server authentication and encryption +This is the simplest authentication scenario, where a client just wants to +authenticate the server and encrypt all data. + +``` +SslCredentialsOptions ssl_opts; // Options to override SSL params, empty by default +// Create the credentials object by providing service account key in constructor +std::unique_ptr creds = CredentialsFactory::SslCredentials(ssl_opts); +// Create a channel using the credentials created in the previous step +std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); +// Create a stub on the channel +std::unique_ptr stub(Greeter::NewStub(channel)); +// Make actual RPC calls on the stub. +grpc::Status s = stub->sayHello(&context, *request, response); +``` + +For advanced use cases such as modifying the root CA or using client certs, +the corresponding options can be set in the SslCredentialsOptions parameter +passed to the factory method. + + +###Authenticating with Google + +gRPC applications can use a simple API to create a credential that works in various deployment scenarios. + +``` +std::unique_ptr creds = CredentialsFactory::DefaultGoogleCredentials(); +// Create a channel, stub and make RPC calls (same as in the previous example) +std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); +std::unique_ptr stub(Greeter::NewStub(channel)); +grpc::Status s = stub->sayHello(&context, *request, response); +``` + +This credential works for applications using Service Accounts as well as for +applications running in Google Compute Engine (GCE). In the former case, the +service account’s private keys are expected in file located at [TODO: well +known file fath for service account keys] or in the file named in the environment +variable [TODO: add the env var name here]. The keys are used at run-time to +generate bearer tokens that are attached to each outgoing RPC on the +corresponding channel. + +For applications running in GCE, a default service account and corresponding +OAuth scopes can be configured during VM setup. At run-time, this credential +handles communication with the authentication systems to obtain OAuth2 access +tokens and attaches them to each outgoing RPC on the corresponding channel. +Extending gRPC to support other authentication mechanisms +The gRPC protocol is designed with a general mechanism for sending metadata +associated with RPC. Clients can send metadata at the beginning of an RPC and +servers can send back metadata at the beginning and end of the RPC. This +provides a natural mechanism to support OAuth2 and other authentication +mechanisms that need attach bearer tokens to individual request. + +In the simplest case, there is a single line of code required on the client +to add a specific token as metadata to an RPC and a corresponding access on +the server to retrieve this piece of metadata. The generation of the token +on the client side and its verification at the server can be done separately. + +A deeper integration can be achieved by plugging in a gRPC credentials implementation for any custom authentication mechanism that needs to attach per-request tokens. gRPC internals also allow switching out SSL/TLS with other encryption mechanisms. -- cgit v1.2.3 From 4a8feaac4cc48be2cfcda99a5ec9eea5736ea58d Mon Sep 17 00:00:00 2001 From: Dan Ciruli Date: Tue, 24 Feb 2015 11:52:49 -0800 Subject: Adding grpc org to path In the instructions, adding grpc to the path for the github project. --- go/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/README.md b/go/README.md index bf5d6c8cf4..9fc49474d7 100644 --- a/go/README.md +++ b/go/README.md @@ -16,8 +16,8 @@ INSTALL ------- ```sh -$ go get -u github.com/grpc-common/go/greeter_client -$ go get -u github.com/grpc-common/go/greeter_server +$ go get -u github.com/grpc/grpc-common/go/greeter_client +$ go get -u github.com/grpc/grpc-common/go/greeter_server ``` TRY IT! -- cgit v1.2.3 From cd3379fbeb80bd9741eda750ecbd2cc2e1474d23 Mon Sep 17 00:00:00 2001 From: Dan Ciruli Date: Tue, 24 Feb 2015 11:56:02 -0800 Subject: Fixing path for pb import Was missing grpc in the path --- go/greeter_client/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/greeter_client/main.go b/go/greeter_client/main.go index 3398040d7e..065ae852bc 100644 --- a/go/greeter_client/main.go +++ b/go/greeter_client/main.go @@ -37,7 +37,7 @@ import ( "log" "os" - pb "github.com/grpc-common/go/helloworld" + pb "github.com/grpc/grpc-common/go/helloworld" "golang.org/x/net/context" "google.golang.org/grpc" ) -- cgit v1.2.3 From 3054eba891802f7c48de16240ac1296fb1411e44 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Tue, 24 Feb 2015 14:36:18 -0800 Subject: Fix readme --- cpp/README.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/cpp/README.md b/cpp/README.md index fe9b71620e..ac4dea9b7f 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -35,7 +35,7 @@ $ make helloworld.pb.cc Which internally invokes the proto-compiler as: ```sh -$protoc -I ../../protos/ --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto ``` ### Client and server implementations @@ -45,8 +45,18 @@ The client implementation is at [greeter_client.cc](https://github.com/grpc/grpc The server implementation is at [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). ### Try it! - -###TODO: instructions to run server and client +Build client and server: +```sh +$ make +``` +Run the server: +```sh +$ ./greeter_server +``` +Run the client: +```sh +$ ./greeter_client +``` ## Tutorial -- cgit v1.2.3 From ecee424a879d0e56e7bd7115a7015beafe09c4e6 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Tue, 24 Feb 2015 14:46:53 -0800 Subject: Add output piece. --- cpp/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/README.md b/cpp/README.md index ac4dea9b7f..078021d876 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -53,10 +53,11 @@ Run the server: ```sh $ ./greeter_server ``` -Run the client: +Run the client (in a different terminal): ```sh $ ./greeter_client ``` +If things go smoothly, you will see the "Greeter received: Hello world" in the client side output. ## Tutorial -- cgit v1.2.3 From 84c263fd720090c1b5018068caf4c61f40cb0605 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Tue, 24 Feb 2015 14:47:47 -0800 Subject: Add port info. --- cpp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/README.md b/cpp/README.md index 078021d876..759e10bfe1 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -49,7 +49,7 @@ Build client and server: ```sh $ make ``` -Run the server: +Run the server, which will listen on port 50051: ```sh $ ./greeter_server ``` -- cgit v1.2.3 From cdbb60c7b6dc1c64745e1ce0b0905f3a876a9a1b Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Tue, 24 Feb 2015 15:01:36 -0800 Subject: Add missing protoc command --- cpp/cpptutorial.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index af6b6b1a65..338e1e7d5a 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -101,7 +101,9 @@ $ make route_guide.pb.cc which actually runs: -[actual command] +```shell +$ protoc -I ../../protos --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ../../protos/route_guide.proto +``` Running this command generates the following files: - `route_guide.pb.h`, the header which declares your generated classes -- cgit v1.2.3 From e1ea962f0a34d1d1d85e77de7536102d5b237bf2 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Tue, 24 Feb 2015 15:09:26 -0800 Subject: Fix broken link --- cpp/cpptutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index 338e1e7d5a..cd712fe3c5 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -20,7 +20,7 @@ With gRPC we can define our service once in a .proto file and implement clients ## Example code and setup -The example code for our tutorial is in [grpc/grpc-common/cpp/route_guide](https://github.com/grpc/grpc-common/cpp/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +The example code for our tutorial is in [grpc/grpc-common/cpp/route_guide](https://github.com/grpc/grpc-common/tree/master/cpp/route_guide). To download the example, clone the `grpc-common` repository by running the following command: ```shell $ git clone https://github.com/google/grpc-common.git ``` -- cgit v1.2.3 From de0c653ed5b8d639aa1436d9e55ccf88cbd240af Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Tue, 24 Feb 2015 15:52:22 -0800 Subject: various fixes --- cpp/cpptutorial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index cd712fe3c5..b13dff175e 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -49,7 +49,7 @@ Then you define `rpc` methods inside your service definition, specifying their r - A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. ``` - // Obtains the feature at a given position. + // Obtains the feature at a given position. rpc GetFeature(Point) returns (Feature) {} ``` @@ -125,7 +125,7 @@ There are two parts to making our `RouteGuide` service do its job: - Implementing the service interface generated from our service definition: doing the actual "work" of our service. - Running a gRPC server to listen for requests from clients and return the service responses. -You can find our example `RouteGuide` server in [grpc-common/cpp/route_guide/route_guide_server.cc]((https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_server.cc). Let's take a closer look at how it works. +You can find our example `RouteGuide` server in [grpc-common/cpp/route_guide/route_guide_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_server.cc). Let's take a closer look at how it works. ### Implementing RouteGuide -- cgit v1.2.3 From 633625525ad7302c107cd23a21e1460ddf0e94bb Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 15:56:44 -0800 Subject: Update the Maven link --- java/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/README.md b/java/README.md index 35c9db3192..4410f830f6 100644 --- a/java/README.md +++ b/java/README.md @@ -6,7 +6,7 @@ PREREQUISITES - [Java 8](http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html) -- [Maven 3.2](http://maven.apache.org/users/index.html). +- [Maven 3.2 or later](http://maven.apache.org/download.cgi). - this is needed to install Netty5, a dependency of gRPC, and to build this sample - [Latest version of google-protobuf](https://github.com/google/protobuf/tree/master/java) -- cgit v1.2.3 From 6b99bc5b7f73e2c590cce4e8b53cf8bc1fee796d Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 15:57:30 -0800 Subject: Remove superfluous link to protobuf install --- java/README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/java/README.md b/java/README.md index 4410f830f6..89724904d4 100644 --- a/java/README.md +++ b/java/README.md @@ -9,11 +9,6 @@ PREREQUISITES - [Maven 3.2 or later](http://maven.apache.org/download.cgi). - this is needed to install Netty5, a dependency of gRPC, and to build this sample -- [Latest version of google-protobuf](https://github.com/google/protobuf/tree/master/java) - - to generate java code from proto files - - to install the base Java proto3 library - - INSTALL ------- -- cgit v1.2.3 From 2b4be223d3455c250b5618b14d9637eeaa98eb0a Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Tue, 24 Feb 2015 15:59:43 -0800 Subject: Change to server.Wait() --- cpp/helloworld/greeter_server.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cpp/helloworld/greeter_server.cc b/cpp/helloworld/greeter_server.cc index 01a0bf242d..e3dd36b0ed 100644 --- a/cpp/helloworld/greeter_server.cc +++ b/cpp/helloworld/greeter_server.cc @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -69,9 +68,7 @@ void RunServer() { builder.RegisterService(&service); std::unique_ptr server(builder.BuildAndStart()); std::cout << "Server listening on " << server_address << std::endl; - while (true) { - std::this_thread::sleep_for(std::chrono::seconds(5)); - } + server->Wait(); } int main(int argc, char** argv) { -- cgit v1.2.3 From 50bc9a77f878a682e687e75511c9cfe4d7eb30c7 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Tue, 24 Feb 2015 16:02:59 -0800 Subject: Change to server.Wait() api. --- cpp/route_guide/route_guide_server.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cpp/route_guide/route_guide_server.cc b/cpp/route_guide/route_guide_server.cc index 2699330e4c..d0a2ecd5d4 100644 --- a/cpp/route_guide/route_guide_server.cc +++ b/cpp/route_guide/route_guide_server.cc @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -191,9 +190,7 @@ void RunServer(const std::string& db_path) { builder.RegisterService(&service); std::unique_ptr server(builder.BuildAndStart()); std::cout << "Server listening on " << server_address << std::endl; - while (true) { - std::this_thread::sleep_for(std::chrono::seconds(5)); - } + server->Wait(); } int main(int argc, char** argv) { -- cgit v1.2.3 From 44e9822568e906abfe1a587681ea5e9c83c7074f Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Tue, 24 Feb 2015 16:06:02 -0800 Subject: Change code and text in text too --- cpp/cpptutorial.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index b13dff175e..144b902519 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -220,9 +220,7 @@ void RunServer(const std::string& db_path) { builder.RegisterService(&service); std::unique_ptr server(builder.BuildAndStart()); std::cout << "Server listening on " << server_address << std::endl; - while (true) { - std::this_thread::sleep_for(std::chrono::seconds(5)); - } + server->Wait(); } ``` As you can see, we build and start our server using a `ServerBuilder`. To do this, we: @@ -232,8 +230,7 @@ As you can see, we build and start our server using a `ServerBuilder`. To do thi 3. Specify the address and port we want to use to listen for client requests using the builder's `AddPort()` method. 4. Register our service implementation with the builder. 5. Call `BuildAndStart()` on the builder to create and start an RPC server for our service. - -_[is there no equivalent of the Stubby4 wait() method, ie do you have to do the while(true) loop to keep the server running?]_ +5. Call `Wait()` on the server to do a blocking wait until process is killed or `Shutdown()` is called. ## Creating the client -- cgit v1.2.3 From 9a2ff4f376da3564f197df8b5704e1dda3799468 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Tue, 24 Feb 2015 16:13:02 -0800 Subject: Add build and run section --- cpp/cpptutorial.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index 144b902519..613af1ae7c 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -350,7 +350,16 @@ The syntax for reading and writing here is exactly the same as for our client-st ## Try it out! -_[need build and run instructions here]_ - - +Build client and server: +```shell +$ make +``` +Run the server, which will listen on port 50051: +```shell +$ ./route_guide_server +``` +Run the client (in a different terminal): +```shell +$ ./route_guide_client +``` -- cgit v1.2.3 From 507a2410f1071a529ea4883f7f6b193043b08d5e Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 17:22:37 -0800 Subject: Fixes more go package references --- go/greeter_client/main.go | 2 +- go/greeter_server/main.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go/greeter_client/main.go b/go/greeter_client/main.go index abe33c0e2a..0ca5a00035 100644 --- a/go/greeter_client/main.go +++ b/go/greeter_client/main.go @@ -37,7 +37,7 @@ import ( "log" "os" - pb "github.com/grpc-common/go/helloworld" + pb "github.com/grpc/grpc-common/go/helloworld" "golang.org/x/net/context" "google.golang.org/grpc" ) diff --git a/go/greeter_server/main.go b/go/greeter_server/main.go index 231f5c607b..c7fa06ad18 100644 --- a/go/greeter_server/main.go +++ b/go/greeter_server/main.go @@ -37,7 +37,7 @@ import ( "log" "net" - pb "github.com/grpc-common/go/helloworld" + pb "github.com/grpc/grpc-common/go/helloworld" "golang.org/x/net/context" "google.golang.org/grpc" ) -- cgit v1.2.3 From cec80edc6cda25ef870f64a67d774f7f6688fe2f Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Tue, 24 Feb 2015 23:45:00 -0800 Subject: fix link to Gemfile --- ruby/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/README.md b/ruby/README.md index 1fc19a4f24..4afea611a4 100644 --- a/ruby/README.md +++ b/ruby/README.md @@ -11,7 +11,7 @@ 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 the full gRPC distribution from source on your local machine and update path: in [Gemfile] to refer src/ruby within it. +- *Temporary* Install the full gRPC distribution from source on your local machine and update path: in [Gemfile](https://github.com/grpc/grpc-common/blob/master/ruby/Gemfile) to refer src/ruby within it. - this is necessary until the gRPC ruby gem is published - Use bundler to install ```sh -- cgit v1.2.3 From 78c9e77a4adeff309ad1380aa2c9bf892889b53f Mon Sep 17 00:00:00 2001 From: LisaFC Date: Wed, 25 Feb 2015 11:37:36 +0000 Subject: mentioned that we have (some) tutorials --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index acea9289a7..4c9fc90903 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,11 @@ Welcome to the developer documentation for gRPC, a language-neutral, platform-neutral remote procedure call (RPC) system developed at Google. This document introduces you to gRPC with a quick overview and a simple -Hello World example. More documentation is coming soon! +Hello World example. You'll find more tutorials and reference docs in this repository - more documentation is coming soon! + ## Quick start -You can find quick start guides for each language, including installation instructions and examples here: +You can find quick start guides for each language, including installation instructions, examples, and tutorials here: * [C++](https://github.com/grpc/grpc-common/tree/master/cpp) * [Java](https://github.com/grpc/grpc-common/tree/master/java) * [Python](https://github.com/grpc/grpc-common/tree/master/python) @@ -98,8 +99,8 @@ than how to install and run a few git commands. This is an introductory example rather than a comprehensive tutorial, so don't worry if you're not a Go or Java developer - the concepts are similar for all languages, and you can -find more implementations of our Hello World example in other languages in -the language-specific folders in this repository. Complete tutorials and +find more implementations of our Hello World example in other languages (and full tutorials where available) in +the [language-specific folders](#quickstart) in this repository. Complete tutorials and reference documentation for all gRPC languages are coming soon. -- cgit v1.2.3 From b756da3bfd4612f915ea1c1aa57354c06d6547e6 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Wed, 25 Feb 2015 11:42:43 +0000 Subject: Update cpptutorial.md --- cpp/cpptutorial.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index 613af1ae7c..65fd5c7eec 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -16,8 +16,6 @@ Our example is a simple route mapping application that lets clients get informat With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. -[possibly insert more advantages here] - ## Example code and setup The example code for our tutorial is in [grpc/grpc-common/cpp/route_guide](https://github.com/grpc/grpc-common/tree/master/cpp/route_guide). To download the example, clone the `grpc-common` repository by running the following command: -- cgit v1.2.3 From 5b5e146d4d132170cb85a077ff7b35654fca9cea Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 25 Feb 2015 04:18:56 -0800 Subject: Update README.md --- ruby/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ruby/README.md b/ruby/README.md index 1fc19a4f24..b386a9b925 100644 --- a/ruby/README.md +++ b/ruby/README.md @@ -6,6 +6,16 @@ PREREQUISITES This requires Ruby 2.1, as the gRPC API surface uses keyword args. +If you don't have that installed locally, you can use [RVM](https://www.rvm.io/) to use Ruby 2.1 for testing without upgrading the version of Ruby on your whole system. +```sh +$ command curl -sSL https://rvm.io/mpapis.asc | gpg --import - +$ \curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2.1 +$ +$ # follow the instructions to ensure that your're using the latest stable version of Ruby +$ # and that the rvm command is installed +``` +- Make sure your run `source $HOME/.rvm/scripts/rvm` as instructed to complete the set up of RVM + INSTALL ------- -- cgit v1.2.3 From 25ffbd86db8a07fc9a7ffd538288f1f46af08a53 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Wed, 25 Feb 2015 14:12:39 +0000 Subject: Update cpptutorial.md --- cpp/cpptutorial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md index 65fd5c7eec..d176240626 100644 --- a/cpp/cpptutorial.md +++ b/cpp/cpptutorial.md @@ -28,7 +28,7 @@ Then change your current directory to `grpc-common/cpp/route_guide`: $ cd grpc-common/cpp/route_guide ``` -Although we've provided the complete example so you don't need to generate the gRPC code yourself, if you want to try generating your own server and client interface code you can follow the setup instructions in [the C++ quick start guide](https://github.com/grpc/grpc-common/tree/master/cpp). +You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the C++ quick start guide](https://github.com/grpc/grpc-common/tree/master/cpp). ## Defining the service @@ -103,7 +103,7 @@ which actually runs: $ protoc -I ../../protos --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ../../protos/route_guide.proto ``` -Running this command generates the following files: +Running this command generates the following files in your current directory: - `route_guide.pb.h`, the header which declares your generated classes - `route_guide.pb.cc`, which contains the implementation of your classes -- cgit v1.2.3 From e7e5b55e2296eddbfe492d37c6e230a287020d52 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 25 Feb 2015 07:10:01 -0800 Subject: Update grpc-auth-support.md --- grpc-auth-support.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/grpc-auth-support.md b/grpc-auth-support.md index 9850b8b24e..5aa526af45 100644 --- a/grpc-auth-support.md +++ b/grpc-auth-support.md @@ -86,3 +86,34 @@ the server to retrieve this piece of metadata. The generation of the token on the client side and its verification at the server can be done separately. A deeper integration can be achieved by plugging in a gRPC credentials implementation for any custom authentication mechanism that needs to attach per-request tokens. gRPC internals also allow switching out SSL/TLS with other encryption mechanisms. + +These authentication mechanisms will be available in all gRPC's supported languages. +The following sections demonstrate how authentication and authorization features described above appear in each language + +####SSL/TLS for server authentication and encryption (Ruby) +```ruby +# Base case - No encryption +stub = Helloworld::Greeter::Stub.new('localhost:50051') +... + +# With server authentication SSL/TLS +creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file +stub = Helloworld::Greeter::Stub.new('localhost:50051', creds: creds) +``` + +###Authenticating with Google (Ruby) +```ruby +# Base case - No encryption/authorization +stub = Helloworld::Greeter::Stub.new('localhost:50051') +... + +# Authenticating with Google +require 'googleauth' # from [googleauth](http://www.rubydoc.info/gems/googleauth/0.1.0) +... +creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file +scope = 'https://www.googleapis.com/auth/grpc-testing' +authorization = Google::Auth.get_application_default(scope) +stub = Helloworld::Greeter::Stub.new('localhost:50051', + creds: creds, + update_metadata: authorization.updater_proc) +``` -- cgit v1.2.3 From 43a0eb0a993305467a4ea58112c1f14c1c3923cc Mon Sep 17 00:00:00 2001 From: LisaFC Date: Wed, 25 Feb 2015 17:27:56 +0000 Subject: Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4c9fc90903..77ac47a515 100644 --- a/README.md +++ b/README.md @@ -320,6 +320,7 @@ As you can see, the class `GreeterImpl` implements the interface } ``` - `hello` takes two parameters: + -`Helloworld.HelloRequest`: the request -`StreamObserver`: a response observer, which is a special interface for the server to call with its response -- cgit v1.2.3 From a25a42b4b711d6eb97383947b243f215342139b5 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Wed, 25 Feb 2015 17:28:30 +0000 Subject: Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 77ac47a515..c58dca9a2b 100644 --- a/README.md +++ b/README.md @@ -320,9 +320,8 @@ As you can see, the class `GreeterImpl` implements the interface } ``` - `hello` takes two parameters: - - -`Helloworld.HelloRequest`: the request - -`StreamObserver`: a response observer, which is + - `Helloworld.HelloRequest`: the request + - `StreamObserver`: a response observer, which is a special interface for the server to call with its response To return our response to the client and complete the call: -- cgit v1.2.3 From 133b4b3b023fddc11b75f6d26e305d9441bcacc6 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Wed, 25 Feb 2015 18:46:17 +0000 Subject: New shiny Java tutorial --- java/javatutorial.md | 351 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 351 insertions(+) create mode 100644 java/javatutorial.md diff --git a/java/javatutorial.md b/java/javatutorial.md new file mode 100644 index 0000000000..4c419cf345 --- /dev/null +++ b/java/javatutorial.md @@ -0,0 +1,351 @@ +#gRPC Basics: Java + +This tutorial provides a basic Java programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate server and client code using the protocol buffer compiler. +- Use the Java gRPC API to write a simple client and server for your service. + +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. + +This isn't a comprehensive guide to using gRPC in Java: more reference documentation is coming soon. + +## Why use gRPC? + +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-java/examples/src/main/java/io/grpc/examples](https://github.com/grpc/grpc-java/tree/master/examples/src/main/java/io/grpc/examples). To download the example, clone the `grpc-java` repository by running the following command: +```shell +$ git clone https://github.com/google/grpc-java.git +``` + +Then change your current directory to `grpc-java/examples`: +```shell +$ cd grpc-java/examples +``` + +You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Java quick start guide](https://github.com/grpc/grpc-common/tree/master/java). + + +## Defining the service + +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-java/examples/src/main/proto/route_guide.proto`](https://github.com/grpc/grpc-java/blob/master/examples/src/main/proto/route_guide.proto). + +As we're generating Java code in this example, we've specified a `java_package` file option in our .proto: +``` +option java_package = "io.grpc.examples"; +``` + +This specifies the package we want to use for our generated Java classes. If no explicit `java_package` option is given in the .proto file, then by default the proto package (specified using the "package" keyword) will be used. However, proto packages generally do not make good Java packages since proto packages are not expected to start with reverse domain names. If we generate code in another language from this .proto, the `java_package` option has no effect. + +To define a service, we specify a named `service` in the .proto file: + +``` +service RouteGuide { + ... +} +``` + +Then we define `rpc` methods inside our service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +``` + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. +``` + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} +``` + +- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. +``` + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +``` + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +``` +// 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; +} +``` + + +## Generating client and server code + +Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC Java plugin. + +For simplicity, we've provided a [Gradle build file](https://github.com/grpc/grpc-java/blob/master/examples/build.gradle) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](https://github.com/grpc/grpc-java) first): + +```shell +gradle build +``` + +which actually runs: + +[actual command] + +Running this command generates the following files: +- `RouteGuideOuterClass.java` [cheeeeeeck], which contains all the protocol buffer code to populate, serialize, and retrieve our request and response message types +- `RouteGuideGrpc.java` which contains (along with some other useful code): + - an interface for `RouteGuide` servers to implement, `RouteGuideGrpc.Service`, with all the methods defined in the `RouteGuide` service. + - *stub* classes that clients can use to talk to a `RouteGuide` server. These also implement the `RouteGuide` interface. + + + +## Creating the server + +First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). + +There are two parts to making our `RouteGuide` service do its job: +- Implementing the service interface generated from our service definition: doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and return the service responses. + +You can find our example `RouteGuide` server in [grpc-java/examples/src/main/java/io/grpc/examples/RouteGuideServer.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/RouteGuideServer.java). Let's take a closer look at how it works. + +### Implementing RouteGuide + +As you can see, our server has a `RouteGuideService` class that implements the generated `RouteGuideGrpc.Service` interface: + +```java +private static class RouteGuideService implements RouteGuideGrpc.RouteGuide { +... +} +``` + +`RouteGuideService` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. + +```java + @Override + public void getFeature(Point request, StreamObserver responseObserver) { + responseObserver.onValue(getFeature(request)); + responseObserver.onCompleted(); + } + +... + + private Feature getFeature(Point location) { + for (Feature feature : features) { + if (feature.getLocation().getLatitude() == location.getLatitude() + && feature.getLocation().getLongitude() == location.getLongitude()) { + return feature; + } + } + + // No feature was found, return an unnamed feature. + return Feature.newBuilder().setName("").setLocation(location).build(); + } +``` + +`getFeature()` takes two parameters: +- `Point`: the request +- `StreamObserver`: a response observer, which is a special interface for the server to call with its response. + +To return our response to the client and complete the call: + +1. We construct and populate a `Feature` response object to return to the client, as specified in our service definition. In this example, we do this in a separate private `getFeature()` method. +2. We use the response observer's `onValue()` method to return the `Feature`. +3. We use the response observer's `onCompleted()` method to specify that we've finished dealing with the RPC. + +Next let's look at a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. + +```java +private final Collection features; + +... + + @Override + public void listFeatures(Rectangle request, StreamObserver responseObserver) { + int left = min(request.getLo().getLongitude(), request.getHi().getLongitude()); + int right = max(request.getLo().getLongitude(), request.getHi().getLongitude()); + int top = max(request.getLo().getLatitude(), request.getHi().getLatitude()); + int bottom = min(request.getLo().getLatitude(), request.getHi().getLatitude()); + + for (Feature feature : features) { + if (!RouteGuideUtil.exists(feature)) { + continue; + } + + int lat = feature.getLocation().getLatitude(); + int lon = feature.getLocation().getLongitude(); + if (lon >= left && lon <= right && lat >= bottom && lat <= top) { + responseObserver.onValue(feature); + } + } + responseObserver.onCompleted(); + } +``` + +Like the simple RPC, this method gets a request object (the `Rectangle` in which our client wants to find `Feature`s) and a `StreamObserver` response observer. + +This time, we get as many `Feature` objects as we need to return to the client (in this case, we select them from the service's feature collection based on whether they're inside our request `Rectangle`), and write them each in turn to the response observer using its `Write()` method. Finally, as in our simple RPC, we use the response observer's `onCompleted()` method to tell gRPC that we've finished writing responses. + +Now let's look at something a little more complicated: the client-side streaming method `RecordRoute`, where we get a stream of `Point`s from the client and return a single `RouteSummary` with information about their trip. + +```java + @Override + public StreamObserver recordRoute(final StreamObserver responseObserver) { + return new StreamObserver() { + int pointCount; + int featureCount; + int distance; + Point previous; + long startTime = System.nanoTime(); + + @Override + public void onValue(Point point) { + pointCount++; + if (RouteGuideUtil.exists(getFeature(point))) { + featureCount++; + } + // For each point after the first, add the incremental distance from the previous point to + // the total distance value. + if (previous != null) { + distance += calcDistance(previous, point); + } + previous = point; + } + + @Override + public void onError(Throwable t) { + logger.log(Level.WARNING, "Encountered error in recordRoute", t); + } + + @Override + public void onCompleted() { + long seconds = NANOSECONDS.toSeconds(System.nanoTime() - startTime); + responseObserver.onValue(RouteSummary.newBuilder().setPointCount(pointCount) + .setFeatureCount(featureCount).setDistance(distance) + .setElapsedTime((int) seconds).build()); + responseObserver.onCompleted(); + } + }; + } +``` + +As you can see, like the previous method types our method gets a `StreamObserver` response observer parameter, but this time it returns a `StreamObserver` for the client to write its `Point`s. + +In the method body we instantiate an anonymous `StreamObserver` to return, in which we: +- Override the `onValue()` method to get features and other information each time the client writes a `Point` to the message stream. +- Override the `onCompleted()' method (called when the *client* has finished writing messages) to populate and build our `RouteSummary`. We then call our method's own response observer's `onValue()` with our `RouteSummary`, and then call its `onCompleted()` method to finish the call from the server side. + +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. + +```cpp + @Override + public StreamObserver routeChat(final StreamObserver responseObserver) { + return new StreamObserver() { + @Override + public void onValue(RouteNote note) { + List notes = getOrCreateNotes(note.getLocation()); + + // Respond with all previous notes at this location. + for (RouteNote prevNote : notes.toArray(new RouteNote[0])) { + responseObserver.onValue(prevNote); + } + + // Now add the new note to the list + notes.add(note); + } + + @Override + public void onError(Throwable t) { + logger.log(Level.WARNING, "Encountered error in routeChat", t); + } + + @Override + public void onCompleted() { + responseObserver.onCompleted(); + } + }; + } +``` + +As with our client-side streaming example, we both get and return a `StreamObserver` response observer, except this time we return values via our method's response observer while the client is still writing messages to *their* message stream. The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + +### Starting the server + +Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: + +```java + public void start() { + gRpcServer = NettyServerBuilder.forPort(port) + .addService(RouteGuideGrpc.bindService(new RouteGuideService(features))) + .build().start(); + logger.info("Server started, listening on " + port); + ... + } +``` +As you can see, we build and start our server using a `NettyServerBuilder`. To do this, we: + +1. Create an instance of our service implementation class `RouteGuideService` and pass it to the generated `RouteGuideGrpc` class's static `bindService()` method to get a service definition. +3. Specify the address and port we want to use to listen for client requests using the builder's `forPort()` method. +4. Register our service implementation with the builder by passing the service definition returned from `bindService()` to the builder's `addService()` method. +5. Call `build()` and `start()` on the builder to create and start an RPC server for our service. + + +## Creating the client + +In this section, we'll look at creating a Java client for our `RouteGuide` service. You can see our complete example client code in [grpc-java/examples/src/main/java/io/grpc/examples/RouteGuideClient.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/RouteGuideClient.java). + +### Creating a stub + +To call service methods, we first need to create a *stub*, or rather, two stubs: +- a *blocking/synchronous* stub: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception. +- a *non-blocking/asynchronous* stub that makes non-blocking calls to the server, where the response is returned asynchronously. You can make certain types of streaming call only using the asynchronous stub. + +First we need to create a gRPC *channel* for our stub, specifying the server address and port we want to connect to: + +```java + channel = NettyChannelBuilder.forAddress(host, port) + .negotiationType(NegotiationType.PLAINTEXT) + .build(); +``` + +Now we can use the channel to create our stubs using the `newStub` and `newBlockingStub` methods provided in the `RouteGuideGrpc` class we generated from our .proto. + +```java + blockingStub = RouteGuideGrpc.newBlockingStub(channel); + asyncStub = RouteGuideGrpc.newStub(channel); +``` + +### Calling service methods + +Now let's look at how we call our service methods. + +#### Simple RPC + + + +#### Streaming RPCs + + +## Try it out! + +_[need build and run instructions here]_ + + + -- cgit v1.2.3 From 63f6633529372743ac1ca3512e29646a8dbeda71 Mon Sep 17 00:00:00 2001 From: Lisa Carey Date: Wed, 25 Feb 2015 18:48:22 +0000 Subject: Fixed typo --- java/javatutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/javatutorial.md b/java/javatutorial.md index 4c419cf345..e74573e0b4 100644 --- a/java/javatutorial.md +++ b/java/javatutorial.md @@ -250,7 +250,7 @@ As you can see, like the previous method types our method gets a `StreamObserver In the method body we instantiate an anonymous `StreamObserver` to return, in which we: - Override the `onValue()` method to get features and other information each time the client writes a `Point` to the message stream. -- Override the `onCompleted()' method (called when the *client* has finished writing messages) to populate and build our `RouteSummary`. We then call our method's own response observer's `onValue()` with our `RouteSummary`, and then call its `onCompleted()` method to finish the call from the server side. +- Override the `onCompleted()` method (called when the *client* has finished writing messages) to populate and build our `RouteSummary`. We then call our method's own response observer's `onValue()` with our `RouteSummary`, and then call its `onCompleted()` method to finish the call from the server side. Finally, let's look at our bidirectional streaming RPC `RouteChat()`. -- cgit v1.2.3 From dacca2cd5e6191a0b221dea79b48c04a8ff6f9c2 Mon Sep 17 00:00:00 2001 From: nmittler Date: Wed, 25 Feb 2015 10:50:15 -0800 Subject: Updating java package for helloworld.proto --- protos/helloworld.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protos/helloworld.proto b/protos/helloworld.proto index f9abd3d87f..6281c934ae 100644 --- a/protos/helloworld.proto +++ b/protos/helloworld.proto @@ -29,7 +29,7 @@ syntax = "proto3"; -option java_package = "ex.grpc"; +option java_package = "io.grpc.examples"; package helloworld; -- cgit v1.2.3 From e384403de53d095b886fb5a2ca1b6d6d05761cf7 Mon Sep 17 00:00:00 2001 From: Dan Ciruli Date: Wed, 25 Feb 2015 10:57:30 -0800 Subject: Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c58dca9a2b..7360182c56 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ Hello World example. You'll find more tutorials and reference docs in this repos You can find quick start guides for each language, including installation instructions, examples, and tutorials here: * [C++](https://github.com/grpc/grpc-common/tree/master/cpp) * [Java](https://github.com/grpc/grpc-common/tree/master/java) -* [Python](https://github.com/grpc/grpc-common/tree/master/python) * [Go](https://github.com/grpc/grpc-common/tree/master/go) * [ruby](https://github.com/grpc/grpc-common/tree/master/ruby) * [Node.js](https://github.com/grpc/grpc-common/tree/master/node) +* Python is coming soon ## What's in this repository? -- cgit v1.2.3 From 255b73b5b198f593b14d878842dd2a0bfec87fe9 Mon Sep 17 00:00:00 2001 From: nmittler Date: Wed, 25 Feb 2015 11:02:03 -0800 Subject: Removing java examples from grpc-common --- java/pom.xml | 105 --- java/run_greeter_client.sh | 10 - java/run_greeter_server.sh | 9 - java/src/main/java/ex/grpc/GreeterClient.java | 55 -- java/src/main/java/ex/grpc/GreeterGrpc.java | 172 ----- java/src/main/java/ex/grpc/GreeterImpl.java | 16 - java/src/main/java/ex/grpc/GreeterServer.java | 51 -- java/src/main/java/ex/grpc/Helloworld.java | 951 -------------------------- 8 files changed, 1369 deletions(-) delete mode 100644 java/pom.xml delete mode 100755 java/run_greeter_client.sh delete mode 100755 java/run_greeter_server.sh delete mode 100644 java/src/main/java/ex/grpc/GreeterClient.java delete mode 100644 java/src/main/java/ex/grpc/GreeterGrpc.java delete mode 100644 java/src/main/java/ex/grpc/GreeterImpl.java delete mode 100644 java/src/main/java/ex/grpc/GreeterServer.java delete mode 100644 java/src/main/java/ex/grpc/Helloworld.java diff --git a/java/pom.xml b/java/pom.xml deleted file mode 100644 index da0ee205f7..0000000000 --- a/java/pom.xml +++ /dev/null @@ -1,105 +0,0 @@ - - 4.0.0 - - - com.google.net.stubby - stubby-parent - 0.1.0-SNAPSHOT - - - grpc-hello-world - jar - - Hello gRPC World - - - - ${project.groupId} - stubby-core - ${project.version} - - - ${project.groupId} - stubby-netty - ${project.version} - - - ${project.groupId} - stubby-okhttp - ${project.version} - - - ${project.groupId} - stubby-stub - ${project.version} - - - ${project.groupId} - stubby-testing - ${project.version} - - - junit - junit - compile - - - org.mockito - mockito-core - compile - - - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - assemble-all - package - - single - - - - - - jar-with-dependencies - - - - - - com.internetitem - write-properties-file-maven-plugin - - - bootclasspath - prepare-package - - write-properties-file - - - bootclasspath.properties - ${project.build.directory} - - - bootclasspath - ${argLine.bootcp} - - - jar - ${project.build.directory}/${project.artifactId}-${project.version}-jar-with-dependencies.jar - - - - - - - - - diff --git a/java/run_greeter_client.sh b/java/run_greeter_client.sh deleted file mode 100755 index e86ab4ae89..0000000000 --- a/java/run_greeter_client.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -e -TARGET='Greeter Client' -TARGET_CLASS='ex.grpc.GreeterClient' -TARGET_ARGS="$@" - -cd "$(dirname "$0")" -mvn -q -nsu -am package -Dcheckstyle.skip=true -DskipTests -. target/bootclasspath.properties -echo "[INFO] Running: $TARGET ($TARGET_CLASS $TARGET_ARGS)" -exec java "$bootclasspath" -cp "$jar" "$TARGET_CLASS" $TARGET_ARGS diff --git a/java/run_greeter_server.sh b/java/run_greeter_server.sh deleted file mode 100755 index 836abc7f48..0000000000 --- a/java/run_greeter_server.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -e -TARGET='Greeter Server' -TARGET_CLASS='ex.grpc.GreeterServer' - -cd "$(dirname "$0")" -mvn -q -nsu -am package -Dcheckstyle.skip=true -DskipTests -. target/bootclasspath.properties -echo "[INFO] Running: $TARGET ($TARGET_CLASS)" -exec java "$bootclasspath" -cp "$jar" "$TARGET_CLASS" diff --git a/java/src/main/java/ex/grpc/GreeterClient.java b/java/src/main/java/ex/grpc/GreeterClient.java deleted file mode 100644 index 9a4615132d..0000000000 --- a/java/src/main/java/ex/grpc/GreeterClient.java +++ /dev/null @@ -1,55 +0,0 @@ -package ex.grpc; - -import com.google.net.stubby.ChannelImpl; -import com.google.net.stubby.stub.StreamObserver; -import com.google.net.stubby.transport.netty.NegotiationType; -import com.google.net.stubby.transport.netty.NettyChannelBuilder; - -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.concurrent.TimeUnit; - -public class GreeterClient { - private final Logger logger = Logger.getLogger( - GreeterClient.class.getName()); - private final ChannelImpl channel; - private final GreeterGrpc.GreeterBlockingStub blockingStub; - - public GreeterClient(String host, int port) { - channel = NettyChannelBuilder.forAddress(host, port) - .negotiationType(NegotiationType.PLAINTEXT) - .build(); - blockingStub = GreeterGrpc.newBlockingStub(channel); - } - - public void shutdown() throws InterruptedException { - channel.shutdown().awaitTerminated(5, TimeUnit.SECONDS); - } - - public void greet(String name) { - try { - logger.fine("Will try to greet " + name + " ..."); - Helloworld.HelloRequest req = - Helloworld.HelloRequest.newBuilder().setName(name).build(); - Helloworld.HelloReply reply = blockingStub.sayHello(req); - logger.info("Greeting: " + reply.getMessage()); - } catch (RuntimeException e) { - logger.log(Level.WARNING, "RPC failed", e); - return; - } - } - - public static void main(String[] args) throws Exception { - GreeterClient client = new GreeterClient("localhost", 50051); - try { - /* Access a service running on the local machine on port 50051 */ - String user = "world"; - if (args.length > 0) { - user = args[0]; /* Use the arg as the name to greet if provided */ - } - client.greet(user); - } finally { - client.shutdown(); - } - } -} diff --git a/java/src/main/java/ex/grpc/GreeterGrpc.java b/java/src/main/java/ex/grpc/GreeterGrpc.java deleted file mode 100644 index 080c3dfc43..0000000000 --- a/java/src/main/java/ex/grpc/GreeterGrpc.java +++ /dev/null @@ -1,172 +0,0 @@ -package ex.grpc; - -import static com.google.net.stubby.stub.Calls.createMethodDescriptor; -import static com.google.net.stubby.stub.Calls.asyncUnaryCall; -import static com.google.net.stubby.stub.Calls.asyncServerStreamingCall; -import static com.google.net.stubby.stub.Calls.asyncClientStreamingCall; -import static com.google.net.stubby.stub.Calls.duplexStreamingCall; -import static com.google.net.stubby.stub.Calls.blockingUnaryCall; -import static com.google.net.stubby.stub.Calls.blockingServerStreamingCall; -import static com.google.net.stubby.stub.Calls.unaryFutureCall; -import static com.google.net.stubby.stub.ServerCalls.createMethodDefinition; -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 GreeterGrpc { - - private static final com.google.net.stubby.stub.Method METHOD_SAY_HELLO = - com.google.net.stubby.stub.Method.create( - 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 GreeterStub newStub(com.google.net.stubby.Channel channel) { - return new GreeterStub(channel, CONFIG); - } - - public static GreeterBlockingStub newBlockingStub( - com.google.net.stubby.Channel channel) { - return new GreeterBlockingStub(channel, CONFIG); - } - - public static GreeterFutureStub newFutureStub( - com.google.net.stubby.Channel channel) { - return new GreeterFutureStub(channel, CONFIG); - } - - public static final GreeterServiceDescriptor CONFIG = - new GreeterServiceDescriptor(); - - @javax.annotation.concurrent.Immutable - public static class GreeterServiceDescriptor extends - com.google.net.stubby.stub.AbstractServiceDescriptor { - public final com.google.net.stubby.MethodDescriptor sayHello; - - private GreeterServiceDescriptor() { - sayHello = createMethodDescriptor( - "helloworld.Greeter", METHOD_SAY_HELLO); - } - - private GreeterServiceDescriptor( - java.util.Map> methodMap) { - sayHello = (com.google.net.stubby.MethodDescriptor) methodMap.get( - CONFIG.sayHello.getName()); - } - - @java.lang.Override - protected GreeterServiceDescriptor build( - java.util.Map> methodMap) { - return new GreeterServiceDescriptor(methodMap); - } - - @java.lang.Override - public com.google.common.collect.ImmutableList> methods() { - return com.google.common.collect.ImmutableList.>of( - sayHello); - } - } - - public static interface Greeter { - - public void sayHello(ex.grpc.Helloworld.HelloRequest request, - com.google.net.stubby.stub.StreamObserver responseObserver); - } - - public static interface GreeterBlockingClient { - - public ex.grpc.Helloworld.HelloReply sayHello(ex.grpc.Helloworld.HelloRequest request); - } - - public static interface GreeterFutureClient { - - public com.google.common.util.concurrent.ListenableFuture sayHello( - ex.grpc.Helloworld.HelloRequest request); - } - - public static class GreeterStub extends - com.google.net.stubby.stub.AbstractStub - implements Greeter { - private GreeterStub(com.google.net.stubby.Channel channel, - GreeterServiceDescriptor config) { - super(channel, config); - } - - @java.lang.Override - protected GreeterStub build(com.google.net.stubby.Channel channel, - GreeterServiceDescriptor config) { - return new GreeterStub(channel, config); - } - - @java.lang.Override - public void sayHello(ex.grpc.Helloworld.HelloRequest request, - com.google.net.stubby.stub.StreamObserver responseObserver) { - asyncUnaryCall( - channel.newCall(config.sayHello), request, responseObserver); - } - } - - public static class GreeterBlockingStub extends - com.google.net.stubby.stub.AbstractStub - implements GreeterBlockingClient { - private GreeterBlockingStub(com.google.net.stubby.Channel channel, - GreeterServiceDescriptor config) { - super(channel, config); - } - - @java.lang.Override - protected GreeterBlockingStub build(com.google.net.stubby.Channel channel, - GreeterServiceDescriptor config) { - return new GreeterBlockingStub(channel, config); - } - - @java.lang.Override - public ex.grpc.Helloworld.HelloReply sayHello(ex.grpc.Helloworld.HelloRequest request) { - return blockingUnaryCall( - channel.newCall(config.sayHello), request); - } - } - - public static class GreeterFutureStub extends - com.google.net.stubby.stub.AbstractStub - implements GreeterFutureClient { - private GreeterFutureStub(com.google.net.stubby.Channel channel, - GreeterServiceDescriptor config) { - super(channel, config); - } - - @java.lang.Override - protected 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 sayHello( - ex.grpc.Helloworld.HelloRequest request) { - return unaryFutureCall( - channel.newCall(config.sayHello), request); - } - } - - public static com.google.net.stubby.ServerServiceDefinition bindService( - final Greeter serviceImpl) { - return com.google.net.stubby.ServerServiceDefinition.builder("helloworld.Greeter") - .addMethod(createMethodDefinition( - METHOD_SAY_HELLO, - asyncUnaryRequestCall( - new com.google.net.stubby.stub.ServerCalls.UnaryRequestMethod< - ex.grpc.Helloworld.HelloRequest, - ex.grpc.Helloworld.HelloReply>() { - @java.lang.Override - public void invoke( - ex.grpc.Helloworld.HelloRequest request, - com.google.net.stubby.stub.StreamObserver responseObserver) { - serviceImpl.sayHello(request, responseObserver); - } - }))).build(); - } -} diff --git a/java/src/main/java/ex/grpc/GreeterImpl.java b/java/src/main/java/ex/grpc/GreeterImpl.java deleted file mode 100644 index 825ba8631e..0000000000 --- a/java/src/main/java/ex/grpc/GreeterImpl.java +++ /dev/null @@ -1,16 +0,0 @@ -package ex.grpc; - -import com.google.net.stubby.stub.StreamObserver; - -public class GreeterImpl implements GreeterGrpc.Greeter { - - @Override - public void sayHello(Helloworld.HelloRequest req, - StreamObserver responseObserver) { - Helloworld.HelloReply reply = Helloworld.HelloReply.newBuilder().setMessage( - "Hello " + req.getName()).build(); - responseObserver.onValue(reply); - responseObserver.onCompleted(); - } - -} diff --git a/java/src/main/java/ex/grpc/GreeterServer.java b/java/src/main/java/ex/grpc/GreeterServer.java deleted file mode 100644 index bb05680b0a..0000000000 --- a/java/src/main/java/ex/grpc/GreeterServer.java +++ /dev/null @@ -1,51 +0,0 @@ -package ex.grpc; - -import com.google.common.util.concurrent.MoreExecutors; -import com.google.net.stubby.ServerImpl; -import com.google.net.stubby.transport.netty.NettyServerBuilder; - -import java.util.concurrent.TimeUnit; - -/** - * Server that manages startup/shutdown of a {@code Greeter} server. - */ -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(GreeterGrpc.bindService(new GreeterImpl())) - .build(); - server.startAsync(); - server.awaitRunning(5, TimeUnit.SECONDS); - System.out.println("Server started on port:" + port); - } - - private void stop() throws Exception { - server.stopAsync(); - server.awaitTerminated(); - System.out.println("Server shutting down ..."); - } - - /** - * Main launches the server from the command line. - */ - public static void main(String[] args) throws Exception { - final GreeterServer server = new GreeterServer(); - - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - try { - System.out.println("Shutting down"); - server.stop(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - server.start(); - } -} diff --git a/java/src/main/java/ex/grpc/Helloworld.java b/java/src/main/java/ex/grpc/Helloworld.java deleted file mode 100644 index b25a63fca3..0000000000 --- a/java/src/main/java/ex/grpc/Helloworld.java +++ /dev/null @@ -1,951 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: helloworld.proto - -package ex.grpc; - -public final class Helloworld { - private Helloworld() {} - public static void registerAllExtensions( - com.google.protobuf.ExtensionRegistry registry) { - } - public interface HelloRequestOrBuilder extends - // @@protoc_insertion_point(interface_extends:helloworld.HelloRequest) - com.google.protobuf.MessageOrBuilder { - - /** - * optional string name = 1; - */ - java.lang.String getName(); - /** - * optional string name = 1; - */ - com.google.protobuf.ByteString - getNameBytes(); - } - /** - * Protobuf type {@code helloworld.HelloRequest} - * - *
-   * The request message containing the user's name.
-   * 
- */ - public static final class HelloRequest extends - com.google.protobuf.GeneratedMessage implements - // @@protoc_insertion_point(message_implements:helloworld.HelloRequest) - HelloRequestOrBuilder { - // Use HelloRequest.newBuilder() to construct. - private HelloRequest(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - } - private HelloRequest() { - name_ = ""; - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return com.google.protobuf.UnknownFieldSet.getDefaultInstance(); - } - private HelloRequest( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - int mutable_bitField0_ = 0; - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!input.skipField(tag)) { - done = true; - } - break; - } - case 10: { - com.google.protobuf.ByteString bs = input.readBytes(); - - name_ = bs; - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ex.grpc.Helloworld.HelloRequest.class, ex.grpc.Helloworld.HelloRequest.Builder.class); - } - - public static final com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public HelloRequest parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new HelloRequest(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - public static final int NAME_FIELD_NUMBER = 1; - private java.lang.Object name_; - /** - * optional string name = 1; - */ - public java.lang.String getName() { - java.lang.Object ref = name_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - name_ = s; - } - return s; - } - } - /** - * optional string name = 1; - */ - public com.google.protobuf.ByteString - getNameBytes() { - java.lang.Object ref = name_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - name_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (!getNameBytes().isEmpty()) { - output.writeBytes(1, getNameBytes()); - } - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (!getNameBytes().isEmpty()) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, getNameBytes()); - } - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - public static ex.grpc.Helloworld.HelloRequest parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ex.grpc.Helloworld.HelloRequest parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloRequest parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ex.grpc.Helloworld.HelloRequest parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloRequest parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static ex.grpc.Helloworld.HelloRequest parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloRequest parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static ex.grpc.Helloworld.HelloRequest parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloRequest parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static ex.grpc.Helloworld.HelloRequest parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return new Builder(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(ex.grpc.Helloworld.HelloRequest prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code helloworld.HelloRequest} - * - *
-     * The request message containing the user's name.
-     * 
- */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder implements - // @@protoc_insertion_point(builder_implements:helloworld.HelloRequest) - ex.grpc.Helloworld.HelloRequestOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ex.grpc.Helloworld.HelloRequest.class, ex.grpc.Helloworld.HelloRequest.Builder.class); - } - - // Construct using ex.grpc.Helloworld.HelloRequest.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - } - } - public Builder clear() { - super.clear(); - name_ = ""; - - return this; - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloRequest_descriptor; - } - - public ex.grpc.Helloworld.HelloRequest getDefaultInstanceForType() { - return ex.grpc.Helloworld.HelloRequest.getDefaultInstance(); - } - - public ex.grpc.Helloworld.HelloRequest build() { - ex.grpc.Helloworld.HelloRequest result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public ex.grpc.Helloworld.HelloRequest buildPartial() { - ex.grpc.Helloworld.HelloRequest result = new ex.grpc.Helloworld.HelloRequest(this); - result.name_ = name_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ex.grpc.Helloworld.HelloRequest) { - return mergeFrom((ex.grpc.Helloworld.HelloRequest)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(ex.grpc.Helloworld.HelloRequest other) { - if (other == ex.grpc.Helloworld.HelloRequest.getDefaultInstance()) return this; - if (!other.getName().isEmpty()) { - name_ = other.name_; - onChanged(); - } - onChanged(); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - ex.grpc.Helloworld.HelloRequest parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ex.grpc.Helloworld.HelloRequest) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - - private java.lang.Object name_ = ""; - /** - * optional string name = 1; - */ - public java.lang.String getName() { - java.lang.Object ref = name_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - name_ = s; - } - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string name = 1; - */ - public com.google.protobuf.ByteString - getNameBytes() { - java.lang.Object ref = name_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - name_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string name = 1; - */ - public Builder setName( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - - name_ = value; - onChanged(); - return this; - } - /** - * optional string name = 1; - */ - public Builder clearName() { - - name_ = getDefaultInstance().getName(); - onChanged(); - return this; - } - /** - * optional string name = 1; - */ - public Builder setNameBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - - name_ = value; - onChanged(); - return this; - } - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return this; - } - - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return this; - } - - - // @@protoc_insertion_point(builder_scope:helloworld.HelloRequest) - } - - // @@protoc_insertion_point(class_scope:helloworld.HelloRequest) - private static final ex.grpc.Helloworld.HelloRequest defaultInstance;static { - defaultInstance = new ex.grpc.Helloworld.HelloRequest(); - } - - public static ex.grpc.Helloworld.HelloRequest getDefaultInstance() { - return defaultInstance; - } - - public ex.grpc.Helloworld.HelloRequest getDefaultInstanceForType() { - return defaultInstance; - } - - } - - public interface HelloReplyOrBuilder extends - // @@protoc_insertion_point(interface_extends:helloworld.HelloReply) - com.google.protobuf.MessageOrBuilder { - - /** - * optional string message = 1; - */ - java.lang.String getMessage(); - /** - * optional string message = 1; - */ - com.google.protobuf.ByteString - getMessageBytes(); - } - /** - * Protobuf type {@code helloworld.HelloReply} - * - *
-   * The response message containing the greetings
-   * 
- */ - public static final class HelloReply extends - com.google.protobuf.GeneratedMessage implements - // @@protoc_insertion_point(message_implements:helloworld.HelloReply) - HelloReplyOrBuilder { - // Use HelloReply.newBuilder() to construct. - private HelloReply(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - } - private HelloReply() { - message_ = ""; - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return com.google.protobuf.UnknownFieldSet.getDefaultInstance(); - } - private HelloReply( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - int mutable_bitField0_ = 0; - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!input.skipField(tag)) { - done = true; - } - break; - } - case 10: { - com.google.protobuf.ByteString bs = input.readBytes(); - - message_ = bs; - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ex.grpc.Helloworld.HelloReply.class, ex.grpc.Helloworld.HelloReply.Builder.class); - } - - public static final com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public HelloReply parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new HelloReply(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - public static final int MESSAGE_FIELD_NUMBER = 1; - private java.lang.Object message_; - /** - * optional string message = 1; - */ - public java.lang.String getMessage() { - java.lang.Object ref = message_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - message_ = s; - } - return s; - } - } - /** - * optional string message = 1; - */ - public com.google.protobuf.ByteString - getMessageBytes() { - java.lang.Object ref = message_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - message_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (!getMessageBytes().isEmpty()) { - output.writeBytes(1, getMessageBytes()); - } - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (!getMessageBytes().isEmpty()) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, getMessageBytes()); - } - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - public static ex.grpc.Helloworld.HelloReply parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ex.grpc.Helloworld.HelloReply parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloReply parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ex.grpc.Helloworld.HelloReply parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloReply parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static ex.grpc.Helloworld.HelloReply parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloReply parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static ex.grpc.Helloworld.HelloReply parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static ex.grpc.Helloworld.HelloReply parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static ex.grpc.Helloworld.HelloReply parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return new Builder(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(ex.grpc.Helloworld.HelloReply prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code helloworld.HelloReply} - * - *
-     * The response message containing the greetings
-     * 
- */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder implements - // @@protoc_insertion_point(builder_implements:helloworld.HelloReply) - ex.grpc.Helloworld.HelloReplyOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ex.grpc.Helloworld.HelloReply.class, ex.grpc.Helloworld.HelloReply.Builder.class); - } - - // Construct using ex.grpc.Helloworld.HelloReply.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - } - } - public Builder clear() { - super.clear(); - message_ = ""; - - return this; - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return ex.grpc.Helloworld.internal_static_helloworld_HelloReply_descriptor; - } - - public ex.grpc.Helloworld.HelloReply getDefaultInstanceForType() { - return ex.grpc.Helloworld.HelloReply.getDefaultInstance(); - } - - public ex.grpc.Helloworld.HelloReply build() { - ex.grpc.Helloworld.HelloReply result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public ex.grpc.Helloworld.HelloReply buildPartial() { - ex.grpc.Helloworld.HelloReply result = new ex.grpc.Helloworld.HelloReply(this); - result.message_ = message_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ex.grpc.Helloworld.HelloReply) { - return mergeFrom((ex.grpc.Helloworld.HelloReply)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(ex.grpc.Helloworld.HelloReply other) { - if (other == ex.grpc.Helloworld.HelloReply.getDefaultInstance()) return this; - if (!other.getMessage().isEmpty()) { - message_ = other.message_; - onChanged(); - } - onChanged(); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - ex.grpc.Helloworld.HelloReply parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ex.grpc.Helloworld.HelloReply) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - - private java.lang.Object message_ = ""; - /** - * optional string message = 1; - */ - public java.lang.String getMessage() { - java.lang.Object ref = message_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - message_ = s; - } - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string message = 1; - */ - public com.google.protobuf.ByteString - getMessageBytes() { - java.lang.Object ref = message_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - message_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string message = 1; - */ - public Builder setMessage( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - - message_ = value; - onChanged(); - return this; - } - /** - * optional string message = 1; - */ - public Builder clearMessage() { - - message_ = getDefaultInstance().getMessage(); - onChanged(); - return this; - } - /** - * optional string message = 1; - */ - public Builder setMessageBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - - message_ = value; - onChanged(); - return this; - } - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return this; - } - - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return this; - } - - - // @@protoc_insertion_point(builder_scope:helloworld.HelloReply) - } - - // @@protoc_insertion_point(class_scope:helloworld.HelloReply) - private static final ex.grpc.Helloworld.HelloReply defaultInstance;static { - defaultInstance = new ex.grpc.Helloworld.HelloReply(); - } - - public static ex.grpc.Helloworld.HelloReply getDefaultInstance() { - return defaultInstance; - } - - public ex.grpc.Helloworld.HelloReply getDefaultInstanceForType() { - return defaultInstance; - } - - } - - private static final com.google.protobuf.Descriptors.Descriptor - internal_static_helloworld_HelloRequest_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_helloworld_HelloRequest_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor - internal_static_helloworld_HelloReply_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_helloworld_HelloReply_fieldAccessorTable; - - public static com.google.protobuf.Descriptors.FileDescriptor - getDescriptor() { - return descriptor; - } - private static com.google.protobuf.Descriptors.FileDescriptor - descriptor; - static { - java.lang.String[] descriptorData = { - "\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() { - public com.google.protobuf.ExtensionRegistry assignDescriptors( - com.google.protobuf.Descriptors.FileDescriptor root) { - descriptor = root; - return null; - } - }; - com.google.protobuf.Descriptors.FileDescriptor - .internalBuildGeneratedFileFrom(descriptorData, - new com.google.protobuf.Descriptors.FileDescriptor[] { - }, assigner); - internal_static_helloworld_HelloRequest_descriptor = - getDescriptor().getMessageTypes().get(0); - internal_static_helloworld_HelloRequest_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_helloworld_HelloRequest_descriptor, - new java.lang.String[] { "Name", }); - internal_static_helloworld_HelloReply_descriptor = - getDescriptor().getMessageTypes().get(1); - internal_static_helloworld_HelloReply_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_helloworld_HelloReply_descriptor, - new java.lang.String[] { "Message", }); - } - - // @@protoc_insertion_point(outer_class_scope) -} -- cgit v1.2.3 From 3ae2147cbcec04605d30fb6f60e51d01f233119f Mon Sep 17 00:00:00 2001 From: Jayant Kolhe Date: Wed, 25 Feb 2015 11:29:45 -0800 Subject: Update README.md Fixed repository listed in command line. --- cpp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/README.md b/cpp/README.md index 759e10bfe1..e9e9962a9b 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -15,7 +15,7 @@ following command: ```sh -$ git clone https://github.com/google/grpc-common.git +$ git clone https://github.com/grpc/grpc-common.git ``` Change your current directory to grpc-common/cpp/helloworld -- cgit v1.2.3 From b99d48190463c3cce7f4646f715a8a723924d192 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 25 Feb 2015 11:59:08 -0800 Subject: Update grpc-auth-support.md Fix method name. --- grpc-auth-support.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grpc-auth-support.md b/grpc-auth-support.md index 9850b8b24e..59d690d8a5 100644 --- a/grpc-auth-support.md +++ b/grpc-auth-support.md @@ -54,7 +54,7 @@ passed to the factory method. gRPC applications can use a simple API to create a credential that works in various deployment scenarios. ``` -std::unique_ptr creds = CredentialsFactory::DefaultGoogleCredentials(); +std::unique_ptr creds = GoogleDefaultGoogleDefaultCredentials(); // Create a channel, stub and make RPC calls (same as in the previous example) std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); std::unique_ptr stub(Greeter::NewStub(channel)); -- cgit v1.2.3 From a08dc0a6ca1eebda2591d26bb0d3c8ce1db08a82 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 25 Feb 2015 12:00:47 -0800 Subject: Update grpc-auth-support.md Fix the method name, for real this time. --- grpc-auth-support.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grpc-auth-support.md b/grpc-auth-support.md index 59d690d8a5..b1b576e742 100644 --- a/grpc-auth-support.md +++ b/grpc-auth-support.md @@ -54,7 +54,7 @@ passed to the factory method. gRPC applications can use a simple API to create a credential that works in various deployment scenarios. ``` -std::unique_ptr creds = GoogleDefaultGoogleDefaultCredentials(); +std::unique_ptr creds = CredentialsFactory::GoogleDefaultCredentials(); // Create a channel, stub and make RPC calls (same as in the previous example) std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); std::unique_ptr stub(Greeter::NewStub(channel)); -- cgit v1.2.3 From d84e9cede8d49a0e4e5f190a5dac793b03bb0403 Mon Sep 17 00:00:00 2001 From: Dan Ciruli Date: Wed, 25 Feb 2015 12:13:03 -0800 Subject: Update README.md --- node/README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/node/README.md b/node/README.md index f9df3b0a81..076755a695 100644 --- a/node/README.md +++ b/node/README.md @@ -10,9 +10,21 @@ INSTALL ------- - Clone this repository + + ```sh + $ git clone https://github.com/grpc/grpc-common.git + ``` - 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`. + - Install + + ```sh + $ cd grpc-common/node + $ npm install + # If node is not found, you'll need to clone the grpc repository (if you haven't already) + $ git clone https://github.com/grpc/grpc.git + $ npm install ~/grpc/src/node + ``` + Try it! ------- -- cgit v1.2.3 From ecc3d900ea81bf157d1f5c4fc0d16863d29fda14 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 25 Feb 2015 12:19:50 -0800 Subject: Update grpc-auth-support.md Address previous TODOs by providing the actual environment variable name and file path name where the service account keys are loaded from. --- grpc-auth-support.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/grpc-auth-support.md b/grpc-auth-support.md index 9850b8b24e..a43f873e5d 100644 --- a/grpc-auth-support.md +++ b/grpc-auth-support.md @@ -63,11 +63,13 @@ grpc::Status s = stub->sayHello(&context, *request, response); This credential works for applications using Service Accounts as well as for applications running in Google Compute Engine (GCE). In the former case, the -service account’s private keys are expected in file located at [TODO: well -known file fath for service account keys] or in the file named in the environment -variable [TODO: add the env var name here]. The keys are used at run-time to -generate bearer tokens that are attached to each outgoing RPC on the -corresponding channel. +service account’s private keys are loaded from the file named in the environment +variable `GOOGLE_APPLICATION_CREDENTIALS`. If that environment variable is not +set, the library attempts to load the keys from the file located at +`/.config/gcloud/application_default_credentials.json` where `` is +the relative path specified in the environment variable `HOME`. Once loaded, the +keys are used to generate bearer tokens that are attached to each outgoing RPC +on the corresponding channel. For applications running in GCE, a default service account and corresponding OAuth scopes can be configured during VM setup. At run-time, this credential -- cgit v1.2.3 From 03f702f5eab794b4ae720569da289dfaf0927dca Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 25 Feb 2015 12:48:44 -0800 Subject: Update grpc-auth-support.md --- grpc-auth-support.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/grpc-auth-support.md b/grpc-auth-support.md index a43f873e5d..8d715804d5 100644 --- a/grpc-auth-support.md +++ b/grpc-auth-support.md @@ -64,10 +64,7 @@ grpc::Status s = stub->sayHello(&context, *request, response); This credential works for applications using Service Accounts as well as for applications running in Google Compute Engine (GCE). In the former case, the service account’s private keys are loaded from the file named in the environment -variable `GOOGLE_APPLICATION_CREDENTIALS`. If that environment variable is not -set, the library attempts to load the keys from the file located at -`/.config/gcloud/application_default_credentials.json` where `` is -the relative path specified in the environment variable `HOME`. Once loaded, the +variable `GOOGLE_APPLICATION_CREDENTIALS`. The keys are used to generate bearer tokens that are attached to each outgoing RPC on the corresponding channel. -- cgit v1.2.3 From 038b0df466bd70663f7917a5e43901fea413c353 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Wed, 25 Feb 2015 22:20:20 +0000 Subject: Update javatutorial.md Updated with @nmittler's edits. --- java/javatutorial.md | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/java/javatutorial.md b/java/javatutorial.md index e74573e0b4..7465a8ab0e 100644 --- a/java/javatutorial.md +++ b/java/javatutorial.md @@ -6,7 +6,7 @@ This tutorial provides a basic Java programmer's introduction to working with gR - Generate server and client code using the protocol buffer compiler. - Use the Java gRPC API to write a simple client and server for your service. -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the [proto3](https://github.com/google/protobuf/releases) version of the protocol buffers language, which is currently in alpha release: you can see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. This isn't a comprehensive guide to using gRPC in Java: more reference documentation is coming soon. @@ -36,7 +36,7 @@ You also should have the relevant tools installed to generate the server and cli Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-java/examples/src/main/proto/route_guide.proto`](https://github.com/grpc/grpc-java/blob/master/examples/src/main/proto/route_guide.proto). As we're generating Java code in this example, we've specified a `java_package` file option in our .proto: -``` +```proto option java_package = "io.grpc.examples"; ``` @@ -44,7 +44,7 @@ This specifies the package we want to use for our generated Java classes. If no To define a service, we specify a named `service` in the .proto file: -``` +```proto service RouteGuide { ... } @@ -53,13 +53,13 @@ service RouteGuide { Then we define `rpc` methods inside our service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: - A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. -``` - // Obtains the feature at a given position. +```proto + // Obtains the feature at a given position. rpc GetFeature(Point) returns (Feature) {} ``` - A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. -``` +```proto // 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 @@ -68,21 +68,21 @@ Then we define `rpc` methods inside our service definition, specifying their req ``` - A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. -``` +```proto // Accepts a stream of Points on a route being traversed, returning a // RouteSummary when traversal is completed. rpc RecordRoute(stream Point) returns (RouteSummary) {} ``` - A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -``` +```proto // Accepts a stream of RouteNotes sent while a route is being traversed, // while receiving other RouteNotes (e.g. from other users). rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} ``` Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -``` +```proto // 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 @@ -109,7 +109,7 @@ which actually runs: [actual command] Running this command generates the following files: -- `RouteGuideOuterClass.java` [cheeeeeeck], which contains all the protocol buffer code to populate, serialize, and retrieve our request and response message types +- `RouteGuideOuterClass.java`, which contains all the protocol buffer code to populate, serialize, and retrieve our request and response message types - `RouteGuideGrpc.java` which contains (along with some other useful code): - an interface for `RouteGuide` servers to implement, `RouteGuideGrpc.Service`, with all the methods defined in the `RouteGuide` service. - *stub* classes that clients can use to talk to a `RouteGuide` server. These also implement the `RouteGuide` interface. @@ -135,7 +135,7 @@ private static class RouteGuideService implements RouteGuideGrpc.RouteGuide { ... } ``` - +#### Simple RPC `RouteGuideService` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. ```java @@ -170,7 +170,8 @@ To return our response to the client and complete the call: 2. We use the response observer's `onValue()` method to return the `Feature`. 3. We use the response observer's `onCompleted()` method to specify that we've finished dealing with the RPC. -Next let's look at a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. +#### Server-side streaming RPC +Next let's look at one of our streaming RPCs. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. ```java private final Collection features; @@ -203,6 +204,7 @@ Like the simple RPC, this method gets a request object (the `Rectangle` in which This time, we get as many `Feature` objects as we need to return to the client (in this case, we select them from the service's feature collection based on whether they're inside our request `Rectangle`), and write them each in turn to the response observer using its `Write()` method. Finally, as in our simple RPC, we use the response observer's `onCompleted()` method to tell gRPC that we've finished writing responses. +#### Client-side streaming RPC Now let's look at something a little more complicated: the client-side streaming method `RecordRoute`, where we get a stream of `Point`s from the client and return a single `RouteSummary` with information about their trip. ```java @@ -252,6 +254,7 @@ In the method body we instantiate an anonymous `StreamObserver` to return, in wh - Override the `onValue()` method to get features and other information each time the client writes a `Point` to the message stream. - Override the `onCompleted()` method (called when the *client* has finished writing messages) to populate and build our `RouteSummary`. We then call our method's own response observer's `onValue()` with our `RouteSummary`, and then call its `onCompleted()` method to finish the call from the server side. +#### Bidirectional streaming RPC Finally, let's look at our bidirectional streaming RPC `RouteChat()`. ```cpp @@ -299,7 +302,9 @@ Once we've implemented all our methods, we also need to start up a gRPC server s ... } ``` -As you can see, we build and start our server using a `NettyServerBuilder`. To do this, we: +As you can see, we build and start our server using a `NettyServerBuilder`. This is a builder for servers based on the [Netty](http://netty.io/) transport framework. + +To do this, we: 1. Create an instance of our service implementation class `RouteGuideService` and pass it to the generated `RouteGuideGrpc` class's static `bindService()` method to get a service definition. 3. Specify the address and port we want to use to listen for client requests using the builder's `forPort()` method. @@ -340,12 +345,19 @@ Now let's look at how we call our service methods. -#### Streaming RPCs +#### Server-side streaming RPC + + + +#### Client-side streaming RPC + + +#### Bidirectional streaming RPC ## Try it out! -_[need build and run instructions here]_ +Follow the instructions in the example directory [README](https://github.com/grpc/grpc-java/blob/master/examples/README.md) to build and run the client and server -- cgit v1.2.3 From c4b28a9d362dab6128ca25a7cc912685860d6e92 Mon Sep 17 00:00:00 2001 From: Dan Ciruli Date: Wed, 25 Feb 2015 14:22:46 -0800 Subject: Update README.md Added a background section. --- go/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/go/README.md b/go/README.md index 9fc49474d7..2ef89ff7a4 100644 --- a/go/README.md +++ b/go/README.md @@ -1,6 +1,10 @@ gRPC in 3 minutes (Go) ====================== +BACKGROUND +------------- +For this sample, we've already generated the server and client stubs from [helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). + PREREQUISITES ------------- -- cgit v1.2.3 From 41df7de1a2d9077c66f7ae9d2d3a07f56f944067 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Wed, 25 Feb 2015 22:25:47 +0000 Subject: Added note about using most recent compiler --- java/javatutorial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/javatutorial.md b/java/javatutorial.md index 7465a8ab0e..0b4fac0e69 100644 --- a/java/javatutorial.md +++ b/java/javatutorial.md @@ -96,7 +96,7 @@ message Point { ## Generating client and server code -Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC Java plugin. +Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC Java plugin. Note that you need to use [version 3](https://github.com/google/protobuf/releases) of `protoc` in order to use the plugin. For simplicity, we've provided a [Gradle build file](https://github.com/grpc/grpc-java/blob/master/examples/build.gradle) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](https://github.com/grpc/grpc-java) first): @@ -357,7 +357,7 @@ Now let's look at how we call our service methods. ## Try it out! -Follow the instructions in the example directory [README](https://github.com/grpc/grpc-java/blob/master/examples/README.md) to build and run the client and server +Follow the instructions in the example directory [README](https://github.com/grpc/grpc-java/blob/master/examples/README.md) to build and run the client and server. -- cgit v1.2.3 From e0faf3166b4cc77723abd5782639851a05cda4e8 Mon Sep 17 00:00:00 2001 From: Dan Ciruli Date: Wed, 25 Feb 2015 14:29:11 -0800 Subject: Update README.md --- java/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/README.md b/java/README.md index 89724904d4..4c5e4c5902 100644 --- a/java/README.md +++ b/java/README.md @@ -1,6 +1,10 @@ gRPC in 3 minutes (Java) ======================== +BACKGROUND +------------- +For this sample, we've already generated the server and client stubs from [helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). + PREREQUISITES ------------- -- cgit v1.2.3 From b6bcf2e46dd5796f50a1cc2b52d76ddb44b8e874 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Wed, 25 Feb 2015 22:30:00 +0000 Subject: made last added comment a bit simpler! --- java/javatutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/javatutorial.md b/java/javatutorial.md index 0b4fac0e69..05c122b8fc 100644 --- a/java/javatutorial.md +++ b/java/javatutorial.md @@ -96,7 +96,7 @@ message Point { ## Generating client and server code -Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC Java plugin. Note that you need to use [version 3](https://github.com/google/protobuf/releases) of `protoc` in order to use the plugin. +Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC Java plugin. You need to use the [proto3](https://github.com/google/protobuf/releases) compiler in order to generate gRPC services For simplicity, we've provided a [Gradle build file](https://github.com/grpc/grpc-java/blob/master/examples/build.gradle) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](https://github.com/grpc/grpc-java) first): -- cgit v1.2.3 From 8813157abe55748c25210973b8636b1e8fb476ce Mon Sep 17 00:00:00 2001 From: LisaFC Date: Wed, 25 Feb 2015 22:34:56 +0000 Subject: changed gradle command to ./gradlew --- java/javatutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/javatutorial.md b/java/javatutorial.md index 05c122b8fc..d4f3216d46 100644 --- a/java/javatutorial.md +++ b/java/javatutorial.md @@ -101,7 +101,7 @@ Next we need to generate the gRPC client and server interfaces from our .proto s For simplicity, we've provided a [Gradle build file](https://github.com/grpc/grpc-java/blob/master/examples/build.gradle) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](https://github.com/grpc/grpc-java) first): ```shell -gradle build +../gradlew build ``` which actually runs: -- cgit v1.2.3 From 5d6398c3ba5585a4f1042d579e744ee20168c407 Mon Sep 17 00:00:00 2001 From: LisaFC Date: Wed, 25 Feb 2015 22:39:07 +0000 Subject: small fixes --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 7360182c56..f60e9c7176 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,6 @@ Hello World method. - Create a Java client that accesses the Java server. - Create a Go client that accesses the same Java server. -- Update the service with a streaming RPC. The complete code for the example is available in the `grpc-common` GitHub repository. We use the Git versioning system for source code management: @@ -290,7 +289,7 @@ public static class GreeterStub extends Now let's write some code! First we'll create a server application to implement our service. Note that we're not going to go into a lot of detail about how to create a server in this section. More detailed information will be in the -tutorial for your chosen language (coming soon). +tutorial for your chosen language: check if there's one available yet in the relevant [quick start](#quickstart). Our server application has two classes: -- cgit v1.2.3 From 7dfd4abba5174bc73f848b898fce284493ae44fe Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 25 Feb 2015 15:00:46 -0800 Subject: added python helloworld --- python/helloworld/.gitignore | 1 + python/helloworld/README.md | 111 +++++++++++++++++++++++++ python/helloworld/greeter_client.py | 44 ++++++++++ python/helloworld/greeter_server.py | 56 +++++++++++++ python/helloworld/helloworld.proto | 49 +++++++++++ python/helloworld/helloworld_pb2.py | 158 ++++++++++++++++++++++++++++++++++++ python/helloworld/run_client.sh | 8 ++ python/helloworld/run_codegen.sh | 4 + python/helloworld/run_server.sh | 9 ++ 9 files changed, 440 insertions(+) create mode 100644 python/helloworld/.gitignore create mode 100644 python/helloworld/README.md create mode 100755 python/helloworld/greeter_client.py create mode 100644 python/helloworld/greeter_server.py create mode 100644 python/helloworld/helloworld.proto create mode 100644 python/helloworld/helloworld_pb2.py create mode 100755 python/helloworld/run_client.sh create mode 100755 python/helloworld/run_codegen.sh create mode 100755 python/helloworld/run_server.sh diff --git a/python/helloworld/.gitignore b/python/helloworld/.gitignore new file mode 100644 index 0000000000..0d20b6487c --- /dev/null +++ b/python/helloworld/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/python/helloworld/README.md b/python/helloworld/README.md new file mode 100644 index 0000000000..2bbfc4b017 --- /dev/null +++ b/python/helloworld/README.md @@ -0,0 +1,111 @@ +# gRPC Python Hello World Tutorial + +### Install gRPC +Make sure you have built gRPC Python from source on your system. Follow the instructions here: +[https://github.com/grpc/grpc/blob/master/src/python/README.md](https://github.com/grpc/grpc/blob/master/src/python/README.md). + +This gives you a python virtual environment with installed gRPC Python +in GRPC_ROOT/python2.7_virtual_environment. GRPC_ROOT is the path to which you +have cloned the [gRPC git repo](https://github.com/grpc/grpc). + +### Get the tutorial source code + +The example code for this and our other examples live in the `grpc-common` +GitHub repository. Clone this repository to your local machine by running the +following command: + + +```sh +$ git clone https://github.com/google/grpc-common.git +``` + +Change your current directory to grpc-common/python/helloworld + +```sh +$ cd grpc-common/python/helloworld/ +``` + +### Defining a service + +The first step in creating our example is to define a *service*: an RPC +service specifies the methods that can be called remotely with their parameters +and return types. As you saw in the +[overview](#protocolbuffers) above, gRPC does this using [protocol +buffers](https://developers.google.com/protocol-buffers/docs/overview). We +use the protocol buffers interface definition language (IDL) to define our +service methods, and define the parameters and return +types as protocol buffer message types. Both the client and the +server use interface code generated from the service definition. + +Here's our example service definition, defined using protocol buffers IDL in +[helloworld.proto](https://github.com/grpc/grpc-common/blob/master/python/helloworld/helloworld.proto). The `Greeting` +service has one method, `hello`, that lets the server receive a single +`HelloRequest` +message from the remote client containing the user's name, then send back +a greeting in a single `HelloReply`. This is the simplest type of RPC you +can specify in gRPC. + +``` +syntax = "proto2"; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + optional string name = 1; +} + +// The response message containing the greetings +message HelloReply { + optional string message = 1; +} + +``` + + +### Generating gRPC code + +Once we've defined our service, we use the protocol buffer compiler +`protoc` to generate the special client and server code we need to create +our application. The generated code contains both stub code for clients to +use and an abstract interface for servers to implement, both with the method +defined in our `Greeting` service. + +To generate the client and server side interfaces: + +```sh +$ ./run_codegen.sh +``` +Which internally invokes the proto-compiler as: + +```sh +$ protoc -I . --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` helloworld.proto +``` + +Optionally, you can just skip the code generation step as the generated python module has already +been generated for you (helloworld_pb2.py). + +### The client + +Client-side code can be found in [greeter_client.py](https://github.com/grpc/grpc-common/blob/master/python/helloworld/greeter_client.py). + +You can run the client using: + +```sh +$ ./run_client.sh +``` + + +### The server + +Server side code can be found in [greeter_server.py](https://github.com/grpc/grpc-common/blob/master/python/helloworld/greeter_server.py). + +You can run the server using: + +```sh +$ ./run_server.sh +``` diff --git a/python/helloworld/greeter_client.py b/python/helloworld/greeter_client.py new file mode 100755 index 0000000000..370ce46770 --- /dev/null +++ b/python/helloworld/greeter_client.py @@ -0,0 +1,44 @@ +# 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. + +"""The Python implementation of the GRPC helloworld.Greeter client.""" + +import helloworld_pb2 + +_TIMEOUT_SECONDS = 10 + + +def run(): + with helloworld_pb2.early_adopter_create_Greeter_stub('localhost', 50051) as stub: + response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'), _TIMEOUT_SECONDS) + print "Greeter client received: " + response.message + + +if __name__ == '__main__': + run() diff --git a/python/helloworld/greeter_server.py b/python/helloworld/greeter_server.py new file mode 100644 index 0000000000..81353666b1 --- /dev/null +++ b/python/helloworld/greeter_server.py @@ -0,0 +1,56 @@ +# 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. + +"""The Python implementation of the GRPC helloworld.Greeter server.""" + +import time + +import helloworld_pb2 + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +class Greeter(helloworld_pb2.EarlyAdopterGreeterServicer): + + def SayHello(self, request, context): + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) + + +def serve(): + server = helloworld_pb2.early_adopter_create_Greeter_server( + Greeter(), 50051, None, None) + server.start() + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop() + +if __name__ == '__main__': + serve() diff --git a/python/helloworld/helloworld.proto b/python/helloworld/helloworld.proto new file mode 100644 index 0000000000..1ade8fb2ac --- /dev/null +++ b/python/helloworld/helloworld.proto @@ -0,0 +1,49 @@ +// 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 = "proto2"; + +//TODO: see https://github.com/grpc/grpc/issues/814 +//package examples; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + optional string name = 1; +} + +// The response message containing the greetings +message HelloReply { + optional string message = 1; +} diff --git a/python/helloworld/helloworld_pb2.py b/python/helloworld/helloworld_pb2.py new file mode 100644 index 0000000000..d35ebb77c6 --- /dev/null +++ b/python/helloworld/helloworld_pb2.py @@ -0,0 +1,158 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: helloworld.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='helloworld.proto', + package='', + serialized_pb=_b('\n\x10helloworld.proto\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t23\n\x07Greeter\x12(\n\x08SayHello\x12\r.HelloRequest\x1a\x0b.HelloReply\"\x00') +) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + + + + +_HELLOREQUEST = _descriptor.Descriptor( + name='HelloRequest', + full_name='HelloRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='HelloRequest.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=20, + serialized_end=48, +) + + +_HELLOREPLY = _descriptor.Descriptor( + name='HelloReply', + full_name='HelloReply', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='HelloReply.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=50, + serialized_end=79, +) + +DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST +DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY + +HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict( + DESCRIPTOR = _HELLOREQUEST, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:HelloRequest) + )) +_sym_db.RegisterMessage(HelloRequest) + +HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), dict( + DESCRIPTOR = _HELLOREPLY, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:HelloReply) + )) +_sym_db.RegisterMessage(HelloReply) + + +import abc +from grpc._adapter import fore +from grpc._adapter import rear +from grpc.framework.assembly import implementations +from grpc.framework.assembly import utilities +class EarlyAdopterGreeterServicer(object): + """""" + __metaclass__ = abc.ABCMeta + @abc.abstractmethod + def SayHello(self, request): + raise NotImplementedError() +class EarlyAdopterGreeterServer(object): + """""" + __metaclass__ = abc.ABCMeta + @abc.abstractmethod + def start(self): + raise NotImplementedError() + @abc.abstractmethod + def stop(self): + raise NotImplementedError() +class EarlyAdopterGreeterStub(object): + """""" + __metaclass__ = abc.ABCMeta + @abc.abstractmethod + def SayHello(self, request): + raise NotImplementedError() + SayHello.async = None +def early_adopter_create_Greeter_server(servicer, port, root_certificates, key_chain_pairs): + method_implementations = { + "SayHello": utilities.unary_unary_inline(servicer.SayHello), + } + import helloworld_pb2 + request_deserializers = { + "SayHello": helloworld_pb2.HelloRequest.FromString, + } + response_serializers = { + "SayHello": lambda x: x.SerializeToString(), + } + link = fore.activated_fore_link(port, request_deserializers, response_serializers, root_certificates, key_chain_pairs) + return implementations.assemble_service(method_implementations, link) +def early_adopter_create_Greeter_stub(host, port): + method_implementations = { + "SayHello": utilities.unary_unary_inline(None), + } + import helloworld_pb2 + response_deserializers = { + "SayHello": helloworld_pb2.HelloReply.FromString, + } + request_serializers = { + "SayHello": lambda x: x.SerializeToString(), + } + link = rear.activated_rear_link(host, port, request_serializers, response_deserializers) + return implementations.assemble_dynamic_inline_stub(method_implementations, link) +# @@protoc_insertion_point(module_scope) diff --git a/python/helloworld/run_client.sh b/python/helloworld/run_client.sh new file mode 100755 index 0000000000..095e6bc2f0 --- /dev/null +++ b/python/helloworld/run_client.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# This is where you have cloned out the https://github.com/grpc/grpc repository +# And built gRPC Python. +# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS +GRPC_ROOT=~/github/grpc + +$GRPC_ROOT/python2.7_virtual_environment/bin/python greeter_client.py diff --git a/python/helloworld/run_codegen.sh b/python/helloworld/run_codegen.sh new file mode 100755 index 0000000000..ed40386bc0 --- /dev/null +++ b/python/helloworld/run_codegen.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Runs the protoc with gRPC plugin to generate protocol messages and gRPC stubs. +protoc -I . --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` helloworld.proto diff --git a/python/helloworld/run_server.sh b/python/helloworld/run_server.sh new file mode 100755 index 0000000000..13b009e6cc --- /dev/null +++ b/python/helloworld/run_server.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# This is where you have cloned out the https://github.com/grpc/grpc repository +# And built gRPC Python. +# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS +GRPC_ROOT=~/github/grpc + +$GRPC_ROOT/python2.7_virtual_environment/bin/python greeter_server.py + -- cgit v1.2.3 From 1a0043c84826fc155fe980af0a76ee5a6ef0e876 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 25 Feb 2015 15:16:07 -0800 Subject: Added route guide tutorial for Node.js --- node/route_guide/README.md | 375 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 375 insertions(+) create mode 100644 node/route_guide/README.md diff --git a/node/route_guide/README.md b/node/route_guide/README.md new file mode 100644 index 0000000000..175431258d --- /dev/null +++ b/node/route_guide/README.md @@ -0,0 +1,375 @@ +#gRPC Basics: Node.js + +This tutorial provides a basic Node.js programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate server and client code using the protocol buffer compiler. +- Use the C++ gRPC API to write a simple client and server for your service. + +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. + +This isn't a comprehensive guide to using gRPC in Node.js: more reference documentation is coming soon. + +## Why use gRPC? + +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/node/route_guide](https://github.com/grpc/grpc-common/tree/master/node/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/google/grpc-common.git +``` + +Then change your current directory to `grpc-common/node/route_guide`: +```shell +$ cd grpc-common/node/route_guide +``` + +You also should have the relevant tools installed to generate the server and client interface code - if yofu don't already, follow the setup instructions in [the Node.js quick start guide](https://github.com/grpc/grpc-common/tree/master/node). + + +## Defining the service + +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +```protobuf +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +```protobuf + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. +```protobuf + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} +``` + +- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. +```protobuf + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +```protobuf + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +```protobuf +// 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; +} +``` + + +## Generating client and server code + +Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. + +For simplicity, we've provided a [makefile](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): + +```shell +$ make route_guide.pb.cc +``` + +which actually runs: + +```shell +$ protoc -I ../../protos --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ../../protos/route_guide.proto +``` + +Running this command generates the following files in your current directory: +- `route_guide.pb.h`, the header which declares your generated classes +- `route_guide.pb.cc`, which contains the implementation of your classes + +These contain: +- All the protocol buffer code to populate, serialize, and retrieve our request and response message types +- A class called `RouteGuide` that contains + - a remote interface type (or *stub*) for clients to call with the methods defined in the `RouteGuide` service. + - two abstract interfaces for servers to implement, also with the methods defined in the `RouteGuide` service. + + + +## Creating the server + +First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). + +There are two parts to making our `RouteGuide` service do its job: +- Implementing the service interface generated from our service definition: doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and return the service responses. + +You can find our example `RouteGuide` server in [grpc-common/node/route_guide/route_guide_server.js](https://github.com/grpc/grpc-common/blob/master/node/route_guide/route_guide_server.js). Let's take a closer look at how it works. + +### Implementing RouteGuide + +As you can see, our server has a `Server` constructor generated from the `RouteGuide.service` descriptor object + +```node +var Server = grpc.buildServer([examples.RouteGuide.service]); +``` +In this case we're implementing the *asynchronous* version of `RouteGuide`, which provides our default gRPC server behaviour. + +The functions in `route_guide_server.js` implement all our service methods. Let's look at the simplest type first, `getFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. + +```node +function checkFeature(point) { + var feature; + // Check if there is already a feature object for the given point + for (var i = 0; i < feature_list.length; i++) { + feature = feature_list[i]; + if (feature.location.latitude === point.latitude && + feature.location.longitude === point.longitude) { + return feature; + } + } + var name = ''; + feature = { + name: name, + location: point + }; + return feature; +} +function getFeature(call, callback) { + callback(null, checkFeature(call.request)); +} +``` + +The method is passed a call object for the RPC, which has the `Point` parameter as a property, and a callback to be passed the resulting `Feature`. In the method we populate a `Feature` corresponding to the given point and pass it to the callback, with a null first parameter to indicate that there is no error. + +Now let's look at something a bit more complicated - a streaming RPC. `listFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. + +```node +function listFeatures(call) { + var lo = call.request.lo; + var hi = call.request.hi; + var left = _.min([lo.longitude, hi.longitude]); + var right = _.max([lo.longitude, hi.longitude]); + var top = _.max([lo.latitude, hi.latitude]); + var bottom = _.min([lo.latitude, hi.latitude]); + // For each feature, check if it is in the given bounding box + _.each(feature_list, function(feature) { + if (feature.name === '') { + return; + } + if (feature.location.longitude >= left && + feature.location.longitude <= right && + feature.location.latitude >= bottom && + feature.location.latitude <= top) { + call.write(feature); + } + }); + call.end(); +} +``` + +As you can see, instead of getting the call object and callback in our method parameters, this time we get a call object that implements the `Writable` interface. In the method, we create as many `Feature` objects as we need to return, writing them to the `call` using its `write()` method. Finally, we call `call.end()` to indicate that we have sent all messages. + +If you look at the client-side streaming method `RecordRoute` you'll see it's quite similar to the unary call, except this time the `call` parameter implements the `Reader` interface. The `call`'s `'data'` event fires every time there is new data, and the `'end'` event fires when all data has been read. Like the unary case, we respond by calling the callback + +```node +call.on('data', function(point) { + // Process user data +}); +call.on('end', function() { + callback(null, result); +}); +``` + +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. + +```node +function routeChat(call) { + call.on('data', function(note) { + var key = pointKey(note.location); + /* For each note sent, respond with all previous notes that correspond to + * the same point */ + if (route_notes.hasOwnProperty(key)) { + _.each(route_notes[key], function(note) { + call.write(note); + }); + } else { + route_notes[key] = []; + } + // Then add the new note to the list + route_notes[key].push(JSON.parse(JSON.stringify(note))); + }); + call.on('end', function() { + call.end(); + }); +} +``` + +This time we get a `call` implementing `Duplex` that can be used to read *and* write messages. The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + +### Starting the server + +Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: + +```node +function getServer() { + return new Server({ + 'examples.RouteGuide' : { + getFeature: getFeature, + listFeatures: listFeatures, + recordRoute: recordRoute, + routeChat: routeChat + } + }); +} +var routeServer = getServer(); +routeServer.bind('0.0.0.0:50051'); +routeServer.listen(); +``` + +As you can see, we build and start our server with the following steps: + + 1. Create a `Server` constructor from the `RouteGuide` service descriptor. + 2. Implement the service methods. + 3. Create an instance of the server by calling the `Server` constructor with the method implementations. + 4. Specify the address and port we want to use to listen for client requests using the instance's `bind()` method. + 5. Call `listen()` on the instance to start the RPC server. + + +## Creating the client + +In this section, we'll look at creating a Node.js client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/node/route_guide/route_guide_client.js](https://github.com/grpc/grpc-common/blob/master/node/route_guide/route_guide_client.js). + +### Creating a stub + +To call service methods, we first need to create a *stub*. To do this, we just need to call the RouteGuide stub constructor, specifying the server address and port. + +```node +new example.RouteGuide('localhost:50051'); +``` + +### Calling service methods + +Now let's look at how we call our service methods. Note that all of these methods are asynchronous: they use either events or callbacks to retrieve results. + +#### Simple RPC + +Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local asynchronous method. + +```node +var point = {latitude: 409146138, longitude: -746188906}; +stub.getFeature(point, function(err, feature) { + if (err) { + // process error + } else { + // process feature + } +}); +``` + +As you can see, we create and populate a request object. Finally, we call the method on the stub, passing it the request and callback. If there is no error, then we can read the response information from the server from our response object. + +```node + console.log('Found feature called "' + feature.name + '" at ' + + feature.location.latitude/COORD_FACTOR + ', ' + + feature.location.longitude/COORD_FACTOR); +``` + +#### Streaming RPCs + +Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: + +```cpp +var call = client.listFeatures(rectangle); + call.on('data', function(feature) { + console.log('Found feature called "' + feature.name + '" at ' + + feature.location.latitude/COORD_FACTOR + ', ' + + feature.location.longitude/COORD_FACTOR); + }); + call.on('end', function() { + // The server has finished sending + }); + call.on('status', function(status) { + // process status + }); +``` + +Instead of passing the method a request and callback, we pass it a request and get a `Readable` stream object back. The client can use the `Readable`'s `'data'` event to read the server's responses. This event fires with each `Feature` message object until there are no more messages: the `'end'` event indicates that the call is done. Finally, the status event fires when the server sends the status. + +The client-side streaming method `RecordRoute` is similar, except there we pass the method a callback and get back a `Writable`. + +```cpp + var call = client.recordRoute(function(error, stats) { + if (error) { + callback(error); + } + console.log('Finished trip with', stats.point_count, 'points'); + console.log('Passed', stats.feature_count, 'features'); + console.log('Travelled', stats.distance, 'meters'); + console.log('It took', stats.elapsed_time, 'seconds'); + }); + function pointSender(lat, lng) { + return function(callback) { + console.log('Visiting point ' + lat/COORD_FACTOR + ', ' + + lng/COORD_FACTOR); + call.write({ + latitude: lat, + longitude: lng + }); + _.delay(callback, _.random(500, 1500)); + }; + } + var point_senders = []; + for (var i = 0; i < num_points; i++) { + var rand_point = feature_list[_.random(0, feature_list.length - 1)]; + point_senders[i] = pointSender(rand_point.location.latitude, + rand_point.location.longitude); + } + async.series(point_senders, function() { + call.end(); + }); +``` + +Once we've finished writing our client's requests to the stream using `write()`, we need to call `end()` on the stream to let gRPC know that we've finished writing. If the status is `OK`, the `stats` object will be populated with the server's response. + +Finally, let's look at our bidirectional streaming RPC `routeChat()`. In this case, we just pass a context to the method and get back a `Duplex` stream object, which we can use to both write and read messages. + +```cpp +var call = client.routeChat(); +``` + +The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + +## Try it out! + +Build client and server: +```shell +$ npm install +``` +Run the server, which will listen on port 50051: +```shell +$ node ./route_guide_server.js +``` +Run the client (in a different terminal): +```shell +$ node ./route_guide_client.js +``` -- cgit v1.2.3 From bc4b1cecb8ea6b4079da023dc70e93c0c8387052 Mon Sep 17 00:00:00 2001 From: Dan Ciruli Date: Wed, 25 Feb 2015 15:22:58 -0800 Subject: Update README.md --- ruby/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ruby/README.md b/ruby/README.md index 3818b91433..c5902a3039 100644 --- a/ruby/README.md +++ b/ruby/README.md @@ -1,6 +1,10 @@ gRPC in 3 minutes (Ruby) ======================== +BACKGROUND +------------- +For this sample, we've already generated the server and client stubs from [helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). + PREREQUISITES ------------- -- cgit v1.2.3 From 83fed7a1377b44c23644d78ab13a2b5c713ede8e Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 25 Feb 2015 15:27:22 -0800 Subject: Added proto explanation, plus minor corrections --- node/route_guide/README.md | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/node/route_guide/README.md b/node/route_guide/README.md index 175431258d..3e0549b19c 100644 --- a/node/route_guide/README.md +++ b/node/route_guide/README.md @@ -3,8 +3,7 @@ This tutorial provides a basic Node.js programmer's introduction to working with gRPC. By walking through this example you'll learn how to: - Define a service in a .proto file. -- Generate server and client code using the protocol buffer compiler. -- Use the C++ gRPC API to write a simple client and server for your service. +- Use the Node.js gRPC API to write a simple client and server for your service. It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. @@ -87,32 +86,20 @@ message Point { ``` -## Generating client and server code +## Loading service descriptors from proto files -Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. +The Node.js library dynamically generates service descriptors and client stub definitions from `.proto` files loaded at runtime. -For simplicity, we've provided a [makefile](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): +To load a `.proto` file, simply `require` the gRPC library, then use its `load()` method to load the proto file: -```shell -$ make route_guide.pb.cc -``` - -which actually runs: - -```shell -$ protoc -I ../../protos --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ../../protos/route_guide.proto +```node +var grpc = require('grpc'); +var protoDescriptor = grpc.load(__dirname + '/route_guide.proto'); +// The protoDescriptor object has the full package hierarchy +var example = protoDescriptor.examples; ``` -Running this command generates the following files in your current directory: -- `route_guide.pb.h`, the header which declares your generated classes -- `route_guide.pb.cc`, which contains the implementation of your classes - -These contain: -- All the protocol buffer code to populate, serialize, and retrieve our request and response message types -- A class called `RouteGuide` that contains - - a remote interface type (or *stub*) for clients to call with the methods defined in the `RouteGuide` service. - - two abstract interfaces for servers to implement, also with the methods defined in the `RouteGuide` service. - +Then, the stub constructor is in the examples namespace (`protoDescriptor.examples.RouteGuide`) and the service descriptor (which is used to create a server) is a property of the stub (`protoDescriptor.examples.RouteGuide.service`); ## Creating the server @@ -298,7 +285,7 @@ As you can see, we create and populate a request object. Finally, we call the me Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: -```cpp +```node var call = client.listFeatures(rectangle); call.on('data', function(feature) { console.log('Found feature called "' + feature.name + '" at ' + @@ -317,7 +304,7 @@ Instead of passing the method a request and callback, we pass it a request and g The client-side streaming method `RecordRoute` is similar, except there we pass the method a callback and get back a `Writable`. -```cpp +```node var call = client.recordRoute(function(error, stats) { if (error) { callback(error); @@ -353,7 +340,7 @@ Once we've finished writing our client's requests to the stream using `write()`, Finally, let's look at our bidirectional streaming RPC `routeChat()`. In this case, we just pass a context to the method and get back a `Duplex` stream object, which we can use to both write and read messages. -```cpp +```node var call = client.routeChat(); ``` -- cgit v1.2.3 From b224d6a50008f60ebe4983c87d5d386175d9d9c3 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Wed, 25 Feb 2015 16:03:09 -0800 Subject: Update the comment of GetFeature to clarify its unintuitive behavior --- protos/route_guide.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/protos/route_guide.proto b/protos/route_guide.proto index 7cda80efad..37590490f4 100644 --- a/protos/route_guide.proto +++ b/protos/route_guide.proto @@ -38,6 +38,9 @@ service RouteGuide { // A simple RPC. // // Obtains the feature at a given position. + // + // A feature with an empty name is returned if there's no feature at the given + // position. rpc GetFeature(Point) returns (Feature) {} // A server-to-client streaming RPC. -- cgit v1.2.3 From 312f6a585bdfb6a6d9b77b6ed555c67a223564f7 Mon Sep 17 00:00:00 2001 From: Xiao Hang Date: Wed, 25 Feb 2015 16:21:24 -0800 Subject: gRPC Android Helloworld example --- android/GreeterGrpc.java | 184 ++++++++++++++++++++++++++++++++++++++++ android/Helloworld.java | 175 ++++++++++++++++++++++++++++++++++++++ android/HelloworldActivity.java | 92 ++++++++++++++++++++ android/README.md | 72 ++++++++++++++++ android/activity_helloworld.xml | 54 ++++++++++++ 5 files changed, 577 insertions(+) create mode 100644 android/GreeterGrpc.java create mode 100644 android/Helloworld.java create mode 100644 android/HelloworldActivity.java create mode 100644 android/README.md create mode 100644 android/activity_helloworld.xml diff --git a/android/GreeterGrpc.java b/android/GreeterGrpc.java new file mode 100644 index 0000000000..eaef3679d2 --- /dev/null +++ b/android/GreeterGrpc.java @@ -0,0 +1,184 @@ +package io.grpc.examples; + +import static io.grpc.stub.Calls.createMethodDescriptor; +import static io.grpc.stub.Calls.asyncUnaryCall; +import static io.grpc.stub.Calls.asyncServerStreamingCall; +import static io.grpc.stub.Calls.asyncClientStreamingCall; +import static io.grpc.stub.Calls.duplexStreamingCall; +import static io.grpc.stub.Calls.blockingUnaryCall; +import static io.grpc.stub.Calls.blockingServerStreamingCall; +import static io.grpc.stub.Calls.unaryFutureCall; +import static io.grpc.stub.ServerCalls.createMethodDefinition; +import static io.grpc.stub.ServerCalls.asyncUnaryRequestCall; +import static io.grpc.stub.ServerCalls.asyncStreamingRequestCall; + +import java.io.IOException; + +public class GreeterGrpc { + + private static final io.grpc.stub.Method METHOD_SAY_HELLO = + io.grpc.stub.Method.create( + io.grpc.MethodType.UNARY, "SayHello", + io.grpc.nano.NanoUtils.marshaller( + new io.grpc.nano.Parser() { + @Override + public io.grpc.examples.Helloworld.HelloRequest parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return io.grpc.examples.Helloworld.HelloRequest.parseFrom(input); + } + }), + io.grpc.nano.NanoUtils.marshaller( + new io.grpc.nano.Parser() { + @Override + public io.grpc.examples.Helloworld.HelloReply parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return io.grpc.examples.Helloworld.HelloReply.parseFrom(input); + } + })); + + public static GreeterStub newStub(io.grpc.Channel channel) { + return new GreeterStub(channel, CONFIG); + } + + public static GreeterBlockingStub newBlockingStub( + io.grpc.Channel channel) { + return new GreeterBlockingStub(channel, CONFIG); + } + + public static GreeterFutureStub newFutureStub( + io.grpc.Channel channel) { + return new GreeterFutureStub(channel, CONFIG); + } + + public static final GreeterServiceDescriptor CONFIG = + new GreeterServiceDescriptor(); + + public static class GreeterServiceDescriptor extends + io.grpc.stub.AbstractServiceDescriptor { + public final io.grpc.MethodDescriptor sayHello; + + private GreeterServiceDescriptor() { + sayHello = createMethodDescriptor( + "helloworld.Greeter", METHOD_SAY_HELLO); + } + + private GreeterServiceDescriptor( + java.util.Map> methodMap) { + sayHello = (io.grpc.MethodDescriptor) methodMap.get( + CONFIG.sayHello.getName()); + } + + @java.lang.Override + protected GreeterServiceDescriptor build( + java.util.Map> methodMap) { + return new GreeterServiceDescriptor(methodMap); + } + + @java.lang.Override + public com.google.common.collect.ImmutableList> methods() { + return com.google.common.collect.ImmutableList.>of( + sayHello); + } + } + + public static interface Greeter { + + public void sayHello(io.grpc.examples.Helloworld.HelloRequest request, + io.grpc.stub.StreamObserver responseObserver); + } + + public static interface GreeterBlockingClient { + + public io.grpc.examples.Helloworld.HelloReply sayHello(io.grpc.examples.Helloworld.HelloRequest request); + } + + public static interface GreeterFutureClient { + + public com.google.common.util.concurrent.ListenableFuture sayHello( + io.grpc.examples.Helloworld.HelloRequest request); + } + + public static class GreeterStub extends + io.grpc.stub.AbstractStub + implements Greeter { + private GreeterStub(io.grpc.Channel channel, + GreeterServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected GreeterStub build(io.grpc.Channel channel, + GreeterServiceDescriptor config) { + return new GreeterStub(channel, config); + } + + @java.lang.Override + public void sayHello(io.grpc.examples.Helloworld.HelloRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + channel.newCall(config.sayHello), request, responseObserver); + } + } + + public static class GreeterBlockingStub extends + io.grpc.stub.AbstractStub + implements GreeterBlockingClient { + private GreeterBlockingStub(io.grpc.Channel channel, + GreeterServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected GreeterBlockingStub build(io.grpc.Channel channel, + GreeterServiceDescriptor config) { + return new GreeterBlockingStub(channel, config); + } + + @java.lang.Override + public io.grpc.examples.Helloworld.HelloReply sayHello(io.grpc.examples.Helloworld.HelloRequest request) { + return blockingUnaryCall( + channel.newCall(config.sayHello), request); + } + } + + public static class GreeterFutureStub extends + io.grpc.stub.AbstractStub + implements GreeterFutureClient { + private GreeterFutureStub(io.grpc.Channel channel, + GreeterServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected GreeterFutureStub build(io.grpc.Channel channel, + GreeterServiceDescriptor config) { + return new GreeterFutureStub(channel, config); + } + + @java.lang.Override + public com.google.common.util.concurrent.ListenableFuture sayHello( + io.grpc.examples.Helloworld.HelloRequest request) { + return unaryFutureCall( + channel.newCall(config.sayHello), request); + } + } + + public static io.grpc.ServerServiceDefinition bindService( + final Greeter serviceImpl) { + return io.grpc.ServerServiceDefinition.builder("helloworld.Greeter") + .addMethod(createMethodDefinition( + METHOD_SAY_HELLO, + asyncUnaryRequestCall( + new io.grpc.stub.ServerCalls.UnaryRequestMethod< + io.grpc.examples.Helloworld.HelloRequest, + io.grpc.examples.Helloworld.HelloReply>() { + @java.lang.Override + public void invoke( + io.grpc.examples.Helloworld.HelloRequest request, + io.grpc.stub.StreamObserver responseObserver) { + serviceImpl.sayHello(request, responseObserver); + } + }))).build(); + } +} diff --git a/android/Helloworld.java b/android/Helloworld.java new file mode 100644 index 0000000000..35dd534512 --- /dev/null +++ b/android/Helloworld.java @@ -0,0 +1,175 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +package io.grpc.examples; + +@SuppressWarnings("hiding") +public interface Helloworld { + + public static final class HelloRequest extends + com.google.protobuf.nano.MessageNano { + + private static volatile HelloRequest[] _emptyArray; + public static HelloRequest[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized ( + com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new HelloRequest[0]; + } + } + } + return _emptyArray; + } + + // optional string name = 1; + public java.lang.String name; + + public HelloRequest() { + clear(); + } + + public HelloRequest clear() { + name = ""; + cachedSize = -1; + return this; + } + + @Override + public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) + throws java.io.IOException { + if (!this.name.equals("")) { + output.writeString(1, this.name); + } + super.writeTo(output); + } + + @Override + protected int computeSerializedSize() { + int size = super.computeSerializedSize(); + if (!this.name.equals("")) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeStringSize(1, this.name); + } + return size; + } + + @Override + public HelloRequest mergeFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: { + if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { + return this; + } + break; + } + case 10: { + this.name = input.readString(); + break; + } + } + } + } + + public static HelloRequest parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new HelloRequest(), data); + } + + public static HelloRequest parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + return new HelloRequest().mergeFrom(input); + } + } + + public static final class HelloReply extends + com.google.protobuf.nano.MessageNano { + + private static volatile HelloReply[] _emptyArray; + public static HelloReply[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized ( + com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new HelloReply[0]; + } + } + } + return _emptyArray; + } + + // optional string message = 1; + public java.lang.String message; + + public HelloReply() { + clear(); + } + + public HelloReply clear() { + message = ""; + cachedSize = -1; + return this; + } + + @Override + public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) + throws java.io.IOException { + if (!this.message.equals("")) { + output.writeString(1, this.message); + } + super.writeTo(output); + } + + @Override + protected int computeSerializedSize() { + int size = super.computeSerializedSize(); + if (!this.message.equals("")) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeStringSize(1, this.message); + } + return size; + } + + @Override + public HelloReply mergeFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: { + if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { + return this; + } + break; + } + case 10: { + this.message = input.readString(); + break; + } + } + } + } + + public static HelloReply parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new HelloReply(), data); + } + + public static HelloReply parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + return new HelloReply().mergeFrom(input); + } + } +} diff --git a/android/HelloworldActivity.java b/android/HelloworldActivity.java new file mode 100644 index 0000000000..eb4e93b555 --- /dev/null +++ b/android/HelloworldActivity.java @@ -0,0 +1,92 @@ +package io.grpc.helloworld; + +import android.content.Context; +import android.support.v7.app.ActionBarActivity; +import android.os.Bundle; +import android.os.AsyncTask; +import android.text.TextUtils; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; + +import io.grpc.ChannelImpl; +import ex.grpc.GreeterGrpc; +import ex.grpc.Helloworld.HelloRequest; +import ex.grpc.Helloworld.HelloReply; +import io.grpc.transport.okhttp.OkHttpChannelBuilder; + +import java.util.concurrent.TimeUnit; + +public class Helloworld extends ActionBarActivity { + private Button mSendButton; + private EditText mHostEdit; + private EditText mPortEdit; + private EditText mMessageEdit; + private TextView mResultText; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_helloworld); + mSendButton = (Button) findViewById(R.id.send_button); + mHostEdit = (EditText) findViewById(R.id.host_edit_text); + mPortEdit = (EditText) findViewById(R.id.port_edit_text); + mMessageEdit = (EditText) findViewById(R.id.message_edit_text); + mResultText = (TextView) findViewById(R.id.grpc_response_text); + } + + public void sendMessage(View view) { + ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)) + .hideSoftInputFromWindow(mHostEdit.getWindowToken(), 0); + mSendButton.setEnabled(false); + new GrpcTask().execute(); + } + + private class GrpcTask extends AsyncTask { + private String mHost; + private String mMessage; + private int mPort; + private ChannelImpl mChannel; + + @Override + protected void onPreExecute() { + mHost = mHostEdit.getText().toString(); + mMessage = mMessageEdit.getText().toString(); + String portStr = mPortEdit.getText().toString(); + mPort = TextUtils.isEmpty(portStr) ? 0 : Integer.valueOf(portStr); + mResultText.setText(""); + } + + private String sayHello(ChannelImpl channel) { + GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel); + HelloRequest message = new HelloRequest(); + message.name = mMessage; + HelloReply reply = stub.sayHello(message); + return reply.message; + } + + @Override + protected String doInBackground(Void... nothing) { + try { + mChannel = OkHttpChannelBuilder.forAddress(mHost, mPort).build(); + return sayHello(mChannel); + } catch (Exception e) { + return "Failed... : " + e.getMessage(); + } + } + + @Override + protected void onPostExecute(String result) { + try { + mChannel.shutdown().awaitTerminated(1, TimeUnit.SECONDS); + } catch (InterruptedException e) { + } + mResultText.setText(result); + mSendButton.setEnabled(true); + } + } +} \ No newline at end of file diff --git a/android/README.md b/android/README.md new file mode 100644 index 0000000000..013e20c754 --- /dev/null +++ b/android/README.md @@ -0,0 +1,72 @@ +gRPC Hello World Tutorial (gRPC Java on Android) +======================== + +BACKGROUND +------------- +For this sample, we've already generated the server and client stubs from [helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). + +PREREQUISITES +------------- +- [Java gRPC](https://github.com/grpc/grpc-java) + +- [Android Tutorial](https://developer.android.com/training/basics/firstapp/index.html) If you're new to Android development + +- We only have Android gRPC client in this example. Please follow examples in other languages to build and run a gRPC server. + +INSTALL +------- +1 Clone the gRPC Java git repo +```sh +$ cd $grpc_java_dir$ +$ git clone https://github.com/grpc/grpc-java +``` + +2 Install gRPC Java, as described in [How to Build](https://github.com/grpc/grpc-java#how-to-build) +```sh +$ # from this dir +$ cd grpc-java +$ # follow the instructions in 'How to Build' +``` + +3 [Create an Android project](https://developer.android.com/training/basics/firstapp/creating-project.html) under your working directory. +- Set Application name to "Helloworld Example" and set Company Domain to "grpc.io". Make sure your package name is "io.grpc.helloworldexample" +- Choose appropriate minimum SDK +- Use Blank Activity +- Set Activity Name to HelloworldActivity +- Set Layout Name to activity_helloworld + +4 Prepare the app +- Clone this git repo +```sh +$ git clone https://github.com/grpc/grpc-common + +``` +- Replace the generated HelloworldActivity.java and activity_helloworld.xml with the two files in this repo +- Copy GreeterGrpc.java and Helloworld.java under $working_dir$/app/src/main/java/io/grpc/examples/ +- In your AndroidManifest.xml, make sure you have +```sh + +``` +added outside your appplication tag + +5 Add dependencies. gRPC Java on Android depends on grpc-java, protobuf nano, okhttp +- Copy grpc-java .jar files to $working_dir$/app/libs/: + - $grpc-java-dir$/core/build/libs/*.jar + - $grpc-java-dir$/stub/build/libs/*.jar + - $grpc-java-dir$/nano/build/libs/*.jar + - $grpc-java-dir$/okhttp/build/libs/*.jar +- Copy or download other dependencies to $working_dir$/app/libs/: + - protobuf nano: +```sh +$ cp ~/.m2/repository/com/google/protobuf/nano/protobuf-javanano/2.6.2-pre/protobuf-javanano-2.6.2-pre.jar $working_dir$/app/libs/ +``` + - [Guava 18](http://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar) + - [okhttp 2.2.0](http://repo1.maven.org/maven2/com/squareup/okhttp/okhttp/2.2.0/okhttp-2.2.0.jar) +- Make sure your app/build.gradle contains: +```sh +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) +} +``` + +6 [Run your example app](https://developer.android.com/training/basics/firstapp/running-app.html) diff --git a/android/activity_helloworld.xml b/android/activity_helloworld.xml new file mode 100644 index 0000000000..41411d11aa --- /dev/null +++ b/android/activity_helloworld.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + @@ -47,7 +93,7 @@ - + diff --git a/objective-c/auth_sample/SelectUserViewController.h b/objective-c/auth_sample/SelectUserViewController.h new file mode 100644 index 0000000000..eb3c2cf5f0 --- /dev/null +++ b/objective-c/auth_sample/SelectUserViewController.h @@ -0,0 +1,42 @@ +/* + * + * 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. + * + */ + +#import +#import + +@interface SelectUserViewController : UIViewController +@property(weak, nonatomic) IBOutlet GIDSignInButton *signInButton; +@property(weak, nonatomic) IBOutlet UIButton *signOutButton; +@property(weak, nonatomic) IBOutlet UILabel *mainLabel; +@property(weak, nonatomic) IBOutlet UILabel *subLabel; +@end diff --git a/objective-c/auth_sample/SelectUserViewController.m b/objective-c/auth_sample/SelectUserViewController.m new file mode 100644 index 0000000000..5e030565ef --- /dev/null +++ b/objective-c/auth_sample/SelectUserViewController.m @@ -0,0 +1,76 @@ +/* + * + * 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. + * + */ + +#import "SelectUserViewController.h" + +@implementation SelectUserViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.signOutButton.layer.cornerRadius = 5; + self.signOutButton.hidden = YES; + + // As instructed in https://developers.google.com/identity/sign-in/ios/sign-in + GIDSignIn.sharedInstance.delegate = self; + GIDSignIn.sharedInstance.uiDelegate = self; + + [GIDSignIn.sharedInstance signInSilently]; +} + +- (void)signIn:(GIDSignIn *)signIn +didSignInForUser:(GIDGoogleUser *)user + withError:(NSError *)error { + if (error) { + // The user probably cancelled the sign-in flow. + return; + } + + self.mainLabel.text = [NSString stringWithFormat:@"User: %@", user.profile.email]; + NSString *scopes = [user.accessibleScopes componentsJoinedByString:@", "]; + scopes = scopes.length ? scopes : @"(none)"; + self.subLabel.text = [NSString stringWithFormat:@"Scopes: %@", scopes]; + + self.signInButton.hidden = YES; + self.signOutButton.hidden = NO; +} + +- (IBAction)didTapSignOut { + [GIDSignIn.sharedInstance signOut]; + self.mainLabel.text = @"Please sign in."; + self.subLabel.text = @""; + self.signInButton.hidden = NO; + self.signOutButton.hidden = YES; +} + +@end -- cgit v1.2.3 From 3600977997c6f1b5e9bbdde7513872c276f040eb Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Thu, 11 Jun 2015 13:10:38 -0700 Subject: Request test scope --- objective-c/auth_sample/SecondViewController.h | 3 ++- objective-c/auth_sample/SecondViewController.m | 4 ++++ objective-c/auth_sample/SelectUserViewController.m | 16 +++++++++++++--- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/objective-c/auth_sample/SecondViewController.h b/objective-c/auth_sample/SecondViewController.h index 06a3ca012a..3e5ccf95a4 100644 --- a/objective-c/auth_sample/SecondViewController.h +++ b/objective-c/auth_sample/SecondViewController.h @@ -33,6 +33,7 @@ #import -@interface SecondViewController : UIViewController +extern NSString * const kTestScope; +@interface SecondViewController : UIViewController @end diff --git a/objective-c/auth_sample/SecondViewController.m b/objective-c/auth_sample/SecondViewController.m index aa9e5b673e..d5ba19a7ab 100644 --- a/objective-c/auth_sample/SecondViewController.m +++ b/objective-c/auth_sample/SecondViewController.m @@ -33,6 +33,10 @@ #import "SecondViewController.h" +#import + +NSString * const kTestScope = @"https://www.googleapis.com/auth/xapi.zoo"; + @implementation SecondViewController - (void)viewDidLoad { diff --git a/objective-c/auth_sample/SelectUserViewController.m b/objective-c/auth_sample/SelectUserViewController.m index 5e030565ef..e54e9f866a 100644 --- a/objective-c/auth_sample/SelectUserViewController.m +++ b/objective-c/auth_sample/SelectUserViewController.m @@ -33,6 +33,8 @@ #import "SelectUserViewController.h" +#import "SecondViewController.h" + @implementation SelectUserViewController - (void)viewDidLoad { @@ -42,10 +44,16 @@ self.signOutButton.hidden = YES; // As instructed in https://developers.google.com/identity/sign-in/ios/sign-in - GIDSignIn.sharedInstance.delegate = self; - GIDSignIn.sharedInstance.uiDelegate = self; + GIDSignIn *signIn = GIDSignIn.sharedInstance; + signIn.delegate = self; + signIn.uiDelegate = self; + + // As instructed in https://developers.google.com/identity/sign-in/ios/additional-scopes + if (![signIn.scopes containsObject:kTestScope]) { + signIn.scopes = [signIn.scopes arrayByAddingObject:kTestScope]; + } - [GIDSignIn.sharedInstance signInSilently]; + [signIn signInSilently]; } - (void)signIn:(GIDSignIn *)signIn @@ -67,8 +75,10 @@ didSignInForUser:(GIDGoogleUser *)user - (IBAction)didTapSignOut { [GIDSignIn.sharedInstance signOut]; + self.mainLabel.text = @"Please sign in."; self.subLabel.text = @""; + self.signInButton.hidden = NO; self.signOutButton.hidden = YES; } -- cgit v1.2.3 From 64428acf977dfe761cd1348c4486a6a2a6bfcb8e Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Thu, 11 Jun 2015 15:21:55 -0700 Subject: Add MakeRPCViewController with authenticated RPC --- .../AuthSample.xcodeproj/project.pbxproj | 12 +-- objective-c/auth_sample/MakeRPCViewController.h | 40 ++++++++++ objective-c/auth_sample/MakeRPCViewController.m | 89 ++++++++++++++++++++++ .../auth_sample/Misc/Base.lproj/Main.storyboard | 27 +++---- objective-c/auth_sample/SecondViewController.h | 39 ---------- objective-c/auth_sample/SecondViewController.m | 47 ------------ objective-c/auth_sample/SelectUserViewController.m | 2 +- 7 files changed, 148 insertions(+), 108 deletions(-) create mode 100644 objective-c/auth_sample/MakeRPCViewController.h create mode 100644 objective-c/auth_sample/MakeRPCViewController.m delete mode 100644 objective-c/auth_sample/SecondViewController.h delete mode 100644 objective-c/auth_sample/SecondViewController.m diff --git a/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj index dd4778ebeb..1e983ca361 100644 --- a/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj +++ b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj @@ -10,7 +10,7 @@ 63E1E9821B28CB2100EF0978 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9811B28CB2100EF0978 /* main.m */; }; 63E1E9851B28CB2100EF0978 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9841B28CB2100EF0978 /* AppDelegate.m */; }; 63E1E9881B28CB2100EF0978 /* SelectUserViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9871B28CB2100EF0978 /* SelectUserViewController.m */; }; - 63E1E98B1B28CB2100EF0978 /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */; }; + 63E1E98B1B28CB2100EF0978 /* MakeRPCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E98A1B28CB2100EF0978 /* MakeRPCViewController.m */; }; 63E1E98E1B28CB2100EF0978 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 63E1E98C1B28CB2100EF0978 /* Main.storyboard */; }; 63E1E9901B28CB2100EF0978 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 63E1E98F1B28CB2100EF0978 /* Images.xcassets */; }; 63F5DE481B28F5C100CDD07E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */; }; @@ -25,8 +25,8 @@ 63E1E9841B28CB2100EF0978 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 63E1E9861B28CB2100EF0978 /* SelectUserViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SelectUserViewController.h; sourceTree = ""; }; 63E1E9871B28CB2100EF0978 /* SelectUserViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SelectUserViewController.m; sourceTree = ""; }; - 63E1E9891B28CB2100EF0978 /* SecondViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecondViewController.h; sourceTree = ""; }; - 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecondViewController.m; sourceTree = ""; }; + 63E1E9891B28CB2100EF0978 /* MakeRPCViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MakeRPCViewController.h; sourceTree = ""; }; + 63E1E98A1B28CB2100EF0978 /* MakeRPCViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MakeRPCViewController.m; sourceTree = ""; }; 63E1E98D1B28CB2100EF0978 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 63E1E98F1B28CB2100EF0978 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; @@ -87,8 +87,8 @@ children = ( 63E1E9861B28CB2100EF0978 /* SelectUserViewController.h */, 63E1E9871B28CB2100EF0978 /* SelectUserViewController.m */, - 63E1E9891B28CB2100EF0978 /* SecondViewController.h */, - 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */, + 63E1E9891B28CB2100EF0978 /* MakeRPCViewController.h */, + 63E1E98A1B28CB2100EF0978 /* MakeRPCViewController.m */, 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */, 63E1E97F1B28CB2100EF0978 /* Supporting Files */, ); @@ -214,7 +214,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 63E1E98B1B28CB2100EF0978 /* SecondViewController.m in Sources */, + 63E1E98B1B28CB2100EF0978 /* MakeRPCViewController.m in Sources */, 63E1E9851B28CB2100EF0978 /* AppDelegate.m in Sources */, 63E1E9881B28CB2100EF0978 /* SelectUserViewController.m in Sources */, 63E1E9821B28CB2100EF0978 /* main.m in Sources */, diff --git a/objective-c/auth_sample/MakeRPCViewController.h b/objective-c/auth_sample/MakeRPCViewController.h new file mode 100644 index 0000000000..c75a8b3180 --- /dev/null +++ b/objective-c/auth_sample/MakeRPCViewController.h @@ -0,0 +1,40 @@ +/* + * + * 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. + * + */ + +#import + +extern NSString * const kTestScope; + +@interface MakeRPCViewController : UIViewController +@property(weak, nonatomic) IBOutlet UILabel *mainLabel; +@end diff --git a/objective-c/auth_sample/MakeRPCViewController.m b/objective-c/auth_sample/MakeRPCViewController.m new file mode 100644 index 0000000000..410ae7d92b --- /dev/null +++ b/objective-c/auth_sample/MakeRPCViewController.m @@ -0,0 +1,89 @@ +/* + * + * 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. + * + */ + +#import "MakeRPCViewController.h" + +#import +#import +#import +#include + +NSString * const kTestScope = @"https://www.googleapis.com/auth/xapi.zoo"; + +static NSString * const kTestHostAddress = @"grpc-test.sandbox.google.com"; + +@implementation MakeRPCViewController + +- (void)viewWillAppear:(BOOL)animated { + + // Create a service client and a proto request as usual. + AUTHTestService *client = [[AUTHTestService alloc] initWithHost:kTestHostAddress]; + + AUTHRequest *request = [AUTHRequest message]; + request.fillUsername = YES; + request.fillOauthScope = YES; + + // Create a not-yet-started RPC. We want to set the request headers on this object before starting + // it. + __block ProtoRPC *call = + [client RPCToUnaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { + if (response) { + // This test server responds with the email and scope of the access token it receives. + self.mainLabel.text = [NSString stringWithFormat:@"Used scope: %@ on behalf of user %@", + response.oauthScope, response.username]; + + } else if (error.code == GRPC_STATUS_UNAUTHENTICATED) { + // Authentication error. OAuth2 specifies we'll receive a challenge header. + NSString *challengeHeader = call.responseMetadata[@"www-authenticate"][0] ?: @""; + self.mainLabel.text = + [@"Invalid credentials. Server challenge:\n" stringByAppendingString:challengeHeader]; + + } else { + // Any other error. + self.mainLabel.text = [NSString stringWithFormat:@"Unexpected RPC error %li: %@", + (long)error.code, error.localizedDescription]; + } + }]; + + // Set the access token to be used. + NSString *accessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken; + call.requestMetadata = [NSMutableDictionary dictionaryWithDictionary: + @{@"Authorization": [@"Bearer " stringByAppendingString:accessToken]}]; + + // Start the RPC. + [call start]; + + self.mainLabel.text = @"Waiting for RPC to complete..."; +} + +@end diff --git a/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard b/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard index 761e7bffb0..fb29c124e2 100644 --- a/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard +++ b/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard @@ -2,6 +2,7 @@ + @@ -90,10 +91,10 @@ - + - + @@ -102,29 +103,25 @@ - - - - + + - + + + + diff --git a/objective-c/auth_sample/SecondViewController.h b/objective-c/auth_sample/SecondViewController.h deleted file mode 100644 index 3e5ccf95a4..0000000000 --- a/objective-c/auth_sample/SecondViewController.h +++ /dev/null @@ -1,39 +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. - * - */ - -#import - -extern NSString * const kTestScope; - -@interface SecondViewController : UIViewController -@end diff --git a/objective-c/auth_sample/SecondViewController.m b/objective-c/auth_sample/SecondViewController.m deleted file mode 100644 index d5ba19a7ab..0000000000 --- a/objective-c/auth_sample/SecondViewController.m +++ /dev/null @@ -1,47 +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. - * - */ - -#import "SecondViewController.h" - -#import - -NSString * const kTestScope = @"https://www.googleapis.com/auth/xapi.zoo"; - -@implementation SecondViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - // Do any additional setup after loading the view, typically from a nib. -} - -@end diff --git a/objective-c/auth_sample/SelectUserViewController.m b/objective-c/auth_sample/SelectUserViewController.m index e54e9f866a..954c531f3f 100644 --- a/objective-c/auth_sample/SelectUserViewController.m +++ b/objective-c/auth_sample/SelectUserViewController.m @@ -33,7 +33,7 @@ #import "SelectUserViewController.h" -#import "SecondViewController.h" +#import "MakeRPCViewController.h" @implementation SelectUserViewController -- cgit v1.2.3 From 98cbb3f1982fddafcff9d2b2ac364be8f7ccb46e Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 12 Jun 2015 12:38:16 -0700 Subject: Move OAuth2 plist into Misc folder --- objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj | 2 +- objective-c/auth_sample/GoogleService-Info.plist | 10 ---------- objective-c/auth_sample/Misc/GoogleService-Info.plist | 10 ++++++++++ 3 files changed, 11 insertions(+), 11 deletions(-) delete mode 100644 objective-c/auth_sample/GoogleService-Info.plist create mode 100644 objective-c/auth_sample/Misc/GoogleService-Info.plist diff --git a/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj index 1e983ca361..51a39c578c 100644 --- a/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj +++ b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj @@ -89,7 +89,6 @@ 63E1E9871B28CB2100EF0978 /* SelectUserViewController.m */, 63E1E9891B28CB2100EF0978 /* MakeRPCViewController.h */, 63E1E98A1B28CB2100EF0978 /* MakeRPCViewController.m */, - 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */, 63E1E97F1B28CB2100EF0978 /* Supporting Files */, ); name = AuthSample; @@ -99,6 +98,7 @@ isa = PBXGroup; children = ( 63E1E98C1B28CB2100EF0978 /* Main.storyboard */, + 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */, 63E1E98F1B28CB2100EF0978 /* Images.xcassets */, 63E1E9801B28CB2100EF0978 /* Info.plist */, 63E1E9831B28CB2100EF0978 /* AppDelegate.h */, diff --git a/objective-c/auth_sample/GoogleService-Info.plist b/objective-c/auth_sample/GoogleService-Info.plist deleted file mode 100644 index 86909d84a3..0000000000 --- a/objective-c/auth_sample/GoogleService-Info.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - CLIENT_ID - 15087385131-lh9bpkiai9nls53uadju0if6k7un3uih.apps.googleusercontent.com - REVERSED_CLIENT_ID - com.googleusercontent.apps.15087385131-lh9bpkiai9nls53uadju0if6k7un3uih - - \ No newline at end of file diff --git a/objective-c/auth_sample/Misc/GoogleService-Info.plist b/objective-c/auth_sample/Misc/GoogleService-Info.plist new file mode 100644 index 0000000000..86909d84a3 --- /dev/null +++ b/objective-c/auth_sample/Misc/GoogleService-Info.plist @@ -0,0 +1,10 @@ + + + + + CLIENT_ID + 15087385131-lh9bpkiai9nls53uadju0if6k7un3uih.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.15087385131-lh9bpkiai9nls53uadju0if6k7un3uih + + \ No newline at end of file -- cgit v1.2.3 From 3ea5cc927c733b8e8bba9f8bbce1f2ac8634ceb9 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 12 Jun 2015 16:06:37 -0700 Subject: Fixed path names in README --- objective-c/helloworld/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/objective-c/helloworld/README.md b/objective-c/helloworld/README.md index cb25882867..8f6d0d3a8d 100644 --- a/objective-c/helloworld/README.md +++ b/objective-c/helloworld/README.md @@ -17,10 +17,10 @@ following command: $ git clone https://github.com/grpc/grpc-common.git ``` -Change your current directory to `grpc-common/objective-c/HelloWorld` +Change your current directory to `grpc-common/objective-c/helloworld` ```sh -$ cd grpc-common/objective-c/HelloWorld +$ cd grpc-common/objective-c/helloworld ``` ### Try it! @@ -41,7 +41,7 @@ $ pod install This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet on your computer's cache). -Finally, open the XCode workspace created by Cocoapods, and run the app. You can check the calling code in `Supporting Files/main.m` and see the results in XCode's log console. +Finally, open the XCode workspace created by Cocoapods, and run the app. You can check the calling code in `main.m` and see the results in XCode's log console. The code sends a `HLWHelloRequest` containing the string "Objective-C" to a local server. The server responds with a `HLWHelloResponse`, which contains a string that is then output to the log. -- cgit v1.2.3 From a0117adab0f764f499e839eea922e070418c6f14 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 12 Jun 2015 16:08:18 -0700 Subject: Moved main.m up a level --- .../HelloWorld.xcodeproj/project.pbxproj | 2 +- objective-c/helloworld/HelloWorld/main.m | 51 ---------------------- objective-c/helloworld/main.m | 51 ++++++++++++++++++++++ 3 files changed, 52 insertions(+), 52 deletions(-) delete mode 100644 objective-c/helloworld/HelloWorld/main.m create mode 100644 objective-c/helloworld/main.m diff --git a/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj b/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj index 018e722cb7..8d92247a91 100644 --- a/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj +++ b/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj @@ -30,7 +30,7 @@ 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.release.xcconfig"; path = "Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld.release.xcconfig"; sourceTree = ""; }; 5E3690601B2A23800040F884 /* HelloWorld.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorld.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5E3690641B2A23800040F884 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5E3690651B2A23800040F884 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = main.m; path = HelloWorld/main.m; sourceTree = ""; }; + 5E3690651B2A23800040F884 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 5E3690671B2A23800040F884 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 5E3690681B2A23800040F884 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 5E36906A1B2A23800040F884 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; diff --git a/objective-c/helloworld/HelloWorld/main.m b/objective-c/helloworld/HelloWorld/main.m deleted file mode 100644 index 458580be30..0000000000 --- a/objective-c/helloworld/HelloWorld/main.m +++ /dev/null @@ -1,51 +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. - * - */ - -#import -#import "AppDelegate.h" - -#import - -static NSString * const kHostAddress = @"http://localhost:50051"; - -int main(int argc, char * argv[]) { - @autoreleasepool { - HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress]; - HLWHelloRequest *request = [HLWHelloRequest message]; - request.name = @"Objective-C"; - [client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { - NSLog(@"%@", response.message); - }]; - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/objective-c/helloworld/main.m b/objective-c/helloworld/main.m new file mode 100644 index 0000000000..458580be30 --- /dev/null +++ b/objective-c/helloworld/main.m @@ -0,0 +1,51 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import +#import "AppDelegate.h" + +#import + +static NSString * const kHostAddress = @"http://localhost:50051"; + +int main(int argc, char * argv[]) { + @autoreleasepool { + HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress]; + HLWHelloRequest *request = [HLWHelloRequest message]; + request.name = @"Objective-C"; + [client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { + NSLog(@"%@", response.message); + }]; + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} -- cgit v1.2.3 From 5fd27c9a52e518dc1fca74579badbe7d9fd40eec Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Thu, 11 Jun 2015 09:29:06 -0700 Subject: PHP route guide --- php/greeter_client.php | 4 +- php/route_guide/README.md | 232 ++++++++++ php/route_guide/route_guide.php | 731 ++++++++++++++++++++++++++++++ php/route_guide/route_guide.proto | 120 +++++ php/route_guide/route_guide_client.php | 205 +++++++++ php/route_guide/run_route_guide_client.sh | 36 ++ php/run_greeter_client.sh | 18 +- 7 files changed, 1329 insertions(+), 17 deletions(-) create mode 100644 php/route_guide/README.md create mode 100644 php/route_guide/route_guide.php create mode 100644 php/route_guide/route_guide.proto create mode 100644 php/route_guide/route_guide_client.php create mode 100755 php/route_guide/run_route_guide_client.sh diff --git a/php/greeter_client.php b/php/greeter_client.php index 663ed7d5d7..8ae19ae46c 100644 --- a/php/greeter_client.php +++ b/php/greeter_client.php @@ -32,8 +32,8 @@ * */ -require 'vendor/autoload.php'; -require 'helloworld.php'; +require dirname(__FILE__) . '/vendor/autoload.php'; +require dirname(__FILE__) . '/helloworld.php'; function greet($name) { $client = new helloworld\GreeterClient( diff --git a/php/route_guide/README.md b/php/route_guide/README.md new file mode 100644 index 0000000000..2d3c4d311d --- /dev/null +++ b/php/route_guide/README.md @@ -0,0 +1,232 @@ +#gRPC Basics: PHP + +This tutorial provides a basic PHP programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Use the PHP gRPC API to write a simple client for your service. + +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). + +This isn't a comprehensive guide to using gRPC in PHP: more reference documentation is coming soon. + +## Why use gRPC? + +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/php/route_guide](https://github.com/grpc/grpc-common/tree/master/php/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/php/route_guide`: +```shell +$ cd grpc-common/php/route_guide +``` + +You also should have the relevant tools installed to generate the client interface code - if you don't already, follow the setup instructions in [the PHP quick start guide](https://github.com/grpc/grpc-common/tree/master/php). + +Please note that currently we only support gRPC clients implemented in PHP. Please see other supported languages (e.g. [Node.js](https://github.com/grpc/grpc-common/tree/master/node/route_guide)) to see how gRPC servers are implemented. + + +## Defining the service + +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +```protobuf +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +```protobuf + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. +```protobuf + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} +``` + +- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. +```protobuf + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +```protobuf + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +```protobuf +// 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; +} +``` + + +## Generating client stub from proto files + +The PHP client stub implementation of the proto files can be generated by the [`protoc-gen-php`](https://github.com/datto/protobuf-php) tool. + +```sh +$ cd grpc-common/php +$ php composer.phar install +$ cd vendor/datto/protobuf-php +$ gem install rake ronn +$ rake pear:package version=1.0 +$ sudo pear install Protobuf-1.0.tgz +``` + +To generate the client stub implementation .php file: + +```sh +$ cd php/route_guide +$ protoc-gen-php -i . -o . ./route_guide.proto +``` + +A `route_guide.php` file will be generated in the `php/route_guide` directory. You do not need to modify the file. + +To load the generated client stub file, simply `require` it in your PHP application: + +```php +require dirname(__FILE__) . '/route_guide.php'; +``` + +Once you've done this, the client classes are in the `examples\` namespace (e.g. `examples\RouteGuideClient`). + + + +## Creating the client + +In this section, we'll look at creating a PHP client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/php/route_guide/route_guide_client.php](https://github.com/grpc/grpc-common/blob/master/php/route_guide/route_guide_client.php). Again, please consult other languages (e.g. [Node.js](https://github.com/grpc/grpc-common/blob/master/node/route_guide/) to see how to start the route guide example server. + +### Creating a stub + +To call service methods, we first need to create a *stub*. To do this, we just need to call the RouteGuide stub constructor, specifying the server address and port. + +```php +$client = new examples\RouteGuideClient(new Grpc\BaseStub('localhost:50051', [])); +``` + +### Calling service methods + +Now let's look at how we call our service methods. + +#### Simple RPC + +Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local asynchronous method. + +```php +$point = new examples\Point(); +$point->setLatitude(409146138); +$point->setLongitude(-746188906); +list($feature, $status) = $client->GetFeature($point)->wait(); +``` + +As you can see, we create and populate a request object, i.e. an `examples\Point` object. Then, we call the method on the stub, passing it the request object. If there is no error, then we can read the response information from the server from our response object, i.e. an `examples\Feature` object. + +```php + print sprintf("Found %s \n at %f, %f\n", $feature->getName(), + $feature->getLocation()->getLatitude() / COORD_FACTOR, + $feature->getLocation()->getLongitude() / COORD_FACTOR); +``` + +#### Streaming RPCs + +Now let's look at our streaming methods. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: + +```php + $lo_point = new examples\Point(); + $hi_point = new examples\Point(); + + $lo_point->setLatitude(400000000); + $lo_point->setLongitude(-750000000); + $hi_point->setLatitude(420000000); + $hi_point->setLongitude(-730000000); + + $rectangle = new examples\Rectangle(); + $rectangle->setLo($lo_point); + $rectangle->setHi($hi_point); + + $call = $client->ListFeatures($rectangle); + // an iterator over the server streaming responses + $features = $call->responses(); + foreach ($features as $feature) { + // process each feature + } // the loop will end when the server indicates there is no more responses to be sent. +``` + +The `$call->responses()` method call returns an iterator. When the server sends a response, a `$feature` object will be returned in the `foreach` loop, until the server indiciates that there will be no more responses to be sent. + +The client-side streaming method `RecordRoute` is similar, except there we pass the method an iterator and get back a `examples\RouteSummary`. + +```php + $points_iter = function($db) { + for ($i = 0; $i < $num_points; $i++) { + $point = new examples\Point(); + $point->setLatitude($lat); + $point->setLongitude($long); + yield $point; + } + }; + // $points_iter is an iterator simulating client streaming + list($route_summary, $status) = + $client->RecordRoute($points_iter($db))->wait(); +``` + +Finally, let's look at our bidirectional streaming RPC `routeChat()`. In this case, we just pass a context to the method and get back a `Duplex` stream object, which we can use to both write and read messages. + +```php +$call = $client->RouteChat(); +``` + +To write messages from the client: + +```php + foreach ($notes as $n) { + $route_note = new examples\RouteNote(); + $call->write($route_note); + } + $call->writesDone(); +``` + +To read messages from the server: + +```php + while ($route_note_reply = $call->read()) { + // process $route_note_reply + } +``` + +Each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + +## Try it out! + +Run the client (in a different terminal): +```shell +$ ./run_route_guide_client.sh +``` diff --git a/php/route_guide/route_guide.php b/php/route_guide/route_guide.php new file mode 100644 index 0000000000..a836e03b55 --- /dev/null +++ b/php/route_guide/route_guide.php @@ -0,0 +1,731 @@ +number = 1; + $f->name = "latitude"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + // OPTIONAL INT32 longitude = 2 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 2; + $f->name = "longitude"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasLatitude(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \examples\Point + */ + public function clearLatitude(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return int + */ + public function getLatitude(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param int $value + * @return \examples\Point + */ + public function setLatitude( $value){ + return $this->_set(1, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasLongitude(){ + return $this->_has(2); + } + + /** + * Clear value + * + * @return \examples\Point + */ + public function clearLongitude(){ + return $this->_clear(2); + } + + /** + * Get value + * + * @return int + */ + public function getLongitude(){ + return $this->_get(2); + } + + /** + * Set value + * + * @param int $value + * @return \examples\Point + */ + public function setLongitude( $value){ + return $this->_set(2, $value); + } + } +} + +namespace examples { + + class Rectangle extends \DrSlump\Protobuf\Message { + + /** @var \examples\Point */ + public $lo = null; + + /** @var \examples\Point */ + public $hi = null; + + + /** @var \Closure[] */ + protected static $__extensions = array(); + + public static function descriptor() + { + $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.Rectangle'); + + // OPTIONAL MESSAGE lo = 1 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 1; + $f->name = "lo"; + $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->reference = '\examples\Point'; + $descriptor->addField($f); + + // OPTIONAL MESSAGE hi = 2 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 2; + $f->name = "hi"; + $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->reference = '\examples\Point'; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasLo(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \examples\Rectangle + */ + public function clearLo(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return \examples\Point + */ + public function getLo(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param \examples\Point $value + * @return \examples\Rectangle + */ + public function setLo(\examples\Point $value){ + return $this->_set(1, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasHi(){ + return $this->_has(2); + } + + /** + * Clear value + * + * @return \examples\Rectangle + */ + public function clearHi(){ + return $this->_clear(2); + } + + /** + * Get value + * + * @return \examples\Point + */ + public function getHi(){ + return $this->_get(2); + } + + /** + * Set value + * + * @param \examples\Point $value + * @return \examples\Rectangle + */ + public function setHi(\examples\Point $value){ + return $this->_set(2, $value); + } + } +} + +namespace examples { + + class Feature extends \DrSlump\Protobuf\Message { + + /** @var string */ + public $name = null; + + /** @var \examples\Point */ + public $location = null; + + + /** @var \Closure[] */ + protected static $__extensions = array(); + + public static function descriptor() + { + $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.Feature'); + + // OPTIONAL STRING name = 1 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 1; + $f->name = "name"; + $f->type = \DrSlump\Protobuf::TYPE_STRING; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $descriptor->addField($f); + + // OPTIONAL MESSAGE location = 2 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 2; + $f->name = "location"; + $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->reference = '\examples\Point'; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasName(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \examples\Feature + */ + public function clearName(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return string + */ + public function getName(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param string $value + * @return \examples\Feature + */ + public function setName( $value){ + return $this->_set(1, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasLocation(){ + return $this->_has(2); + } + + /** + * Clear value + * + * @return \examples\Feature + */ + public function clearLocation(){ + return $this->_clear(2); + } + + /** + * Get value + * + * @return \examples\Point + */ + public function getLocation(){ + return $this->_get(2); + } + + /** + * Set value + * + * @param \examples\Point $value + * @return \examples\Feature + */ + public function setLocation(\examples\Point $value){ + return $this->_set(2, $value); + } + } +} + +namespace examples { + + class RouteNote extends \DrSlump\Protobuf\Message { + + /** @var \examples\Point */ + public $location = null; + + /** @var string */ + public $message = null; + + + /** @var \Closure[] */ + protected static $__extensions = array(); + + public static function descriptor() + { + $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.RouteNote'); + + // OPTIONAL MESSAGE location = 1 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 1; + $f->name = "location"; + $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->reference = '\examples\Point'; + $descriptor->addField($f); + + // OPTIONAL STRING message = 2 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 2; + $f->name = "message"; + $f->type = \DrSlump\Protobuf::TYPE_STRING; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasLocation(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \examples\RouteNote + */ + public function clearLocation(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return \examples\Point + */ + public function getLocation(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param \examples\Point $value + * @return \examples\RouteNote + */ + public function setLocation(\examples\Point $value){ + return $this->_set(1, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasMessage(){ + return $this->_has(2); + } + + /** + * Clear value + * + * @return \examples\RouteNote + */ + public function clearMessage(){ + return $this->_clear(2); + } + + /** + * Get value + * + * @return string + */ + public function getMessage(){ + return $this->_get(2); + } + + /** + * Set value + * + * @param string $value + * @return \examples\RouteNote + */ + public function setMessage( $value){ + return $this->_set(2, $value); + } + } +} + +namespace examples { + + class RouteSummary extends \DrSlump\Protobuf\Message { + + /** @var int */ + public $point_count = 0; + + /** @var int */ + public $feature_count = 0; + + /** @var int */ + public $distance = 0; + + /** @var int */ + public $elapsed_time = 0; + + + /** @var \Closure[] */ + protected static $__extensions = array(); + + public static function descriptor() + { + $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.RouteSummary'); + + // OPTIONAL INT32 point_count = 1 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 1; + $f->name = "point_count"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + // OPTIONAL INT32 feature_count = 2 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 2; + $f->name = "feature_count"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + // OPTIONAL INT32 distance = 3 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 3; + $f->name = "distance"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + // OPTIONAL INT32 elapsed_time = 4 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 4; + $f->name = "elapsed_time"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasPointCount(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \examples\RouteSummary + */ + public function clearPointCount(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return int + */ + public function getPointCount(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param int $value + * @return \examples\RouteSummary + */ + public function setPointCount( $value){ + return $this->_set(1, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasFeatureCount(){ + return $this->_has(2); + } + + /** + * Clear value + * + * @return \examples\RouteSummary + */ + public function clearFeatureCount(){ + return $this->_clear(2); + } + + /** + * Get value + * + * @return int + */ + public function getFeatureCount(){ + return $this->_get(2); + } + + /** + * Set value + * + * @param int $value + * @return \examples\RouteSummary + */ + public function setFeatureCount( $value){ + return $this->_set(2, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasDistance(){ + return $this->_has(3); + } + + /** + * Clear value + * + * @return \examples\RouteSummary + */ + public function clearDistance(){ + return $this->_clear(3); + } + + /** + * Get value + * + * @return int + */ + public function getDistance(){ + return $this->_get(3); + } + + /** + * Set value + * + * @param int $value + * @return \examples\RouteSummary + */ + public function setDistance( $value){ + return $this->_set(3, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasElapsedTime(){ + return $this->_has(4); + } + + /** + * Clear value + * + * @return \examples\RouteSummary + */ + public function clearElapsedTime(){ + return $this->_clear(4); + } + + /** + * Get value + * + * @return int + */ + public function getElapsedTime(){ + return $this->_get(4); + } + + /** + * Set value + * + * @param int $value + * @return \examples\RouteSummary + */ + public function setElapsedTime( $value){ + return $this->_set(4, $value); + } + } +} + +namespace examples { + + class RouteGuideClient{ + + private $rpc_impl; + + public function __construct($rpc_impl) { + $this->rpc_impl = $rpc_impl; + } + /** + * @param examples\Point $input + */ + public function GetFeature(\examples\Point $argument, $metadata = array()) { + return $this->rpc_impl->_simpleRequest('/examples.RouteGuide/GetFeature', $argument, '\examples\Feature::deserialize', $metadata); + } + /** + * @param examples\Rectangle $input + */ + public function ListFeatures($argument, $metadata = array()) { + return $this->rpc_impl->_serverStreamRequest('/examples.RouteGuide/ListFeatures', $argument, '\examples\Feature::deserialize', $metadata); + } + /** + * @param examples\Point $input + */ + public function RecordRoute($arguments, $metadata = array()) { + return $this->rpc_impl->_clientStreamRequest('/examples.RouteGuide/RecordRoute', $arguments, '\examples\RouteSummary::deserialize', $metadata); + } + /** + * @param examples\RouteNote $input + */ + public function RouteChat($metadata = array()) { + return $this->rpc_impl->_bidiRequest('/examples.RouteGuide/RouteChat', '\examples\RouteNote::deserialize', $metadata); + } + } +} diff --git a/php/route_guide/route_guide.proto b/php/route_guide/route_guide.proto new file mode 100644 index 0000000000..0947184dbb --- /dev/null +++ b/php/route_guide/route_guide.proto @@ -0,0 +1,120 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto2"; + +option java_package = "io.grpc.examples"; + +package examples; + +// Interface exported by the server. +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} + + // A server-to-client streaming RPC. + // + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} + + // A client-to-server streaming RPC. + // + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} + + // A Bidirectional streaming RPC. + // + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +} + +// Points are represented as latitude-longitude pairs in the E7 representation +// (degrees multiplied by 10**7 and rounded to the nearest integer). +// Latitudes should be in the range +/- 90 degrees and longitude should be in +// the range +/- 180 degrees (inclusive). +message Point { + optional int32 latitude = 1 [default = 0]; + optional int32 longitude = 2 [default = 0]; +} + +// A latitude-longitude rectangle, represented as two diagonally opposite +// points "lo" and "hi". +message Rectangle { + // One corner of the rectangle. + optional Point lo = 1; + + // The other corner of the rectangle. + optional Point hi = 2; +} + +// A feature names something at a given point. +// +// If a feature could not be named, the name is empty. +message Feature { + // The name of the feature. + optional string name = 1; + + // The point where the feature is detected. + optional Point location = 2; +} + +// A RouteNote is a message sent while at a given point. +message RouteNote { + // The location from which the message is sent. + optional Point location = 1; + + // The message to be sent. + optional string message = 2; +} + +// A RouteSummary is received in response to a RecordRoute rpc. +// +// It contains the number of individual points received, the number of +// detected features, and the total distance covered as the cumulative sum of +// the distance between each point. +message RouteSummary { + // The number of points received. + optional int32 point_count = 1 [default = 0]; + + // The number of known features passed while traversing the route. + optional int32 feature_count = 2 [default = 0]; + + // The distance covered in metres. + optional int32 distance = 3 [default = 0]; + + // The duration of the traversal in seconds. + optional int32 elapsed_time = 4 [default = 0]; +} diff --git a/php/route_guide/route_guide_client.php b/php/route_guide/route_guide_client.php new file mode 100644 index 0000000000..6d9ae58b66 --- /dev/null +++ b/php/route_guide/route_guide_client.php @@ -0,0 +1,205 @@ +getName(); + if (!$name) { + $name_str = "no feature"; + } else { + $name_str = "feature called $name"; + } + print sprintf("Found %s \n at %f, %f\n", $name_str, + $feature->getLocation()->getLatitude() / COORD_FACTOR, + $feature->getLocation()->getLongitude() / COORD_FACTOR); +} + +/** + * Run the getFeature demo. Calls getFeature with a point known to have a + * feature and a point known not to have a feature. + */ +function runGetFeature() { + print "Running GetFeature...\n"; + global $client; + + $point = new examples\Point(); + $points = array( + array(409146138, -746188906), + array(0, 0), + ); + + foreach ($points as $p) { + $point->setLatitude($p[0]); + $point->setLongitude($p[1]); + // make a unary grpc call + list($feature, $status) = $client->GetFeature($point)->wait(); + printFeature($feature); + } +} + +/** + * Run the listFeatures demo. Calls listFeatures with a rectangle + * containing all of the features in the pre-generated + * database. Prints each response as it comes in. + */ +function runListFeatures() { + print "Running ListFeatures...\n"; + global $client; + + $lo_point = new examples\Point(); + $hi_point = new examples\Point(); + + $lo_point->setLatitude(400000000); + $lo_point->setLongitude(-750000000); + $hi_point->setLatitude(420000000); + $hi_point->setLongitude(-730000000); + + $rectangle = new examples\Rectangle(); + $rectangle->setLo($lo_point); + $rectangle->setHi($hi_point); + + $call = $client->ListFeatures($rectangle); + // an iterator over the server streaming responses + $features = $call->responses(); + foreach ($features as $feature) { + printFeature($feature); + } +} + +/** + * Run the recordRoute demo. Sends several randomly chosen points from the + * pre-generated feature database with a variable delay in between. Prints + * the statistics when they are sent from the server. + */ +function runRecordRoute() { + print "Running RecordRoute...\n"; + global $client, $argv; + + $db = json_decode(file_get_contents($argv[1]), true); + $points_iter = function($db) { + $num_points_in_db = count($db); + $num_points = 10; + for ($i = 0; $i < $num_points; $i++) { + $point = new examples\Point(); + $index = rand(0, $num_points_in_db - 1); + $lat = $db[$index]['location']['latitude']; + $long = $db[$index]['location']['longitude']; + $feature_name = $db[$index]['name']; + $point->setLatitude($lat); + $point->setLongitude($long); + print sprintf("Visiting point %f, %f,\n with feature name: %s\n", + $lat / COORD_FACTOR, $long / COORD_FACTOR, + $feature_name ? $feature_name : ''); + usleep(rand(300000, 800000)); + yield $point; + } + }; + // $points_iter is an iterator simulating client streaming + list($route_summary, $status) = + $client->RecordRoute($points_iter($db))->wait(); + print sprintf("Finished trip with %d points\nPassed %d features\n". + "Travelled %d meters\nIt took %d seconds\n", + $route_summary->getPointCount(), + $route_summary->getFeatureCount(), + $route_summary->getDistance(), + $route_summary->getElapsedTime()); +} + +/** + * Run the routeChat demo. Send some chat messages, and print any chat + * messages that are sent from the server. + */ +function runRouteChat() { + print "Running RouteChat...\n"; + global $client; + + // start the bidirectional streaming call + $call = $client->RouteChat(); + + $notes = array( + array(1, 1, 'first message'), + array(1, 2, 'second message'), + array(2, 1, 'third message'), + array(1, 1, 'fourth message'), + array(1, 1, 'fifth message'), + ); + + foreach ($notes as $n) { + $point = new examples\Point(); + $point->setLatitude($lat = $n[0]); + $point->setLongitude($long = $n[1]); + + $route_note = new examples\RouteNote(); + $route_note->setLocation($point); + $route_note->setMessage($message = $n[2]); + + print sprintf("Sending message: '%s' at (%d, %d)\n", + $message, $lat, $long); + // send a bunch of messages to the server + $call->write($route_note); + } + $call->writesDone(); + + // read from the server until there's no more + while ($route_note_reply = $call->read()) { + print sprintf("Previous left message at (%d, %d): '%s'\n", + $route_note_reply->getLocation()->getLatitude(), + $route_note_reply->getLocation()->getLongitude(), + $route_note_reply->getMessage()); + } +} + +/** + * Run all of the demos in order + */ +function main() { + runGetFeature(); + runListFeatures(); + runRecordRoute(); + runRouteChat(); +} + +if (empty($argv[1])) { + print "Usage: php -d extension=grpc.so route_guide_client.php " . + "\n"; + exit(1); +} +main(); diff --git a/php/route_guide/run_route_guide_client.sh b/php/route_guide/run_route_guide_client.sh new file mode 100755 index 0000000000..e5ca07796b --- /dev/null +++ b/php/route_guide/run_route_guide_client.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# 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. + +set -e +cd $(dirname $0) +command -v brew >/dev/null 2>&1 && \ + extension_dir="-d extension_dir="`brew --prefix`/opt/grpc-php +php $extension_dir -d extension=grpc.so \ + route_guide_client.php ../../node/route_guide/route_guide_db.json diff --git a/php/run_greeter_client.sh b/php/run_greeter_client.sh index 4fdea897f9..2906de9af8 100755 --- a/php/run_greeter_client.sh +++ b/php/run_greeter_client.sh @@ -30,18 +30,6 @@ set -e cd $(dirname $0) -which brew >> /dev/null || { echo 'please make sure brew is in the PATH'; exit 1; } -default_extension_dir=`php -i 2>/dev/null | grep extension_dir | sed 's/.*=> //g'` -brew_home=`brew --prefix` -module_dir=$brew_home/opt/grpc-php - -# sym-link in system supplied extensions -for f in $default_extension_dir/*.so -do - ln -s $f $module_dir/$(basename $f) &> /dev/null || true -done - -php \ - -d extension_dir=$module_dir \ - -d extension=grpc.so \ - greeter_client.php +command -v brew >/dev/null 2>&1 && \ + extension_dir="-d extension_dir="`brew --prefix`/opt/grpc-php +php $extension_dir -d extension=grpc.so greeter_client.php $1 -- cgit v1.2.3 From dcfa963d6e3b1f10ae89a0f16d05b6668af8a505 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 16 Jun 2015 08:17:42 -0700 Subject: Fix readme as per feedback --- php/route_guide/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/route_guide/README.md b/php/route_guide/README.md index 2d3c4d311d..39a9a56d7e 100644 --- a/php/route_guide/README.md +++ b/php/route_guide/README.md @@ -29,7 +29,7 @@ $ cd grpc-common/php/route_guide You also should have the relevant tools installed to generate the client interface code - if you don't already, follow the setup instructions in [the PHP quick start guide](https://github.com/grpc/grpc-common/tree/master/php). -Please note that currently we only support gRPC clients implemented in PHP. Please see other supported languages (e.g. [Node.js](https://github.com/grpc/grpc-common/tree/master/node/route_guide)) to see how gRPC servers are implemented. +Please note that currently we only support gRPC clients implemented in PHP. See the tutorials for our other supported languages (e.g. [Node.js](https://github.com/grpc/grpc-common/tree/master/node/route_guide)) to see how gRPC servers are implemented. ## Defining the service -- cgit v1.2.3 From 45e4380ebd9f56d21494391507967ed466e25eb2 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 16 Jun 2015 08:59:07 -0700 Subject: restructure PHP route guide README using the Objective-C one as guideline --- php/route_guide/README.md | 73 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/php/route_guide/README.md b/php/route_guide/README.md index 39a9a56d7e..931dd0c68a 100644 --- a/php/route_guide/README.md +++ b/php/route_guide/README.md @@ -3,18 +3,28 @@ This tutorial provides a basic PHP programmer's introduction to working with gRPC. By walking through this example you'll learn how to: - Define a service in a .proto file. +- Generate client code using the protocol buffer compiler. - Use the PHP gRPC API to write a simple client for your service. -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). +It assumes a passing familiarity with [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto2 version of the protocol buffers language. This isn't a comprehensive guide to using gRPC in PHP: more reference documentation is coming soon. +- [Why use gRPC?](#why-grpc) +- [Example code and setup](#setup) +- [Defining the service](#proto) +- [Generating client code](#protoc) +- [Creating the client](#client) +- [Try it out!](#try) + + + ## Why use gRPC? -Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. +With gRPC you can define your service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. You also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. -With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + ## Example code and setup The example code for our tutorial is in [grpc/grpc-common/php/route_guide](https://github.com/grpc/grpc-common/tree/master/php/route_guide). To download the example, clone the `grpc-common` repository by running the following command: @@ -27,14 +37,17 @@ Then change your current directory to `grpc-common/php/route_guide`: $ cd grpc-common/php/route_guide ``` -You also should have the relevant tools installed to generate the client interface code - if you don't already, follow the setup instructions in [the PHP quick start guide](https://github.com/grpc/grpc-common/tree/master/php). +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +You also should have the relevant tools installed to generate the client interface code (and a server in another language, for testing). You can obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). -Please note that currently we only support gRPC clients implemented in PHP. See the tutorials for our other supported languages (e.g. [Node.js](https://github.com/grpc/grpc-common/tree/master/node/route_guide)) to see how gRPC servers are implemented. +The next sections guide you step-by-step through how this proto service is defined, how to generate a client library from it, and how to create a client stub that uses that library. + ## Defining the service -Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). +First let's look at how the service we're using is defined. A gRPC *service* and its method *request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file for our example in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). To define a service, you specify a named `service` in your .proto file: @@ -44,15 +57,15 @@ service RouteGuide { } ``` -Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: +Then you define `rpc` methods inside your service definition, specifying their request and response types. Protocol buffers let you define four kinds of service method, all of which are used in the `RouteGuide` service: -- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +- A *simple RPC* where the client sends a request to the server and receives a response later, just like a normal remote procedure call. ```protobuf // Obtains the feature at a given position. rpc GetFeature(Point) returns (Feature) {} ``` -- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. +- A *response-streaming RPC* where the client sends a request to the server and gets back a stream of response messages. You specify a response-streaming method by placing the `stream` keyword before the *response* type. ```protobuf // Obtains the Features available within the given Rectangle. Results are // streamed rather than returned at once (e.g. in a response message with a @@ -61,14 +74,14 @@ Then you define `rpc` methods inside your service definition, specifying their r rpc ListFeatures(Rectangle) returns (stream Feature) {} ``` -- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. +- A *request-streaming RPC* where the client sends a sequence of messages to the server. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a request-streaming method by placing the `stream` keyword before the *request* type. ```protobuf // Accepts a stream of Points on a route being traversed, returning a // RouteSummary when traversal is completed. rpc RecordRoute(stream Point) returns (RouteSummary) {} ``` -- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +- A *bidirectional streaming RPC* where both sides send a sequence of messages to the other. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. ```protobuf // Accepts a stream of RouteNotes sent while a route is being traversed, // while receiving other RouteNotes (e.g. from other users). @@ -88,9 +101,10 @@ message Point { ``` -## Generating client stub from proto files + +## Generating client code -The PHP client stub implementation of the proto files can be generated by the [`protoc-gen-php`](https://github.com/datto/protobuf-php) tool. +The PHP client stub implementation of the proto files can be generated by the [`protoc-gen-php`](https://github.com/datto/protobuf-php) tool. To install the tool: ```sh $ cd grpc-common/php @@ -116,17 +130,19 @@ To load the generated client stub file, simply `require` it in your PHP applicat require dirname(__FILE__) . '/route_guide.php'; ``` -Once you've done this, the client classes are in the `examples\` namespace (e.g. `examples\RouteGuideClient`). +The file contains: +- All the protocol buffer code to populate, serialize, and retrieve our request and response message types. +- A class called `examples\RouteGuideClient` that lets clients call the methods defined in the `RouteGuide` service. ## Creating the client -In this section, we'll look at creating a PHP client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/php/route_guide/route_guide_client.php](https://github.com/grpc/grpc-common/blob/master/php/route_guide/route_guide_client.php). Again, please consult other languages (e.g. [Node.js](https://github.com/grpc/grpc-common/blob/master/node/route_guide/) to see how to start the route guide example server. +In this section, we'll look at creating a PHP client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/php/route_guide/route_guide_client.php](https://github.com/grpc/grpc-common/blob/master/php/route_guide/route_guide_client.php). -### Creating a stub +### Constructing a client object -To call service methods, we first need to create a *stub*. To do this, we just need to call the RouteGuide stub constructor, specifying the server address and port. +To call service methods, we first need to create a client object, an instance of the generated `RouteGuideClient` class. The constructor of the class expects the server address and port we want to connect to: ```php $client = new examples\RouteGuideClient(new Grpc\BaseStub('localhost:50051', [])); @@ -141,10 +157,10 @@ Now let's look at how we call our service methods. Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local asynchronous method. ```php -$point = new examples\Point(); -$point->setLatitude(409146138); -$point->setLongitude(-746188906); -list($feature, $status) = $client->GetFeature($point)->wait(); + $point = new examples\Point(); + $point->setLatitude(409146138); + $point->setLongitude(-746188906); + list($feature, $status) = $client->GetFeature($point)->wait(); ``` As you can see, we create and populate a request object, i.e. an `examples\Point` object. Then, we call the method on the stub, passing it the request object. If there is no error, then we can read the response information from the server from our response object, i.e. an `examples\Feature` object. @@ -198,7 +214,7 @@ The client-side streaming method `RecordRoute` is similar, except there we pass $client->RecordRoute($points_iter($db))->wait(); ``` -Finally, let's look at our bidirectional streaming RPC `routeChat()`. In this case, we just pass a context to the method and get back a `Duplex` stream object, which we can use to both write and read messages. +Finally, let's look at our bidirectional streaming RPC `routeChat()`. In this case, we just pass a context to the method and get back a `BidiStreamingCall` stream object, which we can use to both write and read messages. ```php $call = $client->RouteChat(); @@ -224,9 +240,20 @@ To read messages from the server: Each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + ## Try it out! -Run the client (in a different terminal): +To try the sample app, we need a gRPC server running locally. Let's compile and run, for example, the Node.js server in this repository: + +```shell +$ cd ../../node +$ npm install +$ cd route_guide +$ nodejs ./route_guide_server.js --db_path=route_guide_db.json +``` + +Run the PHP client (in a different terminal): + ```shell $ ./run_route_guide_client.sh ``` -- cgit v1.2.3 From 3508c9a5b85e41b4a7c9a68e10a6838108232170 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Tue, 16 Jun 2015 22:21:48 -0700 Subject: Add README for the auth example --- objective-c/auth_sample/README.md | 174 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 objective-c/auth_sample/README.md diff --git a/objective-c/auth_sample/README.md b/objective-c/auth_sample/README.md new file mode 100644 index 0000000000..06812323bc --- /dev/null +++ b/objective-c/auth_sample/README.md @@ -0,0 +1,174 @@ +#OAuth2 on gRPC: Objective-C + +This example application demostrates how to use OAuth2 on gRPC to make authenticated API calls on +behalf of a user. By walking through it you'll learn how to use the Objective-C gRPC API to: + +- Initialize and configure a remote call object before the RPC is started. +- Set request metadata elements on a call, which are semantically equivalent to HTTP request +headers. +- Read response metadata from a call, which is equivalent to HTTP response headers and trailers. + +It assumes you know the basics on how to make gRPC API calls using the Objective-C client library, +as shown in the [Hello World](https://github.com/grpc/grpc-common/tree/master/objective-c/helloworld) +or [Route Guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide) tutorials, +and familiarity with OAuth2 concepts like _access token_. + +- [Example code and setup](#setup) +- [Try it out!](#try) +- [Create an RPC object and start it later](#rpc-object) +- [Set request metadata of a call: Authorization header with an access token](#request-metadata) +- [Get response metadata of a call: Auth challenge header](#response-metadata) + + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/objective-c/auth_sample](https://github.com/grpc/grpc-common/tree/master/objective-c/auth_sample). +To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/objective-c/auth_sample`: +```shell +$ cd grpc-common/objective-c/auth_sample +``` + +Our example is a simple application with two views. The first one lets a user sign in and out using +the OAuth2 flow of Google's [iOS SignIn library](https://developers.google.com/identity/sign-in/ios/). +(Google's library is used in this example because the test gRPC service we are going to call expects +Google account credentials, but neither gRPC nor the Objective-C client library is tied to any +specific OAuth2 provider). The second view makes a gRPC request to the test server, using the +access token obtained by the first view. + +Note: OAuth2 libraries need the application to register and obtain an ID from the identity provider +(in the case of this example app, Google). The app's XCode project is configured using that ID, so +you shouldn't copy this project as is for your own app: It would result in your app being identified +in the consent screen as "gRPC-AuthSample", and not having access to real Google services. Instead, +configure your XCode project following the [instructions here](https://developers.google.com/identity/sign-in/ios/). + +As with the other examples, you also should have [Cocoapods](https://cocoapods.org/#install) +installed, as well as the relevant tools to generate the client library code. You can obtain the +latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). + + + +## Try it out! + +To try the sample app, first have Cocoapods generate and install the client library for our .proto +files: + +```shell +$ pod install +``` + +(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet +on your computer's cache). + +Finally, open the XCode workspace created by Cocoapods, and run the app. + +The first view, `SelectUserViewController.h/m`, asks you to sign in with your Google account, and to +give the "gRPC-AuthSample" app the following permissions: + +- View your email address. +- View your basic profile info. +- "Test scope for access to the Zoo service". + +This last permission, corresponding to the scope `https://www.googleapis.com/auth/xapi.zoo` doesn't +grant any real capability: It's only used for testing. You can log out at any moment. + +The second view, `MakeRPCViewController.h/m`, makes a gRPC request to a test server at +https://grpc-test.sandbox.google.com, sending the access token along with the request. The test +service simply validates the token and writes in its response which user it belongs to, and which +scopes it gives access to. (The client application already knows those two values; it's a way to +verify that everything went as expected). + +The next sections guide you step-by-step through how the gRPC call in `MakeRPCViewController` is +performed. + + +## Create an RPC object and start it later + +The other basic tutorials show how to invoke an RPC by calling an asynchronous method in a generated +client object. This shows how to initialize an object that represents the RPC, and configure it +before starting the network request. + +Assume you have a proto service definition like this: + +```protobuf +option objc_class_prefix = "AUTH"; + +service TestService { + rpc UnaryCall(Request) returns (Response); +} +``` + +A `unaryCallWithRequest:handler:` method is generated, with which you're already familiar, is +generated for the `AUTHTestService` class: + +```objective-c +[client unaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { + ... +}]; +``` + +And a second `RPCToUnaryCallWithRequest:handler:` method is generated, which returns a +not-yet-started RPC object: + +```objective-c +#import + +ProtoRPC *call = + [client RPCToUnaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { + ... + }]; +``` + +The RPC represented by this object can be started at any later time like this: + +```objective-c +[call start]; +``` + + +## Set request metadata of a call: Authorization header with an access token + +The `ProtoRPC` class has a `requestMetadata` property defined like this: + +```objective-c +@property(nonatomic, readwrite) NSMutableDictionary *requestMetadata; +``` + +Setting it to a dictionary of metadata keys and values will have them sent on the wire when the call +is started. + +```objective-c +call.requestMetadata = [NSMutableDictionary dictionaryWithDictionary: + @{@"My-Header": @"Value for this header", + @"Another-Header": @"Its value"}]; +``` + +If you have an access token, OAuth2 specifies it is to be sent in this format: + +```objective-c +@{@"Authorization": [@"Bearer " stringByAppendingString:accessToken]} +``` + + +## Get response metadata of a call: Auth challenge header + +Analogously to the request metadata, the `ProtoRPC` class has a `responseMetadata` property defined +this way: + +```objective-c +@property(atomic, readonly) NSDictionary *responseMetadata; +``` + +Because gRPC metadata keys can be repeated, the values of the `responseMetadata` dictionary are +always `NSArray`s. Thus, to access OAuth2's authentication challenge header you write: + +```objective-c +call.responseMetadata[@"www-authenticate"][0] +``` + +Note that, as gRPC metadata elements are mapped to HTTP/2 headers (or trailers), the keys of the +response metadata are always ASCII strings in lowercase. -- cgit v1.2.3 From 777fee23d8ae78d01d8f2fce47c6aa566d6e4887 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Tue, 16 Jun 2015 11:03:20 -0700 Subject: Add Objective-C sections to the common auth README --- grpc-auth-support.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/grpc-auth-support.md b/grpc-auth-support.md index 9b97203276..597f4434d2 100644 --- a/grpc-auth-support.md +++ b/grpc-auth-support.md @@ -114,6 +114,22 @@ var channel = new Channel("localhost:50051", credentials); var client = new Greeter.GreeterClient(channel); ``` +###SSL/TLS for server authentication and encryption (Objective-C) + +The default for Objective-C is to use SSL/TLS, as that's the most common use case when accessing +remote APIs. + +```objective-c +// Base case - With server authentication SSL/TLS +HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"localhost:50051"]; +// Same as using @"https://localhost:50051". +... + +// No encryption +HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"http://localhost:50051"]; +// Specifying the HTTP scheme explicitly forces no encryption. +``` + ###Authenticating with Google (Ruby) ```ruby # Base case - No encryption/authorization @@ -174,3 +190,43 @@ if (authorization.IsCreateScopedRequired) var client = new Greeter.GreeterClient(channel, new StubConfiguration(OAuth2InterceptorFactory.Create(credential))); ``` + +###Authenticating with Google (Objective-C) + +This example uses the [Google iOS Sign-In library](https://developers.google.com/identity/sign-in/ios/), +but it's easily extrapolated to any other OAuth2 library. + +```objective-c +// Base case - No authentication +[client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { + ... +}]; + +... + +// Authenticating with Google + +// When signing the user in, ask her for the relevant scopes. +GIDSignIn.sharedInstance.scopes = @[@"https://www.googleapis.com/auth/grpc-testing"]; + +... + +#import + +// Create a not-yet-started RPC. We want to set the request headers on this object before starting +// it. +ProtoRPC *call = + [client RPCToSayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { + ... + }]; + +// Set the access token to be used. +NSString *accessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken; +call.requestMetadata = [NSMutableDictionary dictionaryWithDictionary: + @{@"Authorization": [@"Bearer " stringByAppendingString:accessToken]}]; + +// Start the RPC. +[call start]; +``` + +You can see a working example app, with a more detailed explanation, [here](https://github.com/grpc/grpc-common/tree/master/objective-c/auth_sample). -- cgit v1.2.3 From fd7627691f13b1c62e97014253b3ac011e5e4b94 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Wed, 17 Jun 2015 16:31:39 -0700 Subject: Move to new Status API --- cpp/helloworld/greeter_async_client.cc | 2 +- cpp/helloworld/greeter_client.cc | 2 +- cpp/route_guide/route_guide_client.cc | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cpp/helloworld/greeter_async_client.cc b/cpp/helloworld/greeter_async_client.cc index b88ba0e74a..561b880ecb 100644 --- a/cpp/helloworld/greeter_async_client.cc +++ b/cpp/helloworld/greeter_async_client.cc @@ -79,7 +79,7 @@ class GreeterClient { GPR_ASSERT(ok); GPR_ASSERT(got_tag == (void*)1); - if (status.IsOk()) { + if (status.ok()) { return reply.message(); } else { return "Rpc failed"; diff --git a/cpp/helloworld/greeter_client.cc b/cpp/helloworld/greeter_client.cc index c0aec1696a..44e4447f1f 100644 --- a/cpp/helloworld/greeter_client.cc +++ b/cpp/helloworld/greeter_client.cc @@ -64,7 +64,7 @@ class GreeterClient { ClientContext context; Status status = stub_->SayHello(&context, request, &reply); - if (status.IsOk()) { + if (status.ok()) { return reply.message(); } else { return "Rpc failed"; diff --git a/cpp/route_guide/route_guide_client.cc b/cpp/route_guide/route_guide_client.cc index 91e1cebfc7..734ea9fb8a 100644 --- a/cpp/route_guide/route_guide_client.cc +++ b/cpp/route_guide/route_guide_client.cc @@ -124,7 +124,7 @@ class RouteGuideClient { << feature.location().longitude()/kCoordFactor_ << std::endl; } Status status = reader->Finish(); - if (status.IsOk()) { + if (status.ok()) { std::cout << "ListFeatures rpc succeeded." << std::endl; } else { std::cout << "ListFeatures rpc failed." << std::endl; @@ -160,7 +160,7 @@ class RouteGuideClient { } writer->WritesDone(); Status status = writer->Finish(); - if (status.IsOk()) { + if (status.ok()) { std::cout << "Finished trip with " << stats.point_count() << " points\n" << "Passed " << stats.feature_count() << " features\n" << "Travelled " << stats.distance() << " meters\n" @@ -200,7 +200,7 @@ class RouteGuideClient { } writer.join(); Status status = stream->Finish(); - if (!status.IsOk()) { + if (!status.ok()) { std::cout << "RouteChat rpc failed." << std::endl; } } @@ -210,7 +210,7 @@ class RouteGuideClient { bool GetOneFeature(const Point& point, Feature* feature) { ClientContext context; Status status = stub_->GetFeature(&context, point, feature); - if (!status.IsOk()) { + if (!status.ok()) { std::cout << "GetFeature rpc failed." << std::endl; return false; } -- cgit v1.2.3 From 5bcf4671e479ce73e47bcc1c8aafc21a2208498d Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Thu, 18 Jun 2015 08:23:17 -0700 Subject: update PHP route guide README as per feedback --- php/route_guide/README.md | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/php/route_guide/README.md b/php/route_guide/README.md index 931dd0c68a..084661a5eb 100644 --- a/php/route_guide/README.md +++ b/php/route_guide/README.md @@ -8,14 +8,16 @@ This tutorial provides a basic PHP programmer's introduction to working with gRP It assumes a passing familiarity with [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto2 version of the protocol buffers language. +Also note that currently you can only create clients in PHP for gRPC services - you can find out how to create gRPC servers in our other tutorials, e.g. [Node.js](https://github.com/grpc/grpc-common/tree/master/node/route_guide). + This isn't a comprehensive guide to using gRPC in PHP: more reference documentation is coming soon. - [Why use gRPC?](#why-grpc) - [Example code and setup](#setup) +- [Try it out!](#try) - [Defining the service](#proto) - [Generating client code](#protoc) - [Creating the client](#client) -- [Try it out!](#try) @@ -41,6 +43,25 @@ Our example is a simple route mapping application that lets clients get informat You also should have the relevant tools installed to generate the client interface code (and a server in another language, for testing). You can obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). + + +## Try it out! + +To try the sample app, we need a gRPC server running locally. Let's compile and run, for example, the Node.js server in this repository: + +```shell +$ cd ../../node +$ npm install +$ cd route_guide +$ nodejs ./route_guide_server.js --db_path=route_guide_db.json +``` + +Run the PHP client (in a different terminal): + +```shell +$ ./run_route_guide_client.sh +``` + The next sections guide you step-by-step through how this proto service is defined, how to generate a client library from it, and how to create a client stub that uses that library. @@ -239,21 +260,3 @@ To read messages from the server: ``` Each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. - - -## Try it out! - -To try the sample app, we need a gRPC server running locally. Let's compile and run, for example, the Node.js server in this repository: - -```shell -$ cd ../../node -$ npm install -$ cd route_guide -$ nodejs ./route_guide_server.js --db_path=route_guide_db.json -``` - -Run the PHP client (in a different terminal): - -```shell -$ ./run_route_guide_client.sh -``` -- cgit v1.2.3 From 40dc223f07ec31e0b9acf1796b574109cf965c3b Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 23 Jun 2015 17:35:04 -0700 Subject: Add PHP Google Auth example --- grpc-auth-support.md | 21 ++++++++++++++ php/composer.json | 1 + php/greeter_client_with_auth.php | 57 +++++++++++++++++++++++++++++++++++++ php/run_greeter_client_with_auth.sh | 37 ++++++++++++++++++++++++ 4 files changed, 116 insertions(+) create mode 100644 php/greeter_client_with_auth.php create mode 100755 php/run_greeter_client_with_auth.sh diff --git a/grpc-auth-support.md b/grpc-auth-support.md index 9b97203276..aff952a050 100644 --- a/grpc-auth-support.md +++ b/grpc-auth-support.md @@ -174,3 +174,24 @@ if (authorization.IsCreateScopedRequired) var client = new Greeter.GreeterClient(channel, new StubConfiguration(OAuth2InterceptorFactory.Create(credential))); ``` + +###Authenticating with Google (PHP) +```php +// Base case - No encryption/authorization +$client = new helloworld\GreeterClient( + new Grpc\BaseStub('localhost:50051', [])); +... + +// Authenticating with Google +// the environment variable "GOOGLE_APPLICATION_CREDENTIALS" needs to be set +$scope = "https://www.googleapis.com/auth/grpc-testing"; +$auth = Google\Auth\ApplicationDefaultCredentials::getCredentials($scope); +$opts = [ + 'credentials' => Grpc\Credentials::createSsl(file_get_contents('ca.pem')); + 'update_metadata' => $auth->getUpdateMetadataFunc(), +]; + +$client = new helloworld\GreeterClient( + new Grpc\BaseStub('localhost:50051', $opts)); + +``` diff --git a/php/composer.json b/php/composer.json index d1c4bd2a18..f0ce3a2aff 100644 --- a/php/composer.json +++ b/php/composer.json @@ -11,6 +11,7 @@ "require": { "php": ">=5.5.0", "datto/protobuf-php": "dev-master", + "google/auth": "dev-master", "grpc/grpc": "dev-master" } } diff --git a/php/greeter_client_with_auth.php b/php/greeter_client_with_auth.php new file mode 100644 index 0000000000..39e28fcb80 --- /dev/null +++ b/php/greeter_client_with_auth.php @@ -0,0 +1,57 @@ + Grpc\Credentials::createSsl( + // file_get_contents(getenv('SSL_CERT_FILE'))), + 'update_metadata' => $auth->getUpdateMetadataFunc(), + ]; + $client = new helloworld\GreeterClient( + new Grpc\BaseStub('localhost:50051', $opts)); + + $request = new helloworld\HelloRequest(); + $request->setName($name); + list($reply, $status) = $client->SayHello($request)->wait(); + $message = $reply->getMessage(); + return $message; +} + +$name = !empty($argv[1]) ? $argv[1] : 'world'; +print(greet($name)."\n"); diff --git a/php/run_greeter_client_with_auth.sh b/php/run_greeter_client_with_auth.sh new file mode 100755 index 0000000000..b367096b9b --- /dev/null +++ b/php/run_greeter_client_with_auth.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# 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. + +set -e +cd $(dirname $0) +command -v brew >/dev/null 2>&1 && \ + extension_dir="-d extension_dir="`brew --prefix`/opt/grpc-php +# path to project credentials .json file +export GOOGLE_APPLICATION_CREDENTIALS='' +php $extension_dir -d extension=grpc.so greeter_client_with_auth.php $1 -- cgit v1.2.3 From 20f68f6a63713ab2a9d59732cbc6c8a956c8735e Mon Sep 17 00:00:00 2001 From: Misha Brukman Date: Wed, 24 Jun 2015 09:44:39 -0400 Subject: Add syntax highlighting for C++ code samples. --- grpc-auth-support.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grpc-auth-support.md b/grpc-auth-support.md index 6a5ef0fa3d..78dfd9ade2 100644 --- a/grpc-auth-support.md +++ b/grpc-auth-support.md @@ -31,7 +31,7 @@ Tokens to each request being made on the channel. This is the simplest authentication scenario, where a client just wants to authenticate the server and encrypt all data. -``` +```cpp SslCredentialsOptions ssl_opts; // Options to override SSL params, empty by default // Create the credentials object by providing service account key in constructor std::unique_ptr creds = CredentialsFactory::SslCredentials(ssl_opts); @@ -52,7 +52,7 @@ passed to the factory method. gRPC applications can use a simple API to create a credential that works in various deployment scenarios. -``` +```cpp std::unique_ptr creds = CredentialsFactory::GoogleDefaultCredentials(); // Create a channel, stub and make RPC calls (same as in the previous example) std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); -- cgit v1.2.3 From 05514b042497a4584ec092f40af09d811f904da5 Mon Sep 17 00:00:00 2001 From: Misha Brukman Date: Wed, 24 Jun 2015 09:45:20 -0400 Subject: Fix comments: code blocks ignore MarkDown. --- grpc-auth-support.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grpc-auth-support.md b/grpc-auth-support.md index 78dfd9ade2..7f538d1a84 100644 --- a/grpc-auth-support.md +++ b/grpc-auth-support.md @@ -108,7 +108,7 @@ stub = Helloworld::Greeter::Stub.new('localhost:50051') ... # Authenticating with Google -require 'googleauth' # from [googleauth](http://www.rubydoc.info/gems/googleauth/0.1.0) +require 'googleauth' # from http://www.rubydoc.info/gems/googleauth/0.1.0 ... creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file scope = 'https://www.googleapis.com/auth/grpc-testing' -- cgit v1.2.3 From 865deaeee9ff5c89864dd89c360b0e2c2b1e2c7c Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 24 Jun 2015 11:24:17 -0700 Subject: remove with_auth example because no ssl --- php/greeter_client_with_auth.php | 57 ------------------------------------- php/run_greeter_client_with_auth.sh | 37 ------------------------ 2 files changed, 94 deletions(-) delete mode 100644 php/greeter_client_with_auth.php delete mode 100755 php/run_greeter_client_with_auth.sh diff --git a/php/greeter_client_with_auth.php b/php/greeter_client_with_auth.php deleted file mode 100644 index 39e28fcb80..0000000000 --- a/php/greeter_client_with_auth.php +++ /dev/null @@ -1,57 +0,0 @@ - Grpc\Credentials::createSsl( - // file_get_contents(getenv('SSL_CERT_FILE'))), - 'update_metadata' => $auth->getUpdateMetadataFunc(), - ]; - $client = new helloworld\GreeterClient( - new Grpc\BaseStub('localhost:50051', $opts)); - - $request = new helloworld\HelloRequest(); - $request->setName($name); - list($reply, $status) = $client->SayHello($request)->wait(); - $message = $reply->getMessage(); - return $message; -} - -$name = !empty($argv[1]) ? $argv[1] : 'world'; -print(greet($name)."\n"); diff --git a/php/run_greeter_client_with_auth.sh b/php/run_greeter_client_with_auth.sh deleted file mode 100755 index b367096b9b..0000000000 --- a/php/run_greeter_client_with_auth.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash -# 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. - -set -e -cd $(dirname $0) -command -v brew >/dev/null 2>&1 && \ - extension_dir="-d extension_dir="`brew --prefix`/opt/grpc-php -# path to project credentials .json file -export GOOGLE_APPLICATION_CREDENTIALS='' -php $extension_dir -d extension=grpc.so greeter_client_with_auth.php $1 -- cgit v1.2.3 From 1f0d49bb6e91571cb2a56f3bed2be76a3ea3ec92 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Wed, 8 Jul 2015 16:44:55 -0700 Subject: Fixes per the review. --- objective-c/auth_sample/README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/objective-c/auth_sample/README.md b/objective-c/auth_sample/README.md index 06812323bc..b6776860a1 100644 --- a/objective-c/auth_sample/README.md +++ b/objective-c/auth_sample/README.md @@ -11,7 +11,7 @@ headers. It assumes you know the basics on how to make gRPC API calls using the Objective-C client library, as shown in the [Hello World](https://github.com/grpc/grpc-common/tree/master/objective-c/helloworld) or [Route Guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide) tutorials, -and familiarity with OAuth2 concepts like _access token_. +and are familiar with OAuth2 concepts like _access token_. - [Example code and setup](#setup) - [Try it out!](#try) @@ -42,9 +42,9 @@ access token obtained by the first view. Note: OAuth2 libraries need the application to register and obtain an ID from the identity provider (in the case of this example app, Google). The app's XCode project is configured using that ID, so -you shouldn't copy this project as is for your own app: It would result in your app being identified -in the consent screen as "gRPC-AuthSample", and not having access to real Google services. Instead, -configure your XCode project following the [instructions here](https://developers.google.com/identity/sign-in/ios/). +you shouldn't copy this project "as is" for your own app: it would result in your app being +identified in the consent screen as "gRPC-AuthSample", and not having access to real Google +services. Instead, configure your own XCode project following the [instructions here](https://developers.google.com/identity/sign-in/ios/). As with the other examples, you also should have [Cocoapods](https://cocoapods.org/#install) installed, as well as the relevant tools to generate the client library code. You can obtain the @@ -74,7 +74,7 @@ give the "gRPC-AuthSample" app the following permissions: - "Test scope for access to the Zoo service". This last permission, corresponding to the scope `https://www.googleapis.com/auth/xapi.zoo` doesn't -grant any real capability: It's only used for testing. You can log out at any moment. +grant any real capability: it's only used for testing. You can log out at any time. The second view, `MakeRPCViewController.h/m`, makes a gRPC request to a test server at https://grpc-test.sandbox.google.com, sending the access token along with the request. The test @@ -102,8 +102,8 @@ service TestService { } ``` -A `unaryCallWithRequest:handler:` method is generated, with which you're already familiar, is -generated for the `AUTHTestService` class: +A `unaryCallWithRequest:handler:` method, with which you're already familiar, is generated for the +`AUTHTestService` class: ```objective-c [client unaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { @@ -111,7 +111,7 @@ generated for the `AUTHTestService` class: }]; ``` -And a second `RPCToUnaryCallWithRequest:handler:` method is generated, which returns a +In addition, an `RPCToUnaryCallWithRequest:handler:` method is generated, which returns a not-yet-started RPC object: ```objective-c @@ -156,8 +156,8 @@ If you have an access token, OAuth2 specifies it is to be sent in this format: ## Get response metadata of a call: Auth challenge header -Analogously to the request metadata, the `ProtoRPC` class has a `responseMetadata` property defined -this way: +The `ProtoRPC` class also has a `responseMetadata` property, analogous to the request metadata we +just looked at. It's defined like this: ```objective-c @property(atomic, readonly) NSDictionary *responseMetadata; -- cgit v1.2.3 From 71e4c9679fa556d24f390adb3fc89f8675f3ec53 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Thu, 9 Jul 2015 10:10:15 -0700 Subject: Explain a bit more what metadata is. --- objective-c/auth_sample/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/objective-c/auth_sample/README.md b/objective-c/auth_sample/README.md index b6776860a1..335e29f98b 100644 --- a/objective-c/auth_sample/README.md +++ b/objective-c/auth_sample/README.md @@ -139,7 +139,8 @@ The `ProtoRPC` class has a `requestMetadata` property defined like this: ``` Setting it to a dictionary of metadata keys and values will have them sent on the wire when the call -is started. +is started. gRPC metadata are pieces of information about the call sent by the client to the server +(and vice versa). They take the form of key-value pairs and are essentially opaque to gRPC itself. ```objective-c call.requestMetadata = [NSMutableDictionary dictionaryWithDictionary: -- cgit v1.2.3 From 03515a50c74749f84d8279837c988eaa17f55920 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 9 Jul 2015 21:59:48 -0700 Subject: upgrade greeter to use 0.6.0 release packages --- csharp/.nuget/packages.config | 2 +- csharp/Greeter/Greeter.csproj | 19 ++++++++++--------- csharp/Greeter/packages.config | 8 ++++---- csharp/GreeterClient/GreeterClient.csproj | 19 ++++++++++--------- csharp/GreeterClient/packages.config | 8 ++++---- csharp/GreeterServer/GreeterServer.csproj | 19 ++++++++++--------- csharp/GreeterServer/packages.config | 8 ++++---- 7 files changed, 43 insertions(+), 40 deletions(-) diff --git a/csharp/.nuget/packages.config b/csharp/.nuget/packages.config index 966d46a283..b14373069f 100644 --- a/csharp/.nuget/packages.config +++ b/csharp/.nuget/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/csharp/Greeter/Greeter.csproj b/csharp/Greeter/Greeter.csproj index 8899836e97..b8f965dbd2 100644 --- a/csharp/Greeter/Greeter.csproj +++ b/csharp/Greeter/Greeter.csproj @@ -1,6 +1,6 @@  - + @@ -13,7 +13,7 @@ Greeter Greeter v4.5 - 4d99595a + 927432a0 true @@ -40,13 +40,14 @@ ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - + False - ..\packages\Grpc.Core.0.5.1\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll - - ..\packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll @@ -71,10 +72,10 @@ - - + + - + \ No newline at end of file diff --git a/csharp/Greeter/packages.config b/csharp/Greeter/packages.config index 481390ef9d..5922553bc3 100644 --- a/csharp/Greeter/packages.config +++ b/csharp/Greeter/packages.config @@ -1,11 +1,11 @@  - - + + - + - + \ No newline at end of file diff --git a/csharp/GreeterClient/GreeterClient.csproj b/csharp/GreeterClient/GreeterClient.csproj index 3a1feb367e..59b768af01 100644 --- a/csharp/GreeterClient/GreeterClient.csproj +++ b/csharp/GreeterClient/GreeterClient.csproj @@ -1,6 +1,6 @@  - + @@ -13,7 +13,7 @@ GreeterClient GreeterClient v4.5 - 9e922694 + 985ca8be true @@ -40,13 +40,14 @@ ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - + False - ..\packages\Grpc.Core.0.5.1\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll - - ..\packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll @@ -74,10 +75,10 @@ - - + + - + \ No newline at end of file diff --git a/csharp/GreeterClient/packages.config b/csharp/GreeterClient/packages.config index 481390ef9d..5922553bc3 100644 --- a/csharp/GreeterClient/packages.config +++ b/csharp/GreeterClient/packages.config @@ -1,11 +1,11 @@  - - + + - + - + \ No newline at end of file diff --git a/csharp/GreeterServer/GreeterServer.csproj b/csharp/GreeterServer/GreeterServer.csproj index da73168dc5..cd50d6cd52 100644 --- a/csharp/GreeterServer/GreeterServer.csproj +++ b/csharp/GreeterServer/GreeterServer.csproj @@ -1,6 +1,6 @@  - + @@ -13,7 +13,7 @@ GreeterServer GreeterServer v4.5 - d79af25e + a1eeb1d8 true @@ -40,13 +40,14 @@ ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - + False - ..\packages\Grpc.Core.0.5.1\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll - - ..\packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll @@ -74,10 +75,10 @@ - - + + - + \ No newline at end of file diff --git a/csharp/GreeterServer/packages.config b/csharp/GreeterServer/packages.config index 481390ef9d..5922553bc3 100644 --- a/csharp/GreeterServer/packages.config +++ b/csharp/GreeterServer/packages.config @@ -1,11 +1,11 @@  - - + + - + - + \ No newline at end of file -- cgit v1.2.3 From 0ea1009381dc4efe8cebb833857513e4c53e90c8 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 9 Jul 2015 22:03:52 -0700 Subject: update route guide to use 0.6.0 release packages --- csharp/route_guide/.nuget/packages.config | 2 +- csharp/route_guide/RouteGuide/RouteGuide.csproj | 19 ++++++++++--------- csharp/route_guide/RouteGuide/packages.config | 8 ++++---- .../RouteGuideClient/RouteGuideClient.csproj | 19 ++++++++++--------- csharp/route_guide/RouteGuideClient/packages.config | 8 ++++---- .../RouteGuideServer/RouteGuideServer.csproj | 19 ++++++++++--------- csharp/route_guide/RouteGuideServer/packages.config | 8 ++++---- 7 files changed, 43 insertions(+), 40 deletions(-) diff --git a/csharp/route_guide/.nuget/packages.config b/csharp/route_guide/.nuget/packages.config index 966d46a283..b14373069f 100644 --- a/csharp/route_guide/.nuget/packages.config +++ b/csharp/route_guide/.nuget/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/csharp/route_guide/RouteGuide/RouteGuide.csproj b/csharp/route_guide/RouteGuide/RouteGuide.csproj index 3de2417c70..8358974aac 100644 --- a/csharp/route_guide/RouteGuide/RouteGuide.csproj +++ b/csharp/route_guide/RouteGuide/RouteGuide.csproj @@ -1,6 +1,6 @@  - + @@ -14,7 +14,7 @@ RouteGuide v4.5 512 - 58253d57 + 214cccda true @@ -40,17 +40,18 @@ ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - + False - ..\packages\Grpc.Core.0.5.1\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll False ..\packages\Newtonsoft.Json.7.0.1-beta2\lib\net45\Newtonsoft.Json.dll - - ..\packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll @@ -84,12 +85,12 @@ - - + + - + - -gRPC clients and servers can run and talk to each other in a variety of -environments - from servers inside Google to your own desktop - and can -be written in any of gRPC's [supported languages](#quickstart). So, for -example, you can easily create a gRPC server in Java with clients in Go, -Python, or Ruby. In addition, the latest Google APIs will have gRPC versions -of their interfaces, letting you easily build Google functionality into -your applications. - - -### Working with protocol buffers - -By default gRPC uses *protocol buffers*, Google’s -mature open source mechanism for serializing structured data (although it -can be used with other data formats such as JSON). As you'll -see in our example below, you define gRPC services using *proto files*, -with method parameters and return types specified as protocol buffer message -types. You -can find out lots more about protocol buffers in the [Protocol Buffers -documentation](https://developers.google.com/protocol-buffers/docs/overview). - -#### Protocol buffer versions - -While protocol buffers have been available for open source users for some -time, our examples use a new flavour of protocol buffers called proto3, -which has a slightly simplified syntax, some useful new features, and supports -lots more languages. This is currently available as an alpha release in -Java, C++, Java_nano (Android Java), Python, and Ruby from [the protocol buffers Github -repo](https://github.com/google/protobuf/releases), as well as a Go language -generator from [the golang/protobuf Github repo](https://github.com/golang/protobuf), with more languages in development. You can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3), and see -the major differences from the current default version in the [release notes](https://github.com/google/protobuf/releases). More proto3 documentation is coming soon. - -In general, while you *can* use proto2 (the current default protocol buffers version), we recommend that you use proto3 with gRPC as it lets you use the full range of gRPC-supported languages, as well as avoiding compatibility -issues with proto2 clients talking to proto3 servers and vice versa. - - -## Hello gRPC! - -Now that you know a bit more about gRPC, the easiest way to see how it -works is to look at a simple example. Our Hello World walks you through the -construction of a simple gRPC client-server application, showing you how to: - -- Create a protocol buffers schema that defines a simple RPC service with -a single -Hello World method. -- Create a Java server that implements this interface. -- Create a Java client that accesses the Java server. -- Create a Go client that accesses -the same Java server. - -The complete code for the example is available in the `grpc-common` GitHub -repository. We use the Git versioning system for source code management: -however, you don't need to know anything about Git to follow along other -than how to install and run a few git commands. - -This is an introductory example rather than a comprehensive tutorial, so -don't worry if you're not a Go or -Java developer - the concepts are similar for all languages, and you can -find more implementations of our Hello World example in other languages (and full tutorials where available) in -the [language-specific folders](#quickstart) in this repository. Complete tutorials and -reference documentation for all gRPC languages are coming soon. - - -### Setup - -This section explains how to set up your local machine to work with -the example code. If you just want to read the example, you can go straight -to the [next step](#servicedef). - -#### Install Git - -You can download and install Git from http://git-scm.com/download. Once -installed you should have access to the git command line tool. The main -commands that you will need to use are: - -- git clone ... : clone a remote repository onto your local machine -- git checkout ... : check out a particular branch or a tagged version of -the code to hack on - -#### Install gRPC - -To build and install gRPC plugins and related tools: -- For Java, see the [Java quick start](https://github.com/grpc/grpc-java). -- For Go, see the [Go quick start](https://github.com/grpc/grpc-go). - -#### Get the source code - -The example code for our Java example lives in the `grpc-java` -GitHub repository. Clone this repository to your local machine by running the -following command: - - -``` -git clone https://github.com/grpc/grpc-java.git -``` - -Change your current directory to grpc-java/examples - -``` -cd grpc-java/examples -``` - - - - -### Defining a service - -The first step in creating our example is to define a *service*: an RPC -service specifies the methods that can be called remotely with their parameters -and return types. As you saw in the -[overview](#protocolbuffers) above, gRPC does this using [protocol -buffers](https://developers.google.com/protocol-buffers/docs/overview). We -use the protocol buffers interface definition language (IDL) to define our -service methods, and define the parameters and return -types as protocol buffer message types. Both the client and the -server use interface code generated from the service definition. - -Here's our example service definition, defined using protocol buffers IDL in -[helloworld.proto](https://github.com/grpc/grpc-java/tree/master/examples/src/main/proto). The `Greeter` -service has one method, `SayHello`, that lets the server receive a single -`HelloRequest` -message from the remote client containing the user's name, then send back -a greeting in a single `HelloReply`. This is the simplest type of RPC you -can specify in gRPC - you can find out about other types in the tutorial for your chosen language. - -```proto -syntax = "proto3"; - -option java_package = "io.grpc.examples"; - -package helloworld; - -// The greeter service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} - -``` - - -### Generating gRPC code - -Once we've defined our service, we use the protocol buffer compiler -`protoc` to generate the special client and server code we need to create -our application - right now we're going to generate Java code, though you -can generate gRPC code in any gRPC-supported language (as you'll see later -in this example). The generated code contains both stub code for clients to -use and an abstract interface for servers to implement, both with the method -defined in our `Greeter` service. - -(If you didn't install the gRPC plugins and protoc on your system and are just reading along with -the example, you can skip this step and move -onto the next one where we examine the generated code.) - -For simplicity, we've provided a [Gradle build file](https://github.com/grpc/grpc-java/blob/master/examples/build.gradle) with our Java examples that runs `protoc` for you with the appropriate plugin, input, and output: - -```shell -../gradlew build -``` - -This generates the following classes from our .proto, which contain all the generated code -we need to create our example: - -- `Helloworld.java`, which -has all the protocol buffer code to populate, serialize, and retrieve our -`HelloRequest` and `HelloReply` message types -- `GreeterGrpc.java`, which contains (along with some other useful code): - - an interface for `Greeter` servers to implement - - ```java - public static interface Greeter { - public void sayHello(io.grpc.examples.Helloworld.HelloRequest request, - io.grpc.stub.StreamObserver responseObserver); - } - ``` - - - _stub_ classes that clients can use to talk to a `Greeter` server. As you can see, they also implement the `Greeter` interface. - - ```java - public static class GreeterStub extends - io.grpc.stub.AbstractStub - implements Greeter { - ... - } - ``` - - -### Writing a server - -Now let's write some code! First we'll create a server application to implement -our service. Note that we're not going to go into a lot of detail about how -to create a server in this section. More detailed information will be in the -tutorial for your chosen language: check if there's one available yet in the relevant [quick start](#quickstart). - -Our server application has two classes: - -- a main server class that hosts the service implementation and allows access over the -network: [HelloWorldServer.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java). - - -- a simple service implementation class [GreeterImpl.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java#L51). - - -#### Service implementation - -[GreeterImpl.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java#L51) -actually implements our `Greeter` service's required behaviour. - -As you can see, the class `GreeterImpl` implements the interface -`GreeterGrpc.Greeter` that we [generated](#generating) from our proto -[IDL](https://github.com/grpc/grpc-java/tree/master/examples/src/main/proto) by implementing the method `sayHello`: - -```java - @Override - public void sayHello(HelloRequest req, StreamObserver responseObserver) { - HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build(); - responseObserver.onValue(reply); - responseObserver.onCompleted(); - } -``` -- `sayHello` takes two parameters: - - `HelloRequest`: the request - - `StreamObserver`: a response observer, which is - a special interface for the server to call with its response - -To return our response to the client and complete the call: - -1. We construct and populate a `HelloReply` response object with our exciting -message, as specified in our interface definition. -2. We return the `HelloReply` to the client and then specify that we've finished dealing with the RPC. - - -#### Server implementation - -[HelloWorldServer.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java) -shows the other main feature required to provide a gRPC service; making the service -implementation available from the network. - -```java - /* The port on which the server should run */ - private int port = 50051; - private ServerImpl server; - - private void start() throws Exception { - server = NettyServerBuilder.forPort(port) - .addService(GreeterGrpc.bindService(new GreeterImpl())) - .build().start(); - logger.info("Server started, listening on " + port); - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - // Use stderr here since the logger may have been reset by its JVM shutdown hook. - System.err.println("*** shutting down gRPC server since JVM is shutting down"); - HelloWorldServer.this.stop(); - System.err.println("*** server shut down"); - } - }); - } - -``` - -Here we create an appropriate gRPC server, binding the `Greeter` service -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. - - -### Writing a client - -Client-side gRPC is pretty simple. In this step, we'll use the generated code -to write a simple client that can access the `Greeter` server we created -in the [previous section](#server). You can see the complete client code in -[HelloWorldClient.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldClient.java). - -Again, we're not going to go into much detail about how to implement a client; -we'll leave that for the tutorial. - -#### Connecting to the service - -First let's look at how we connect to the `Greeter` server. First we need -to create a gRPC channel, specifying the hostname and port of the server we -want to connect to. Then we use the channel to construct the stub instance. - - -```java - private final ChannelImpl channel; - private final GreeterGrpc.GreeterBlockingStub blockingStub; - - public HelloWorldClient(String host, int port) { - channel = - NettyChannelBuilder.forAddress(host, port).negotiationType(NegotiationType.PLAINTEXT) - .build(); - blockingStub = GreeterGrpc.newBlockingStub(channel); - } - -``` - -In this case, we create a blocking stub. This means that the RPC call waits -for the server to respond, and will either return a response or raise an -exception. gRPC Java has other kinds of stubs that make non-blocking calls -to the server, where the response is returned asynchronously. - -#### Calling an RPC - -Now we can contact the service and obtain a greeting: - -1. We construct and fill in a `HelloRequest` to send to the service. -2. We call the stub's `hello()` RPC with our request and get a `HelloReply` -back, from which we can get our greeting. - - -```java - HelloRequest req = HelloRequest.newBuilder().setName(name).build(); - HelloReply reply = blockingStub.sayHello(req); - -``` - - -### Try it out! - -Our [Gradle build file](https://github.com/grpc/grpc-java/blob/master/examples/build.gradle) simplifies building and running the examples. - -You can build and run the server from the `grpc-java` root folder with: - -```sh -$ ./gradlew :grpc-examples:helloWorldServer -``` - -and in another terminal window confirm that it receives a message. - -```sh -$ ./gradlew :grpc-examples:helloWorldClient -``` - -### 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 looked at Java code -generated from and implementing our `Greeter` service definition. However, -as you'll see if you look at the language-specific subdirectories -in this repository, we've also generated and implemented `Greeter` -in some of gRPC's other supported languages. Each service -and client uses interface code generated from the same proto -that we used for the Java example. - -So, for example, if we visit the [`go` example -directory](https://github.com/grpc/grpc-common/tree/master/go) and look at the -[`greeter_client`](https://github.com/grpc/grpc-common/blob/master/go/greeter_client/main.go), -we can see that like the Java client, it connects to a `Greeter` service -at `localhost:50051` and uses a stub to call the `SayHello` method with a -`HelloRequest`: - -```go -const ( - address = "localhost:50051" - defaultName = "world" -) - -func main() { - // Set up a connection to the server. - conn, err := grpc.Dial(address) - if err != nil { - log.Fatalf("did not connect: %v", err) - } - defer conn.Close() - c := pb.NewGreeterClient(conn) - - // Contact the server and print out its response. - name := defaultName - if len(os.Args) > 1 { - name = os.Args[1] - } - r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: - name}) - if err != nil { - log.Fatalf("could not greet: %v", err) - } - log.Printf("Greeting: %s", r.Message) -} -``` - - -If we run the Java server from earlier in another terminal window, we can -run the Go client and connect to it just like the Java client, even though -it's written in a different language. - -``` -$ greeter_client -``` -## Read more! - -- You can find links to language-specific tutorials, examples, and other docs in each language's [quick start](#quickstart). -- [gRPC Authentication Support](https://github.com/grpc/grpc-common/blob/master/grpc-auth-support.md) introduces authentication support in gRPC with supported mechanisms and examples. diff --git a/cpp/README.md b/cpp/README.md deleted file mode 100644 index e0a09ff8b8..0000000000 --- a/cpp/README.md +++ /dev/null @@ -1,65 +0,0 @@ -#gRPC in 3 minutes (C++) - -## Installation - -To install gRPC on your system, follow the instructions here: -[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). - -## Hello C++ gRPC! - -Here's how to build and run the C++ implementation of the [Hello World](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto) example used in [Getting started](https://github.com/grpc/grpc-common). - -The example code for this and our other examples lives in the `grpc-common` -GitHub repository. Clone this repository to your local machine by running the -following command: - - -```sh -$ git clone https://github.com/grpc/grpc-common.git -``` - -Change your current directory to grpc-common/cpp/helloworld - -```sh -$ cd grpc-common/cpp/helloworld/ -``` - - -### Generating gRPC code - -To generate the client and server side interfaces: - -```sh -$ make helloworld.grpc.pb.cc helloworld.pb.cc -``` -Which internally invokes the proto-compiler as: - -```sh -$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto -$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto -``` - -### Client and server implementations - -The client implementation is at [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). - -The server implementation is at [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). - -### Try it! -Build client and server: -```sh -$ make -``` -Run the server, which will listen on port 50051: -```sh -$ ./greeter_server -``` -Run the client (in a different terminal): -```sh -$ ./greeter_client -``` -If things go smoothly, you will see the "Greeter received: Hello world" in the client side output. - -## Tutorial - -You can find a more detailed tutorial in [gRPC Basics: C++](https://github.com/grpc/grpc-common/blob/master/cpp/cpptutorial.md) diff --git a/cpp/cpptutorial.md b/cpp/cpptutorial.md deleted file mode 100644 index c19b472744..0000000000 --- a/cpp/cpptutorial.md +++ /dev/null @@ -1,365 +0,0 @@ -#gRPC Basics: C++ - -This tutorial provides a basic C++ programmer's introduction to working with gRPC. By walking through this example you'll learn how to: - -- Define a service in a .proto file. -- Generate server and client code using the protocol buffer compiler. -- Use the C++ gRPC API to write a simple client and server for your service. - -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. - -This isn't a comprehensive guide to using gRPC in C++: more reference documentation is coming soon. - -## Why use gRPC? - -Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. - -With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. - -## Example code and setup - -The example code for our tutorial is in [grpc/grpc-common/cpp/route_guide](https://github.com/grpc/grpc-common/tree/master/cpp/route_guide). To download the example, clone the `grpc-common` repository by running the following command: -```shell -$ git clone https://github.com/grpc/grpc-common.git -``` - -Then change your current directory to `grpc-common/cpp/route_guide`: -```shell -$ cd grpc-common/cpp/route_guide -``` - -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the C++ quick start guide](https://github.com/grpc/grpc-common/tree/master/cpp). - - -## Defining the service - -Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). - -To define a service, you specify a named `service` in your .proto file: - -``` -service RouteGuide { - ... -} -``` - -Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: - -- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. -``` - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} -``` - -- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. -``` - // Obtains the Features available within the given Rectangle. Results are - // streamed rather than returned at once (e.g. in a response message with a - // repeated field), as the rectangle may cover a large area and contain a - // huge number of features. - rpc ListFeatures(Rectangle) returns (stream Feature) {} -``` - -- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a client-side streaming method by placing the `stream` keyword before the *request* type. -``` - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} -``` - -- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -``` - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -``` - -Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -``` -// 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; -} -``` - - -## Generating client and server code - -Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. - -For simplicity, we've provided a [makefile](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): - -```shell -$ make route_guide.grpc.pb.cc route_guide.pb.cc -``` - -which actually runs: - -```shell -$ protoc -I ../../protos --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ../../protos/route_guide.proto -$ protoc -I ../../protos --cpp_out=. ../../protos/route_guide.proto -``` - -Running this command generates the following files in your current directory: -- `route_guide.pb.h`, the header which declares your generated message classes -- `route_guide.pb.cc`, which contains the implementation of your message classes -- `route_guide.grpc.pb.h`, the header which declares your generated service classes -- `route_guide.grpc.pb.cc`, which contains the implementation of your service classes - -These contain: -- All the protocol buffer code to populate, serialize, and retrieve our request and response message types -- A class called `RouteGuide` that contains - - a remote interface type (or *stub*) for clients to call with the methods defined in the `RouteGuide` service. - - two abstract interfaces for servers to implement, also with the methods defined in the `RouteGuide` service. - - - -## Creating the server - -First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). - -There are two parts to making our `RouteGuide` service do its job: -- Implementing the service interface generated from our service definition: doing the actual "work" of our service. -- Running a gRPC server to listen for requests from clients and return the service responses. - -You can find our example `RouteGuide` server in [grpc-common/cpp/route_guide/route_guide_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_server.cc). Let's take a closer look at how it works. - -### Implementing RouteGuide - -As you can see, our server has a `RouteGuideImpl` class that implements the generated `RouteGuide::Service` interface: - -```cpp -class RouteGuideImpl final : public RouteGuide::Service { -... -} -``` -In this case we're implementing the *synchronous* version of `RouteGuide`, which provides our default gRPC server behaviour. It's also possible to implement an asynchronous interface, `RouteGuide::AsyncService`, which allows you to further customize your server's threading behaviour, though we won't look at this in this tutorial. - -`RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. - -```cpp - Status GetFeature(ServerContext* context, const Point* point, - Feature* feature) override { - feature->set_name(GetFeatureName(*point, feature_list_)); - feature->mutable_location()->CopyFrom(*point); - return Status::OK; - } -``` - -The method is passed a context object for the RPC, the client's `Point` protocol buffer request, and a `Feature` protocol buffer to fill in with the response information. In the method we populate the `Feature` with the appropriate information, and then `return` with an `OK` status to tell gRPC that we've finished dealing with the RPC and that the `Feature` can be returned to the client. - -Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. - -```cpp - Status ListFeatures(ServerContext* context, const Rectangle* rectangle, - ServerWriter* writer) override { - auto lo = rectangle->lo(); - auto hi = rectangle->hi(); - long left = std::min(lo.longitude(), hi.longitude()); - long right = std::max(lo.longitude(), hi.longitude()); - long top = std::max(lo.latitude(), hi.latitude()); - long bottom = std::min(lo.latitude(), hi.latitude()); - for (const Feature& f : feature_list_) { - if (f.location().longitude() >= left && - f.location().longitude() <= right && - f.location().latitude() >= bottom && - f.location().latitude() <= top) { - writer->Write(f); - } - } - return Status::OK; - } -``` - -As you can see, instead of getting simple request and response objects in our method parameters, this time we get a request object (the `Rectangle` in which our client wants to find `Feature`s) and a special `ServerWriter` object. In the method, we populate as many `Feature` objects as we need to return, writing them to the `ServerWriter` using its `Write()` method. Finally, as in our simple RPC, we `return Status::OK` to tell gRPC that we've finished writing responses. - -If you look at the client-side streaming method `RecordRoute` you'll see it's quite similar, except this time we get a `ServerReader` instead of a request object and a single response. We use the `ServerReader`s `Read()` method to repeatedly read in our client's requests to a request object (in this case a `Point`) until there are no more messages: the server needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. - -```cpp -while (stream->Read(&point)) { - ...//process client input -} -``` -Finally, let's look at our bidirectional streaming RPC `RouteChat()`. - -```cpp - Status RouteChat(ServerContext* context, - ServerReaderWriter* stream) override { - std::vector received_notes; - RouteNote note; - while (stream->Read(¬e)) { - for (const RouteNote& n : received_notes) { - if (n.location().latitude() == note.location().latitude() && - n.location().longitude() == note.location().longitude()) { - stream->Write(n); - } - } - received_notes.push_back(note); - } - - return Status::OK; - } -``` - -This time we get a `ServerReaderWriter` that can be used to read *and* write messages. The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. - -### Starting the server - -Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: - -```cpp -void RunServer(const std::string& db_path) { - std::string server_address("0.0.0.0:50051"); - RouteGuideImpl service(db_path); - - ServerBuilder builder; - builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); - builder.RegisterService(&service); - std::unique_ptr server(builder.BuildAndStart()); - std::cout << "Server listening on " << server_address << std::endl; - server->Wait(); -} -``` -As you can see, we build and start our server using a `ServerBuilder`. To do this, we: - -1. Create an instance of our service implementation class `RouteGuideImpl`. -2. Create an instance of the factory `ServerBuilder` class. -3. Specify the address and port we want to use to listen for client requests using the builder's `AddListeningPort()` method. -4. Register our service implementation with the builder. -5. Call `BuildAndStart()` on the builder to create and start an RPC server for our service. -5. Call `Wait()` on the server to do a blocking wait until process is killed or `Shutdown()` is called. - - -## Creating the client - -In this section, we'll look at creating a C++ client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/cpp/route_guide/route_guide_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_client.cc). - -### Creating a stub - -To call service methods, we first need to create a *stub*. - -First we need to create a gRPC *channel* for our stub, specifying the server address and port we want to connect to and any special channel arguments - in our case we'll use the default `ChannelArguments` and no SSL: - -```cpp -grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), ChannelArguments()); -``` - -Now we can use the channel to create our stub using the `NewStub` method provided in the `RouteGuide` class we generated from our .proto. - -```cpp - public: - RouteGuideClient(std::shared_ptr channel, const std::string& db) - : stub_(RouteGuide::NewStub(channel)) { - ... - } -``` - -### Calling service methods - -Now let's look at how we call our service methods. Note that in this tutorial we're calling the *blocking/synchronous* versions of each method: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception. - -#### Simple RPC - -Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. - -```cpp - Point point; - Feature feature; - point = MakePoint(409146138, -746188906); - GetOneFeature(point, &feature); - -... - - bool GetOneFeature(const Point& point, Feature* feature) { - ClientContext context; - Status status = stub_->GetFeature(&context, point, feature); - ... - } -``` - -As you can see, we create and populate a request protocol buffer object (in our case `Point`), and create a response protocol buffer object for the server to fill in. We also create a `ClientContext` object for our call - you can optionally set RPC configuration values on this object, such as deadlines, though for now we'll use the default settings. Note that you cannot reuse this object between calls. Finally, we call the method on the stub, passing it the context, request, and response. If the method returns `OK`, then we can read the response information from the server from our response object. - -```cpp - std::cout << "Found feature called " << feature->name() << " at " - << feature->location().latitude()/kCoordFactor_ << ", " - << feature->location().longitude()/kCoordFactor_ << std::endl; -``` - -#### Streaming RPCs - -Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: - -```cpp - std::unique_ptr > reader( - stub_->ListFeatures(&context, rect)); - while (reader->Read(&feature)) { - std::cout << "Found feature called " - << feature.name() << " at " - << feature.location().latitude()/kCoordFactor_ << ", " - << feature.location().longitude()/kCoordFactor_ << std::endl; - } - Status status = reader->Finish(); -``` - -Instead of passing the method a context, request, and response, we pass it a context and request and get a `ClientReader` object back. The client can use the `ClientReader` to read the server's responses. We use the `ClientReader`s `Read()` method to repeatedly read in the server's responses to a response protocol buffer object (in this case a `Feature`) until there are no more messages: the client needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. Finally, we call `Finish()` on the stream to complete the call and get our RPC status. - -The client-side streaming method `RecordRoute` is similar, except there we pass the method a context and response object and get back a `ClientWriter`. - -```cpp - std::unique_ptr > writer( - stub_->RecordRoute(&context, &stats)); - for (int i = 0; i < kPoints; i++) { - const Feature& f = feature_list_[feature_distribution(generator)]; - std::cout << "Visiting point " - << f.location().latitude()/kCoordFactor_ << ", " - << f.location().longitude()/kCoordFactor_ << std::endl; - if (!writer->Write(f.location())) { - // Broken stream. - break; - } - std::this_thread::sleep_for(std::chrono::milliseconds( - delay_distribution(generator))); - } - writer->WritesDone(); - Status status = writer->Finish(); - if (status.IsOk()) { - std::cout << "Finished trip with " << stats.point_count() << " points\n" - << "Passed " << stats.feature_count() << " features\n" - << "Travelled " << stats.distance() << " meters\n" - << "It took " << stats.elapsed_time() << " seconds" - << std::endl; - } else { - std::cout << "RecordRoute rpc failed." << std::endl; - } -``` - -Once we've finished writing our client's requests to the stream using `Write()`, we need to call `WritesDone()` on the stream to let gRPC know that we've finished writing, then `Finish()` to complete the call and get our RPC status. If the status is `OK`, our response object that we initially passed to `RecordRoute()` will be populated with the server's response. - -Finally, let's look at our bidirectional streaming RPC `RouteChat()`. In this case, we just pass a context to the method and get back a `ClientReaderWriter`, which we can use to both write and read messages. - -```cpp - std::shared_ptr > stream( - stub_->RouteChat(&context)); -``` - -The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. - -## Try it out! - -Build client and server: -```shell -$ make -``` -Run the server, which will listen on port 50051: -```shell -$ ./route_guide_server -``` -Run the client (in a different terminal): -```shell -$ ./route_guide_client -``` - diff --git a/cpp/helloworld/Makefile b/cpp/helloworld/Makefile deleted file mode 100644 index f2093afa05..0000000000 --- a/cpp/helloworld/Makefile +++ /dev/null @@ -1,119 +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. -# - -CXX = g++ -CPPFLAGS += -I/usr/local/include -pthread -CXXFLAGS += -std=c++11 -LDFLAGS += -L/usr/local/lib -lgrpc++_unsecure -lgrpc -lgpr -lprotobuf -lpthread -ldl -PROTOC = protoc -GRPC_CPP_PLUGIN = grpc_cpp_plugin -GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` - -PROTOS_PATH = ../../protos - -vpath %.proto $(PROTOS_PATH) - -all: system-check greeter_client greeter_server greeter_async_client greeter_async_server - -greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o - $(CXX) $^ $(LDFLAGS) -o $@ - -greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o - $(CXX) $^ $(LDFLAGS) -o $@ - -greeter_async_client: helloworld.pb.o helloworld.grpc.pb.o greeter_async_client.o - $(CXX) $^ $(LDFLAGS) -o $@ - -greeter_async_server: helloworld.pb.o helloworld.grpc.pb.o greeter_async_server.o - $(CXX) $^ $(LDFLAGS) -o $@ - -%.grpc.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< - -%.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< - -clean: - rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server greeter_async_client greeter_async_server - - -# The following is to test your system and ensure a smoother experience. -# They are by no means necessary to actually compile a grpc-enabled software. - -PROTOC_CMD = which $(PROTOC) -PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 -PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) -HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) -ifeq ($(HAS_PROTOC),true) -HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) -endif -HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) - -SYSTEM_OK = false -ifeq ($(HAS_VALID_PROTOC),true) -ifeq ($(HAS_PLUGIN),true) -SYSTEM_OK = true -endif -endif - -system-check: -ifneq ($(HAS_VALID_PROTOC),true) - @echo " DEPENDENCY ERROR" - @echo - @echo "You don't have protoc 3.0.0 installed in your path." - @echo "Please install Google protocol buffers 3.0.0 and its compiler." - @echo "You can find it here:" - @echo - @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-alpha-1" - @echo - @echo "Here is what I get when trying to evaluate your version of protoc:" - @echo - -$(PROTOC) --version - @echo - @echo -endif -ifneq ($(HAS_PLUGIN),true) - @echo " DEPENDENCY ERROR" - @echo - @echo "You don't have the grpc c++ protobuf plugin installed in your path." - @echo "Please install grpc. You can find it here:" - @echo - @echo " https://github.com/grpc/grpc" - @echo - @echo "Here is what I get when trying to detect if you have the plugin:" - @echo - -which $(GRPC_CPP_PLUGIN) - @echo - @echo -endif -ifneq ($(SYSTEM_OK),true) - @false -endif diff --git a/cpp/helloworld/README.md b/cpp/helloworld/README.md deleted file mode 100644 index c406051e80..0000000000 --- a/cpp/helloworld/README.md +++ /dev/null @@ -1,260 +0,0 @@ -# gRPC C++ Hello World Tutorial - -### Install gRPC -Make sure you have installed gRPC on your system. Follow the instructions here: -[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). - -### Get the tutorial source code - -The example code for this and our other examples lives in the `grpc-common` -GitHub repository. Clone this repository to your local machine by running the -following command: - - -```sh -$ git clone https://github.com/grpc/grpc-common.git -``` - -Change your current directory to grpc-common/cpp/helloworld - -```sh -$ cd grpc-common/cpp/helloworld/ -``` - -### Defining a service - -The first step in creating our example is to define a *service*: an RPC -service specifies the methods that can be called remotely with their parameters -and return types. As you saw in the -[overview](#protocolbuffers) above, gRPC does this using [protocol -buffers](https://developers.google.com/protocol-buffers/docs/overview). We -use the protocol buffers interface definition language (IDL) to define our -service methods, and define the parameters and return -types as protocol buffer message types. Both the client and the -server use interface code generated from the service definition. - -Here's our example service definition, defined using protocol buffers IDL in -[helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). The `Greeting` -service has one method, `hello`, that lets the server receive a single -`HelloRequest` -message from the remote client containing the user's name, then send back -a greeting in a single `HelloReply`. This is the simplest type of RPC you -can specify in gRPC - we'll look at some other types later in this document. - -``` -syntax = "proto3"; - -option java_package = "ex.grpc"; - -package helloworld; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} - -``` - - -### Generating gRPC code - -Once we've defined our service, we use the protocol buffer compiler -`protoc` to generate the special client and server code we need to create -our application. The generated code contains both stub code for clients to -use and an abstract interface for servers to implement, both with the method -defined in our `Greeting` service. - -To generate the client and server side interfaces: - -```sh -$ make helloworld.grpc.pb.cc helloworld.pb.cc -``` -Which internally invokes the proto-compiler as: - -```sh -$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto -$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto -``` - -### Writing a client - -- Create a channel. A channel is a logical connection to an endpoint. A gRPC - channel can be created with the target address, credentials to use and - arguments as follows - - ``` - auto channel = CreateChannel("localhost:50051", InsecureCredentials(), ChannelArguments()); - ``` - -- Create a stub. A stub implements the rpc methods of a service and in the - generated code, a method is provided to created a stub with a channel: - - ``` - auto stub = helloworld::Greeter::NewStub(channel); - ``` - -- Make a unary rpc, with `ClientContext` and request/response proto messages. - - ``` - ClientContext context; - HelloRequest request; - request.set_name("hello"); - HelloReply reply; - Status status = stub->SayHello(&context, request, &reply); - ``` - -- Check returned status and response. - - ``` - if (status.ok()) { - // check reply.message() - } else { - // rpc failed. - } - ``` - -For a working example, refer to [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). - -### Writing a server - -- Implement the service interface - - ``` - 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; - } - }; - - ``` - -- Build a server exporting the service - - ``` - GreeterServiceImpl service; - ServerBuilder builder; - builder.AddListeningPort("0.0.0.0:50051", grpc::InsecureServerCredentials()); - builder.RegisterService(&service); - std::unique_ptr server(builder.BuildAndStart()); - ``` - -For a working example, refer to [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). - -### Writing asynchronous client and server - -gRPC uses `CompletionQueue` API for asynchronous operations. The basic work flow -is -- bind a `CompletionQueue` to a rpc call -- do something like a read or write, present with a unique `void*` tag -- call `CompletionQueue::Next` to wait for operations to complete. If a tag - appears, it indicates that the corresponding operation is complete. - -#### Async client - -The channel and stub creation code is the same as the sync client. - -- Initiate the rpc and create a handle for the rpc. Bind the rpc to a - `CompletionQueue`. - - ``` - CompletionQueue cq; - auto rpc = stub->AsyncSayHello(&context, request, &cq); - ``` - -- Ask for reply and final status, with a unique tag - - ``` - Status status; - rpc->Finish(&reply, &status, (void*)1); - ``` - -- Wait for the completion queue to return the next tag. The reply and status are - ready once the tag passed into the corresponding `Finish()` call is returned. - - ``` - void* got_tag; - bool ok = false; - cq.Next(&got_tag, &ok); - if (ok && got_tag == (void*)1) { - // check reply and status - } - ``` - -For a working example, refer to [greeter_async_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_async_client.cc). - -#### Async server - -The server implementation requests a rpc call with a tag and then wait for the -completion queue to return the tag. The basic flow is - -- Build a server exporting the async service - - ``` - helloworld::Greeter::AsyncService service; - ServerBuilder builder; - builder.AddListeningPort("0.0.0.0:50051", InsecureServerCredentials()); - builder.RegisterAsyncService(&service); - auto cq = builder.AddCompletionQueue(); - auto server = builder.BuildAndStart(); - ``` - -- Request one rpc - - ``` - ServerContext context; - HelloRequest request; - ServerAsyncResponseWriter responder; - service.RequestSayHello(&context, &request, &responder, &cq, &cq, (void*)1); - ``` - -- Wait for the completion queue to return the tag. The context, request and - responder are ready once the tag is retrieved. - - ``` - HelloReply reply; - Status status; - void* got_tag; - bool ok = false; - cq.Next(&got_tag, &ok); - if (ok && got_tag == (void*)1) { - // set reply and status - responder.Finish(reply, status, (void*)2); - } - ``` - -- Wait for the completion queue to return the tag. The rpc is finished when the - tag is back. - - ``` - void* got_tag; - bool ok = false; - cq.Next(&got_tag, &ok); - if (ok && got_tag == (void*)2) { - // clean up - } - ``` - -To handle multiple rpcs, the async server creates an object `CallData` to -maintain the state of each rpc and use the address of it as the unique tag. For -simplicity the server only uses one completion queue for all events, and runs a -main loop in `HandleRpcs` to query the queue. - -For a working example, refer to [greeter_async_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_async_server.cc). - - - - diff --git a/cpp/helloworld/greeter_async_client.cc b/cpp/helloworld/greeter_async_client.cc deleted file mode 100644 index d99f89b135..0000000000 --- a/cpp/helloworld/greeter_async_client.cc +++ /dev/null @@ -1,98 +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. - * - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include "helloworld.grpc.pb.h" - -using grpc::Channel; -using grpc::ChannelArguments; -using grpc::ClientAsyncResponseReader; -using grpc::ClientContext; -using grpc::CompletionQueue; -using grpc::Status; -using helloworld::HelloRequest; -using helloworld::HelloReply; -using helloworld::Greeter; - -class GreeterClient { - public: - explicit GreeterClient(std::shared_ptr channel) - : stub_(Greeter::NewStub(channel)) {} - - std::string SayHello(const std::string& user) { - HelloRequest request; - request.set_name(user); - HelloReply reply; - ClientContext context; - CompletionQueue cq; - Status status; - - std::unique_ptr > rpc( - stub_->AsyncSayHello(&context, request, &cq)); - rpc->Finish(&reply, &status, (void*)1); - void* got_tag; - bool ok = false; - cq.Next(&got_tag, &ok); - GPR_ASSERT(ok); - GPR_ASSERT(got_tag == (void*)1); - - if (status.ok()) { - return reply.message(); - } else { - return "Rpc failed"; - } - } - - private: - std::unique_ptr stub_; -}; - -int main(int argc, char** argv) { - GreeterClient greeter(grpc::CreateChannel( - "localhost:50051", grpc::InsecureCredentials(), ChannelArguments())); - std::string user("world"); - std::string reply = greeter.SayHello(user); - std::cout << "Greeter received: " << reply << std::endl; - - return 0; -} diff --git a/cpp/helloworld/greeter_async_server.cc b/cpp/helloworld/greeter_async_server.cc deleted file mode 100644 index b8a0dbf0e2..0000000000 --- a/cpp/helloworld/greeter_async_server.cc +++ /dev/null @@ -1,136 +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. - * - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include "helloworld.grpc.pb.h" - -using grpc::Server; -using grpc::ServerAsyncResponseWriter; -using grpc::ServerBuilder; -using grpc::ServerContext; -using grpc::ServerCompletionQueue; -using grpc::Status; -using helloworld::HelloRequest; -using helloworld::HelloReply; -using helloworld::Greeter; - -class ServerImpl final { - public: - ~ServerImpl() { - server_->Shutdown(); - cq_->Shutdown(); - } - - // There is no shutdown handling in this code. - void Run() { - std::string server_address("0.0.0.0:50051"); - - ServerBuilder builder; - builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); - builder.RegisterAsyncService(&service_); - cq_ = builder.AddCompletionQueue(); - server_ = builder.BuildAndStart(); - std::cout << "Server listening on " << server_address << std::endl; - - HandleRpcs(); - } - - private: - class CallData { - public: - CallData(Greeter::AsyncService* service, ServerCompletionQueue* cq) - : service_(service), cq_(cq), responder_(&ctx_), status_(CREATE) { - Proceed(); - } - - void Proceed() { - if (status_ == CREATE) { - service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_, - this); - status_ = PROCESS; - } else if (status_ == PROCESS) { - new CallData(service_, cq_); - std::string prefix("Hello "); - reply_.set_message(prefix + request_.name()); - responder_.Finish(reply_, Status::OK, this); - status_ = FINISH; - } else { - delete this; - } - } - - private: - Greeter::AsyncService* service_; - ServerCompletionQueue* cq_; - ServerContext ctx_; - HelloRequest request_; - HelloReply reply_; - ServerAsyncResponseWriter responder_; - enum CallStatus { CREATE, PROCESS, FINISH }; - CallStatus status_; - }; - - // This can be run in multiple threads if needed. - void HandleRpcs() { - new CallData(&service_, cq_.get()); - void* tag; - bool ok; - while (true) { - cq_->Next(&tag, &ok); - GPR_ASSERT(ok); - static_cast(tag)->Proceed(); - } - } - - std::unique_ptr cq_; - Greeter::AsyncService service_; - std::unique_ptr server_; -}; - -int main(int argc, char** argv) { - ServerImpl server; - server.Run(); - - return 0; -} diff --git a/cpp/helloworld/greeter_client.cc b/cpp/helloworld/greeter_client.cc deleted file mode 100644 index dd0358ac95..0000000000 --- a/cpp/helloworld/greeter_client.cc +++ /dev/null @@ -1,85 +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. - * - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include "helloworld.grpc.pb.h" - -using grpc::Channel; -using grpc::ChannelArguments; -using grpc::ClientContext; -using grpc::Status; -using helloworld::HelloRequest; -using helloworld::HelloReply; -using helloworld::Greeter; - -class GreeterClient { - public: - GreeterClient(std::shared_ptr channel) - : stub_(Greeter::NewStub(channel)) {} - - std::string SayHello(const std::string& user) { - HelloRequest request; - request.set_name(user); - HelloReply reply; - ClientContext context; - - Status status = stub_->SayHello(&context, request, &reply); - if (status.ok()) { - return reply.message(); - } else { - return "Rpc failed"; - } - } - - private: - std::unique_ptr stub_; -}; - -int main(int argc, char** argv) { - GreeterClient greeter( - grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), - ChannelArguments())); - std::string user("world"); - std::string reply = greeter.SayHello(user); - std::cout << "Greeter received: " << reply << std::endl; - - return 0; -} diff --git a/cpp/helloworld/greeter_server.cc b/cpp/helloworld/greeter_server.cc deleted file mode 100644 index c1efdf563c..0000000000 --- a/cpp/helloworld/greeter_server.cc +++ /dev/null @@ -1,78 +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. - * - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include "helloworld.grpc.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.AddListeningPort(server_address, grpc::InsecureServerCredentials()); - builder.RegisterService(&service); - std::unique_ptr server(builder.BuildAndStart()); - std::cout << "Server listening on " << server_address << std::endl; - server->Wait(); -} - -int main(int argc, char** argv) { - RunServer(); - - return 0; -} diff --git a/cpp/route_guide/Makefile b/cpp/route_guide/Makefile deleted file mode 100644 index b906177af3..0000000000 --- a/cpp/route_guide/Makefile +++ /dev/null @@ -1,113 +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. -# - -CXX = g++ -CPPFLAGS += -I/usr/local/include -pthread -CXXFLAGS += -std=c++11 -LDFLAGS += -L/usr/local/lib -lgrpc++_unsecure -lgrpc -lgpr -lprotobuf -lpthread -ldl -PROTOC = protoc -GRPC_CPP_PLUGIN = grpc_cpp_plugin -GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` - -PROTOS_PATH = ../../protos - -vpath %.proto $(PROTOS_PATH) - -all: system-check route_guide_client route_guide_server - -route_guide_client: route_guide.pb.o route_guide.grpc.pb.o route_guide_client.o helper.o - $(CXX) $^ $(LDFLAGS) -o $@ - -route_guide_server: route_guide.pb.o route_guide.grpc.pb.o route_guide_server.o helper.o - $(CXX) $^ $(LDFLAGS) -o $@ - -%.grpc.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< - -%.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< - -clean: - rm -f *.o *.pb.cc *.pb.h route_guide_client route_guide_server - - -# The following is to test your system and ensure a smoother experience. -# They are by no means necessary to actually compile a grpc-enabled software. - -PROTOC_CMD = which $(PROTOC) -PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 -PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) -HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) -ifeq ($(HAS_PROTOC),true) -HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) -endif -HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) - -SYSTEM_OK = false -ifeq ($(HAS_VALID_PROTOC),true) -ifeq ($(HAS_PLUGIN),true) -SYSTEM_OK = true -endif -endif - -system-check: -ifneq ($(HAS_VALID_PROTOC),true) - @echo " DEPENDENCY ERROR" - @echo - @echo "You don't have protoc 3.0.0 installed in your path." - @echo "Please install Google protocol buffers 3.0.0 and its compiler." - @echo "You can find it here:" - @echo - @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-alpha-1" - @echo - @echo "Here is what I get when trying to evaluate your version of protoc:" - @echo - -$(PROTOC) --version - @echo - @echo -endif -ifneq ($(HAS_PLUGIN),true) - @echo " DEPENDENCY ERROR" - @echo - @echo "You don't have the grpc c++ protobuf plugin installed in your path." - @echo "Please install grpc. You can find it here:" - @echo - @echo " https://github.com/grpc/grpc" - @echo - @echo "Here is what I get when trying to detect if you have the plugin:" - @echo - -which $(GRPC_CPP_PLUGIN) - @echo - @echo -endif -ifneq ($(SYSTEM_OK),true) - @false -endif diff --git a/cpp/route_guide/helper.cc b/cpp/route_guide/helper.cc deleted file mode 100644 index c2415afdf7..0000000000 --- a/cpp/route_guide/helper.cc +++ /dev/null @@ -1,178 +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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include "route_guide.grpc.pb.h" - -namespace examples { - -std::string GetDbFileContent(int argc, char** argv) { - std::string db_path; - std::string arg_str("--db_path"); - if (argc > 1) { - std::string argv_1 = argv[1]; - size_t start_position = argv_1.find(arg_str); - if (start_position != std::string::npos) { - start_position += arg_str.size(); - if (argv_1[start_position] == ' ' || - argv_1[start_position] == '=') { - db_path = argv_1.substr(start_position + 1); - } - } - } else { - db_path = "route_guide_db.json"; - } - std::ifstream db_file(db_path); - if (!db_file.is_open()) { - std::cout << "Failed to open " << db_path << std::endl; - return ""; - } - std::stringstream db; - db << db_file.rdbuf(); - return db.str(); -} - -// A simple parser for the json db file. It requires the db file to have the -// exact form of [{"location": { "latitude": 123, "longitude": 456}, "name": -// "the name can be empty" }, { ... } ... The spaces will be stripped. -class Parser { - public: - explicit Parser(const std::string& db) : db_(db) { - // Remove all spaces. - db_.erase( - std::remove_if(db_.begin(), db_.end(), isspace), - db_.end()); - if (!Match("[")) { - SetFailedAndReturnFalse(); - } - } - - bool Finished() { - return current_ >= db_.size(); - } - - bool TryParseOne(Feature* feature) { - if (failed_ || Finished() || !Match("{")) { - return SetFailedAndReturnFalse(); - } - if (!Match(location_) || !Match("{") || !Match(latitude_)) { - return SetFailedAndReturnFalse(); - } - long temp = 0; - ReadLong(&temp); - feature->mutable_location()->set_latitude(temp); - if (!Match(",") || !Match(longitude_)) { - return SetFailedAndReturnFalse(); - } - ReadLong(&temp); - feature->mutable_location()->set_longitude(temp); - if (!Match("},") || !Match(name_) || !Match("\"")) { - return SetFailedAndReturnFalse(); - } - size_t name_start = current_; - while (current_ != db_.size() && db_[current_++] != '"') { - } - if (current_ == db_.size()) { - return SetFailedAndReturnFalse(); - } - feature->set_name(db_.substr(name_start, current_-name_start-1)); - if (!Match("},")) { - if (db_[current_ - 1] == ']' && current_ == db_.size()) { - return true; - } - return SetFailedAndReturnFalse(); - } - return true; - } - - private: - - bool SetFailedAndReturnFalse() { - failed_ = true; - return false; - } - - bool Match(const std::string& prefix) { - bool eq = db_.substr(current_, prefix.size()) == prefix; - current_ += prefix.size(); - return eq; - } - - void ReadLong(long* l) { - size_t start = current_; - while (current_ != db_.size() && db_[current_] != ',' && db_[current_] != '}') { - current_++; - } - // It will throw an exception if fails. - *l = std::stol(db_.substr(start, current_ - start)); - } - - bool failed_ = false; - std::string db_; - size_t current_ = 0; - const std::string location_ = "\"location\":"; - const std::string latitude_ = "\"latitude\":"; - const std::string longitude_ = "\"longitude\":"; - const std::string name_ = "\"name\":"; -}; - -void ParseDb(const std::string& db, std::vector* feature_list) { - feature_list->clear(); - std::string db_content(db); - db_content.erase( - std::remove_if(db_content.begin(), db_content.end(), isspace), - db_content.end()); - - Parser parser(db_content); - Feature feature; - while (!parser.Finished()) { - feature_list->push_back(Feature()); - if (!parser.TryParseOne(&feature_list->back())) { - std::cout << "Error parsing the db file"; - feature_list->clear(); - break; - } - } - std::cout << "DB parsed, loaded " << feature_list->size() - << " features." << std::endl; -} - - -} // namespace examples - diff --git a/cpp/route_guide/helper.h b/cpp/route_guide/helper.h deleted file mode 100644 index 65c93c1d34..0000000000 --- a/cpp/route_guide/helper.h +++ /dev/null @@ -1,50 +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. - * - */ - -#ifndef GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_ -#define GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_ - -#include -#include - -namespace examples { -class Feature; - -std::string GetDbFileContent(int argc, char** argv); - -void ParseDb(const std::string& db, std::vector* feature_list); - -} // namespace examples - -#endif // GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_ - diff --git a/cpp/route_guide/route_guide_client.cc b/cpp/route_guide/route_guide_client.cc deleted file mode 100644 index 814def27f3..0000000000 --- a/cpp/route_guide/route_guide_client.cc +++ /dev/null @@ -1,252 +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. - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include "helper.h" -#include "route_guide.grpc.pb.h" - -using grpc::Channel; -using grpc::ChannelArguments; -using grpc::ClientContext; -using grpc::ClientReader; -using grpc::ClientReaderWriter; -using grpc::ClientWriter; -using grpc::Status; -using examples::Point; -using examples::Feature; -using examples::Rectangle; -using examples::RouteSummary; -using examples::RouteNote; -using examples::RouteGuide; - -Point MakePoint(long latitude, long longitude) { - Point p; - p.set_latitude(latitude); - p.set_longitude(longitude); - return p; -} - -Feature MakeFeature(const std::string& name, - long latitude, long longitude) { - Feature f; - f.set_name(name); - f.mutable_location()->CopyFrom(MakePoint(latitude, longitude)); - return f; -} - -RouteNote MakeRouteNote(const std::string& message, - long latitude, long longitude) { - RouteNote n; - n.set_message(message); - n.mutable_location()->CopyFrom(MakePoint(latitude, longitude)); - return n; -} - -class RouteGuideClient { - public: - RouteGuideClient(std::shared_ptr channel, const std::string& db) - : stub_(RouteGuide::NewStub(channel)) { - examples::ParseDb(db, &feature_list_); - } - - void GetFeature() { - Point point; - Feature feature; - point = MakePoint(409146138, -746188906); - GetOneFeature(point, &feature); - point = MakePoint(0, 0); - GetOneFeature(point, &feature); - } - - void ListFeatures() { - examples::Rectangle rect; - Feature feature; - ClientContext context; - - rect.mutable_lo()->set_latitude(400000000); - rect.mutable_lo()->set_longitude(-750000000); - rect.mutable_hi()->set_latitude(420000000); - rect.mutable_hi()->set_longitude(-730000000); - std::cout << "Looking for features between 40, -75 and 42, -73" - << std::endl; - - std::unique_ptr > reader( - stub_->ListFeatures(&context, rect)); - while (reader->Read(&feature)) { - std::cout << "Found feature called " - << feature.name() << " at " - << feature.location().latitude()/kCoordFactor_ << ", " - << feature.location().longitude()/kCoordFactor_ << std::endl; - } - Status status = reader->Finish(); - if (status.ok()) { - std::cout << "ListFeatures rpc succeeded." << std::endl; - } else { - std::cout << "ListFeatures rpc failed." << std::endl; - } - } - - void RecordRoute() { - Point point; - RouteSummary stats; - ClientContext context; - const int kPoints = 10; - unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); - - std::default_random_engine generator(seed); - std::uniform_int_distribution feature_distribution( - 0, feature_list_.size() - 1); - std::uniform_int_distribution delay_distribution( - 500, 1500); - - std::unique_ptr > writer( - stub_->RecordRoute(&context, &stats)); - for (int i = 0; i < kPoints; i++) { - const Feature& f = feature_list_[feature_distribution(generator)]; - std::cout << "Visiting point " - << f.location().latitude()/kCoordFactor_ << ", " - << f.location().longitude()/kCoordFactor_ << std::endl; - if (!writer->Write(f.location())) { - // Broken stream. - break; - } - std::this_thread::sleep_for(std::chrono::milliseconds( - delay_distribution(generator))); - } - writer->WritesDone(); - Status status = writer->Finish(); - if (status.ok()) { - std::cout << "Finished trip with " << stats.point_count() << " points\n" - << "Passed " << stats.feature_count() << " features\n" - << "Travelled " << stats.distance() << " meters\n" - << "It took " << stats.elapsed_time() << " seconds" - << std::endl; - } else { - std::cout << "RecordRoute rpc failed." << std::endl; - } - } - - void RouteChat() { - ClientContext context; - - std::shared_ptr > stream( - stub_->RouteChat(&context)); - - std::thread writer([stream]() { - std::vector notes{ - MakeRouteNote("First message", 0, 0), - MakeRouteNote("Second message", 0, 1), - MakeRouteNote("Third message", 1, 0), - MakeRouteNote("Fourth message", 0, 0)}; - for (const RouteNote& note : notes) { - std::cout << "Sending message " << note.message() - << " at " << note.location().latitude() << ", " - << note.location().longitude() << std::endl; - stream->Write(note); - } - stream->WritesDone(); - }); - - RouteNote server_note; - while (stream->Read(&server_note)) { - std::cout << "Got message " << server_note.message() - << " at " << server_note.location().latitude() << ", " - << server_note.location().longitude() << std::endl; - } - writer.join(); - Status status = stream->Finish(); - if (!status.ok()) { - std::cout << "RouteChat rpc failed." << std::endl; - } - } - - private: - - bool GetOneFeature(const Point& point, Feature* feature) { - ClientContext context; - Status status = stub_->GetFeature(&context, point, feature); - if (!status.ok()) { - std::cout << "GetFeature rpc failed." << std::endl; - return false; - } - if (!feature->has_location()) { - std::cout << "Server returns incomplete feature." << std::endl; - return false; - } - if (feature->name().empty()) { - std::cout << "Found no feature at " - << feature->location().latitude()/kCoordFactor_ << ", " - << feature->location().longitude()/kCoordFactor_ << std::endl; - } else { - std::cout << "Found feature called " << feature->name() << " at " - << feature->location().latitude()/kCoordFactor_ << ", " - << feature->location().longitude()/kCoordFactor_ << std::endl; - } - return true; - } - - const float kCoordFactor_ = 10000000.0; - std::unique_ptr stub_; - std::vector feature_list_; -}; - -int main(int argc, char** argv) { - // Expect only arg: --db_path=path/to/route_guide_db.json. - std::string db = examples::GetDbFileContent(argc, argv); - RouteGuideClient guide( - grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), - ChannelArguments()), - db); - - std::cout << "-------------- GetFeature --------------" << std::endl; - guide.GetFeature(); - std::cout << "-------------- ListFeatures --------------" << std::endl; - guide.ListFeatures(); - std::cout << "-------------- RecordRoute --------------" << std::endl; - guide.RecordRoute(); - std::cout << "-------------- RouteChat --------------" << std::endl; - guide.RouteChat(); - - return 0; -} diff --git a/cpp/route_guide/route_guide_db.json b/cpp/route_guide/route_guide_db.json deleted file mode 100644 index 9d6a980ab7..0000000000 --- a/cpp/route_guide/route_guide_db.json +++ /dev/null @@ -1,601 +0,0 @@ -[{ - "location": { - "latitude": 407838351, - "longitude": -746143763 - }, - "name": "Patriots Path, Mendham, NJ 07945, USA" -}, { - "location": { - "latitude": 408122808, - "longitude": -743999179 - }, - "name": "101 New Jersey 10, Whippany, NJ 07981, USA" -}, { - "location": { - "latitude": 413628156, - "longitude": -749015468 - }, - "name": "U.S. 6, Shohola, PA 18458, USA" -}, { - "location": { - "latitude": 419999544, - "longitude": -740371136 - }, - "name": "5 Conners Road, Kingston, NY 12401, USA" -}, { - "location": { - "latitude": 414008389, - "longitude": -743951297 - }, - "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" -}, { - "location": { - "latitude": 419611318, - "longitude": -746524769 - }, - "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" -}, { - "location": { - "latitude": 406109563, - "longitude": -742186778 - }, - "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" -}, { - "location": { - "latitude": 416802456, - "longitude": -742370183 - }, - "name": "352 South Mountain Road, Wallkill, NY 12589, USA" -}, { - "location": { - "latitude": 412950425, - "longitude": -741077389 - }, - "name": "Bailey Turn Road, Harriman, NY 10926, USA" -}, { - "location": { - "latitude": 412144655, - "longitude": -743949739 - }, - "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" -}, { - "location": { - "latitude": 415736605, - "longitude": -742847522 - }, - "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" -}, { - "location": { - "latitude": 413843930, - "longitude": -740501726 - }, - "name": "162 Merrill Road, Highland Mills, NY 10930, USA" -}, { - "location": { - "latitude": 410873075, - "longitude": -744459023 - }, - "name": "Clinton Road, West Milford, NJ 07480, USA" -}, { - "location": { - "latitude": 412346009, - "longitude": -744026814 - }, - "name": "16 Old Brook Lane, Warwick, NY 10990, USA" -}, { - "location": { - "latitude": 402948455, - "longitude": -747903913 - }, - "name": "3 Drake Lane, Pennington, NJ 08534, USA" -}, { - "location": { - "latitude": 406337092, - "longitude": -740122226 - }, - "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" -}, { - "location": { - "latitude": 406421967, - "longitude": -747727624 - }, - "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" -}, { - "location": { - "latitude": 416318082, - "longitude": -749677716 - }, - "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" -}, { - "location": { - "latitude": 415301720, - "longitude": -748416257 - }, - "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" -}, { - "location": { - "latitude": 402647019, - "longitude": -747071791 - }, - "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" -}, { - "location": { - "latitude": 412567807, - "longitude": -741058078 - }, - "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" -}, { - "location": { - "latitude": 416855156, - "longitude": -744420597 - }, - "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" -}, { - "location": { - "latitude": 404663628, - "longitude": -744820157 - }, - "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" -}, { - "location": { - "latitude": 407113723, - "longitude": -749746483 - }, - "name": "" -}, { - "location": { - "latitude": 402133926, - "longitude": -743613249 - }, - "name": "" -}, { - "location": { - "latitude": 400273442, - "longitude": -741220915 - }, - "name": "" -}, { - "location": { - "latitude": 411236786, - "longitude": -744070769 - }, - "name": "" -}, { - "location": { - "latitude": 411633782, - "longitude": -746784970 - }, - "name": "211-225 Plains Road, Augusta, NJ 07822, USA" -}, { - "location": { - "latitude": 415830701, - "longitude": -742952812 - }, - "name": "" -}, { - "location": { - "latitude": 413447164, - "longitude": -748712898 - }, - "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" -}, { - "location": { - "latitude": 405047245, - "longitude": -749800722 - }, - "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" -}, { - "location": { - "latitude": 418858923, - "longitude": -746156790 - }, - "name": "" -}, { - "location": { - "latitude": 417951888, - "longitude": -748484944 - }, - "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" -}, { - "location": { - "latitude": 407033786, - "longitude": -743977337 - }, - "name": "26 East 3rd Street, New Providence, NJ 07974, USA" -}, { - "location": { - "latitude": 417548014, - "longitude": -740075041 - }, - "name": "" -}, { - "location": { - "latitude": 410395868, - "longitude": -744972325 - }, - "name": "" -}, { - "location": { - "latitude": 404615353, - "longitude": -745129803 - }, - "name": "" -}, { - "location": { - "latitude": 406589790, - "longitude": -743560121 - }, - "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" -}, { - "location": { - "latitude": 414653148, - "longitude": -740477477 - }, - "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" -}, { - "location": { - "latitude": 405957808, - "longitude": -743255336 - }, - "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" -}, { - "location": { - "latitude": 411733589, - "longitude": -741648093 - }, - "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" -}, { - "location": { - "latitude": 412676291, - "longitude": -742606606 - }, - "name": "1270 Lakes Road, Monroe, NY 10950, USA" -}, { - "location": { - "latitude": 409224445, - "longitude": -748286738 - }, - "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" -}, { - "location": { - "latitude": 406523420, - "longitude": -742135517 - }, - "name": "652 Garden Street, Elizabeth, NJ 07202, USA" -}, { - "location": { - "latitude": 401827388, - "longitude": -740294537 - }, - "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" -}, { - "location": { - "latitude": 410564152, - "longitude": -743685054 - }, - "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" -}, { - "location": { - "latitude": 408472324, - "longitude": -740726046 - }, - "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" -}, { - "location": { - "latitude": 412452168, - "longitude": -740214052 - }, - "name": "5 White Oak Lane, Stony Point, NY 10980, USA" -}, { - "location": { - "latitude": 409146138, - "longitude": -746188906 - }, - "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" -}, { - "location": { - "latitude": 404701380, - "longitude": -744781745 - }, - "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" -}, { - "location": { - "latitude": 409642566, - "longitude": -746017679 - }, - "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" -}, { - "location": { - "latitude": 408031728, - "longitude": -748645385 - }, - "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" -}, { - "location": { - "latitude": 413700272, - "longitude": -742135189 - }, - "name": "367 Prospect Road, Chester, NY 10918, USA" -}, { - "location": { - "latitude": 404310607, - "longitude": -740282632 - }, - "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" -}, { - "location": { - "latitude": 409319800, - "longitude": -746201391 - }, - "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" -}, { - "location": { - "latitude": 406685311, - "longitude": -742108603 - }, - "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" -}, { - "location": { - "latitude": 419018117, - "longitude": -749142781 - }, - "name": "43 Dreher Road, Roscoe, NY 12776, USA" -}, { - "location": { - "latitude": 412856162, - "longitude": -745148837 - }, - "name": "Swan Street, Pine Island, NY 10969, USA" -}, { - "location": { - "latitude": 416560744, - "longitude": -746721964 - }, - "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" -}, { - "location": { - "latitude": 405314270, - "longitude": -749836354 - }, - "name": "" -}, { - "location": { - "latitude": 414219548, - "longitude": -743327440 - }, - "name": "" -}, { - "location": { - "latitude": 415534177, - "longitude": -742900616 - }, - "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" -}, { - "location": { - "latitude": 406898530, - "longitude": -749127080 - }, - "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" -}, { - "location": { - "latitude": 407586880, - "longitude": -741670168 - }, - "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" -}, { - "location": { - "latitude": 400106455, - "longitude": -742870190 - }, - "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" -}, { - "location": { - "latitude": 400066188, - "longitude": -746793294 - }, - "name": "" -}, { - "location": { - "latitude": 418803880, - "longitude": -744102673 - }, - "name": "40 Mountain Road, Napanoch, NY 12458, USA" -}, { - "location": { - "latitude": 414204288, - "longitude": -747895140 - }, - "name": "" -}, { - "location": { - "latitude": 414777405, - "longitude": -740615601 - }, - "name": "" -}, { - "location": { - "latitude": 415464475, - "longitude": -747175374 - }, - "name": "48 North Road, Forestburgh, NY 12777, USA" -}, { - "location": { - "latitude": 404062378, - "longitude": -746376177 - }, - "name": "" -}, { - "location": { - "latitude": 405688272, - "longitude": -749285130 - }, - "name": "" -}, { - "location": { - "latitude": 400342070, - "longitude": -748788996 - }, - "name": "" -}, { - "location": { - "latitude": 401809022, - "longitude": -744157964 - }, - "name": "" -}, { - "location": { - "latitude": 404226644, - "longitude": -740517141 - }, - "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" -}, { - "location": { - "latitude": 410322033, - "longitude": -747871659 - }, - "name": "" -}, { - "location": { - "latitude": 407100674, - "longitude": -747742727 - }, - "name": "" -}, { - "location": { - "latitude": 418811433, - "longitude": -741718005 - }, - "name": "213 Bush Road, Stone Ridge, NY 12484, USA" -}, { - "location": { - "latitude": 415034302, - "longitude": -743850945 - }, - "name": "" -}, { - "location": { - "latitude": 411349992, - "longitude": -743694161 - }, - "name": "" -}, { - "location": { - "latitude": 404839914, - "longitude": -744759616 - }, - "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" -}, { - "location": { - "latitude": 414638017, - "longitude": -745957854 - }, - "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" -}, { - "location": { - "latitude": 412127800, - "longitude": -740173578 - }, - "name": "" -}, { - "location": { - "latitude": 401263460, - "longitude": -747964303 - }, - "name": "" -}, { - "location": { - "latitude": 412843391, - "longitude": -749086026 - }, - "name": "" -}, { - "location": { - "latitude": 418512773, - "longitude": -743067823 - }, - "name": "" -}, { - "location": { - "latitude": 404318328, - "longitude": -740835638 - }, - "name": "42-102 Main Street, Belford, NJ 07718, USA" -}, { - "location": { - "latitude": 419020746, - "longitude": -741172328 - }, - "name": "" -}, { - "location": { - "latitude": 404080723, - "longitude": -746119569 - }, - "name": "" -}, { - "location": { - "latitude": 401012643, - "longitude": -744035134 - }, - "name": "" -}, { - "location": { - "latitude": 404306372, - "longitude": -741079661 - }, - "name": "" -}, { - "location": { - "latitude": 403966326, - "longitude": -748519297 - }, - "name": "" -}, { - "location": { - "latitude": 405002031, - "longitude": -748407866 - }, - "name": "" -}, { - "location": { - "latitude": 409532885, - "longitude": -742200683 - }, - "name": "" -}, { - "location": { - "latitude": 416851321, - "longitude": -742674555 - }, - "name": "" -}, { - "location": { - "latitude": 406411633, - "longitude": -741722051 - }, - "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" -}, { - "location": { - "latitude": 413069058, - "longitude": -744597778 - }, - "name": "261 Van Sickle Road, Goshen, NY 10924, USA" -}, { - "location": { - "latitude": 418465462, - "longitude": -746859398 - }, - "name": "" -}, { - "location": { - "latitude": 411733222, - "longitude": -744228360 - }, - "name": "" -}, { - "location": { - "latitude": 410248224, - "longitude": -747127767 - }, - "name": "3 Hasta Way, Newton, NJ 07860, USA" -}] diff --git a/cpp/route_guide/route_guide_server.cc b/cpp/route_guide/route_guide_server.cc deleted file mode 100644 index b37539299a..0000000000 --- a/cpp/route_guide/route_guide_server.cc +++ /dev/null @@ -1,202 +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. - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include "helper.h" -#include "route_guide.grpc.pb.h" - -using grpc::Server; -using grpc::ServerBuilder; -using grpc::ServerContext; -using grpc::ServerReader; -using grpc::ServerReaderWriter; -using grpc::ServerWriter; -using grpc::Status; -using examples::Point; -using examples::Feature; -using examples::Rectangle; -using examples::RouteSummary; -using examples::RouteNote; -using examples::RouteGuide; -using std::chrono::system_clock; - - -float ConvertToRadians(float num) { - return num * 3.1415926 /180; -} - -float GetDistance(const Point& start, const Point& end) { - const float kCoordFactor = 10000000.0; - float lat_1 = start.latitude() / kCoordFactor; - float lat_2 = end.latitude() / kCoordFactor; - float lon_1 = start.longitude() / kCoordFactor; - float lon_2 = end.longitude() / kCoordFactor; - float lat_rad_1 = ConvertToRadians(lat_1); - float lat_rad_2 = ConvertToRadians(lat_2); - float delta_lat_rad = ConvertToRadians(lat_2-lat_1); - float delta_lon_rad = ConvertToRadians(lon_2-lon_1); - - float a = pow(sin(delta_lat_rad/2), 2) + cos(lat_rad_1) * cos(lat_rad_2) * - pow(sin(delta_lon_rad/2), 2); - float c = 2 * atan2(sqrt(a), sqrt(1-a)); - int R = 6371000; // metres - - return R * c; -} - -std::string GetFeatureName(const Point& point, - const std::vector& feature_list) { - for (const Feature& f : feature_list) { - if (f.location().latitude() == point.latitude() && - f.location().longitude() == point.longitude()) { - return f.name(); - } - } - return ""; -} - -class RouteGuideImpl final : public RouteGuide::Service { - public: - explicit RouteGuideImpl(const std::string& db) { - examples::ParseDb(db, &feature_list_); - } - - Status GetFeature(ServerContext* context, const Point* point, - Feature* feature) override { - feature->set_name(GetFeatureName(*point, feature_list_)); - feature->mutable_location()->CopyFrom(*point); - return Status::OK; - } - - Status ListFeatures(ServerContext* context, - const examples::Rectangle* rectangle, - ServerWriter* writer) override { - auto lo = rectangle->lo(); - auto hi = rectangle->hi(); - long left = (std::min)(lo.longitude(), hi.longitude()); - long right = (std::max)(lo.longitude(), hi.longitude()); - long top = (std::max)(lo.latitude(), hi.latitude()); - long bottom = (std::min)(lo.latitude(), hi.latitude()); - for (const Feature& f : feature_list_) { - if (f.location().longitude() >= left && - f.location().longitude() <= right && - f.location().latitude() >= bottom && - f.location().latitude() <= top) { - writer->Write(f); - } - } - return Status::OK; - } - - Status RecordRoute(ServerContext* context, ServerReader* reader, - RouteSummary* summary) override { - Point point; - int point_count = 0; - int feature_count = 0; - float distance = 0.0; - Point previous; - - system_clock::time_point start_time = system_clock::now(); - while (reader->Read(&point)) { - point_count++; - if (!GetFeatureName(point, feature_list_).empty()) { - feature_count++; - } - if (point_count != 1) { - distance += GetDistance(previous, point); - } - previous = point; - } - system_clock::time_point end_time = system_clock::now(); - summary->set_point_count(point_count); - summary->set_feature_count(feature_count); - summary->set_distance(static_cast(distance)); - auto secs = std::chrono::duration_cast( - end_time - start_time); - summary->set_elapsed_time(secs.count()); - - return Status::OK; - } - - Status RouteChat(ServerContext* context, - ServerReaderWriter* stream) override { - std::vector received_notes; - RouteNote note; - while (stream->Read(¬e)) { - for (const RouteNote& n : received_notes) { - if (n.location().latitude() == note.location().latitude() && - n.location().longitude() == note.location().longitude()) { - stream->Write(n); - } - } - received_notes.push_back(note); - } - - return Status::OK; - } - - private: - - std::vector feature_list_; -}; - -void RunServer(const std::string& db_path) { - std::string server_address("0.0.0.0:50051"); - RouteGuideImpl service(db_path); - - ServerBuilder builder; - builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); - builder.RegisterService(&service); - std::unique_ptr server(builder.BuildAndStart()); - std::cout << "Server listening on " << server_address << std::endl; - server->Wait(); -} - -int main(int argc, char** argv) { - // Expect only arg: --db_path=path/to/route_guide_db.json. - std::string db = examples::GetDbFileContent(argc, argv); - RunServer(db); - - return 0; -} diff --git a/csharp/.gitignore b/csharp/.gitignore deleted file mode 100644 index 585000ea2d..0000000000 --- a/csharp/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -bin/ -obj/ -packages/ -*.suo -*.userprefs diff --git a/csharp/.nuget/packages.config b/csharp/.nuget/packages.config deleted file mode 100644 index b14373069f..0000000000 --- a/csharp/.nuget/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/csharp/Greeter.sln b/csharp/Greeter.sln deleted file mode 100644 index 9430e94de9..0000000000 --- a/csharp/Greeter.sln +++ /dev/null @@ -1,42 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.31101.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Greeter", "Greeter\Greeter.csproj", "{724DFC8C-4B57-4C3F-811C-0463BE2A2829}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterServer", "GreeterServer\GreeterServer.csproj", "{A7706C84-92D2-4B7A-B779-76B64D2950EC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterClient", "GreeterClient\GreeterClient.csproj", "{ACCF4597-3748-4117-8633-1CB767F8CCC3}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{FF1EBE95-F20D-4C27-8A61-D0125F3C8152}" - ProjectSection(SolutionItems) = preProject - .nuget\packages.config = .nuget\packages.config - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Debug|Any CPU.Build.0 = Debug|Any CPU - {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Release|Any CPU.ActiveCfg = Release|Any CPU - {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Release|Any CPU.Build.0 = Release|Any CPU - {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Release|Any CPU.Build.0 = Release|Any CPU - {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution - StartupItem = Greeter\Greeter.csproj - EndGlobalSection -EndGlobal diff --git a/csharp/Greeter/.gitignore b/csharp/Greeter/.gitignore deleted file mode 100644 index 1746e3269e..0000000000 --- a/csharp/Greeter/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -bin -obj diff --git a/csharp/Greeter/Greeter.csproj b/csharp/Greeter/Greeter.csproj deleted file mode 100644 index b8f965dbd2..0000000000 --- a/csharp/Greeter/Greeter.csproj +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {724DFC8C-4B57-4C3F-811C-0463BE2A2829} - Library - Greeter - Greeter - v4.5 - 927432a0 - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - false - - - full - true - bin\Release - prompt - 4 - false - - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - - - False - ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll - - - - False - ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - - - ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll - - - - - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - \ No newline at end of file diff --git a/csharp/Greeter/Helloworld.cs b/csharp/Greeter/Helloworld.cs deleted file mode 100644 index 923a4271e9..0000000000 --- a/csharp/Greeter/Helloworld.cs +++ /dev/null @@ -1,617 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: helloworld.proto -#pragma warning disable 1591, 0612, 3021 -#region Designer generated code - -using pb = global::Google.ProtocolBuffers; -using pbc = global::Google.ProtocolBuffers.Collections; -using pbd = global::Google.ProtocolBuffers.Descriptors; -using scg = global::System.Collections.Generic; -namespace helloworld { - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public static partial class Helloworld { - - #region Extension registration - public static void RegisterAllExtensions(pb::ExtensionRegistry registry) { - } - #endregion - #region Static variables - internal static pbd::MessageDescriptor internal__static_helloworld_HelloRequest__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_helloworld_HelloRequest__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_helloworld_HelloReply__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_helloworld_HelloReply__FieldAccessorTable; - #endregion - #region Descriptor - public static pbd::FileDescriptor Descriptor { - get { return descriptor; } - } - private static pbd::FileDescriptor descriptor; - - static Helloworld() { - byte[] descriptorData = global::System.Convert.FromBase64String( - string.Concat( - "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz", - "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo", - "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl", - "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEISChBpby5ncnBjLmV4", - "YW1wbGVz")); - pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) { - descriptor = root; - internal__static_helloworld_HelloRequest__Descriptor = Descriptor.MessageTypes[0]; - internal__static_helloworld_HelloRequest__FieldAccessorTable = - new pb::FieldAccess.FieldAccessorTable(internal__static_helloworld_HelloRequest__Descriptor, - new string[] { "Name", }); - internal__static_helloworld_HelloReply__Descriptor = Descriptor.MessageTypes[1]; - internal__static_helloworld_HelloReply__FieldAccessorTable = - new pb::FieldAccess.FieldAccessorTable(internal__static_helloworld_HelloReply__Descriptor, - new string[] { "Message", }); - pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance(); - RegisterAllExtensions(registry); - return registry; - }; - pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData, - new pbd::FileDescriptor[] { - }, assigner); - } - #endregion - - } - #region Messages - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class HelloRequest : pb::GeneratedMessage { - private HelloRequest() { } - private static readonly HelloRequest defaultInstance = new HelloRequest().MakeReadOnly(); - private static readonly string[] _helloRequestFieldNames = new string[] { "name" }; - private static readonly uint[] _helloRequestFieldTags = new uint[] { 10 }; - public static HelloRequest DefaultInstance { - get { return defaultInstance; } - } - - public override HelloRequest DefaultInstanceForType { - get { return DefaultInstance; } - } - - protected override HelloRequest ThisMessage { - get { return this; } - } - - public static pbd::MessageDescriptor Descriptor { - get { return global::helloworld.Helloworld.internal__static_helloworld_HelloRequest__Descriptor; } - } - - protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { - get { return global::helloworld.Helloworld.internal__static_helloworld_HelloRequest__FieldAccessorTable; } - } - - public const int NameFieldNumber = 1; - private bool hasName; - private string name_ = ""; - public bool HasName { - get { return hasName; } - } - public string Name { - get { return name_; } - } - - public override bool IsInitialized { - get { - return true; - } - } - - public override void WriteTo(pb::ICodedOutputStream output) { - CalcSerializedSize(); - string[] field_names = _helloRequestFieldNames; - if (hasName) { - output.WriteString(1, field_names[0], Name); - } - UnknownFields.WriteTo(output); - } - - private int memoizedSerializedSize = -1; - public override int SerializedSize { - get { - int size = memoizedSerializedSize; - if (size != -1) return size; - return CalcSerializedSize(); - } - } - - private int CalcSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (hasName) { - size += pb::CodedOutputStream.ComputeStringSize(1, Name); - } - size += UnknownFields.SerializedSize; - memoizedSerializedSize = size; - return size; - } - public static HelloRequest ParseFrom(pb::ByteString data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static HelloRequest ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static HelloRequest ParseFrom(byte[] data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static HelloRequest ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static HelloRequest ParseFrom(global::System.IO.Stream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static HelloRequest ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - public static HelloRequest ParseDelimitedFrom(global::System.IO.Stream input) { - return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); - } - public static HelloRequest ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); - } - public static HelloRequest ParseFrom(pb::ICodedInputStream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static HelloRequest ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - private HelloRequest MakeReadOnly() { - return this; - } - - public static Builder CreateBuilder() { return new Builder(); } - public override Builder ToBuilder() { return CreateBuilder(this); } - public override Builder CreateBuilderForType() { return new Builder(); } - public static Builder CreateBuilder(HelloRequest prototype) { - return new Builder(prototype); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Builder : pb::GeneratedBuilder { - protected override Builder ThisBuilder { - get { return this; } - } - public Builder() { - result = DefaultInstance; - resultIsReadOnly = true; - } - internal Builder(HelloRequest cloneFrom) { - result = cloneFrom; - resultIsReadOnly = true; - } - - private bool resultIsReadOnly; - private HelloRequest result; - - private HelloRequest PrepareBuilder() { - if (resultIsReadOnly) { - HelloRequest original = result; - result = new HelloRequest(); - resultIsReadOnly = false; - MergeFrom(original); - } - return result; - } - - public override bool IsInitialized { - get { return result.IsInitialized; } - } - - protected override HelloRequest MessageBeingBuilt { - get { return PrepareBuilder(); } - } - - public override Builder Clear() { - result = DefaultInstance; - resultIsReadOnly = true; - return this; - } - - public override Builder Clone() { - if (resultIsReadOnly) { - return new Builder(result); - } else { - return new Builder().MergeFrom(result); - } - } - - public override pbd::MessageDescriptor DescriptorForType { - get { return global::helloworld.HelloRequest.Descriptor; } - } - - public override HelloRequest DefaultInstanceForType { - get { return global::helloworld.HelloRequest.DefaultInstance; } - } - - public override HelloRequest BuildPartial() { - if (resultIsReadOnly) { - return result; - } - resultIsReadOnly = true; - return result.MakeReadOnly(); - } - - public override Builder MergeFrom(pb::IMessage other) { - if (other is HelloRequest) { - return MergeFrom((HelloRequest) other); - } else { - base.MergeFrom(other); - return this; - } - } - - public override Builder MergeFrom(HelloRequest other) { - if (other == global::helloworld.HelloRequest.DefaultInstance) return this; - PrepareBuilder(); - if (other.HasName) { - Name = other.Name; - } - this.MergeUnknownFields(other.UnknownFields); - return this; - } - - public override Builder MergeFrom(pb::ICodedInputStream input) { - return MergeFrom(input, pb::ExtensionRegistry.Empty); - } - - public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - PrepareBuilder(); - pb::UnknownFieldSet.Builder unknownFields = null; - uint tag; - string field_name; - while (input.ReadTag(out tag, out field_name)) { - if(tag == 0 && field_name != null) { - int field_ordinal = global::System.Array.BinarySearch(_helloRequestFieldNames, field_name, global::System.StringComparer.Ordinal); - if(field_ordinal >= 0) - tag = _helloRequestFieldTags[field_ordinal]; - else { - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - continue; - } - } - switch (tag) { - case 0: { - throw pb::InvalidProtocolBufferException.InvalidTag(); - } - default: { - if (pb::WireFormat.IsEndGroupTag(tag)) { - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - break; - } - case 10: { - result.hasName = input.ReadString(ref result.name_); - break; - } - } - } - - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - - - public bool HasName { - get { return result.hasName; } - } - public string Name { - get { return result.Name; } - set { SetName(value); } - } - public Builder SetName(string value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasName = true; - result.name_ = value; - return this; - } - public Builder ClearName() { - PrepareBuilder(); - result.hasName = false; - result.name_ = ""; - return this; - } - } - static HelloRequest() { - object.ReferenceEquals(global::helloworld.Helloworld.Descriptor, null); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class HelloReply : pb::GeneratedMessage { - private HelloReply() { } - private static readonly HelloReply defaultInstance = new HelloReply().MakeReadOnly(); - private static readonly string[] _helloReplyFieldNames = new string[] { "message" }; - private static readonly uint[] _helloReplyFieldTags = new uint[] { 10 }; - public static HelloReply DefaultInstance { - get { return defaultInstance; } - } - - public override HelloReply DefaultInstanceForType { - get { return DefaultInstance; } - } - - protected override HelloReply ThisMessage { - get { return this; } - } - - public static pbd::MessageDescriptor Descriptor { - get { return global::helloworld.Helloworld.internal__static_helloworld_HelloReply__Descriptor; } - } - - protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { - get { return global::helloworld.Helloworld.internal__static_helloworld_HelloReply__FieldAccessorTable; } - } - - public const int MessageFieldNumber = 1; - private bool hasMessage; - private string message_ = ""; - public bool HasMessage { - get { return hasMessage; } - } - public string Message { - get { return message_; } - } - - public override bool IsInitialized { - get { - return true; - } - } - - public override void WriteTo(pb::ICodedOutputStream output) { - CalcSerializedSize(); - string[] field_names = _helloReplyFieldNames; - if (hasMessage) { - output.WriteString(1, field_names[0], Message); - } - UnknownFields.WriteTo(output); - } - - private int memoizedSerializedSize = -1; - public override int SerializedSize { - get { - int size = memoizedSerializedSize; - if (size != -1) return size; - return CalcSerializedSize(); - } - } - - private int CalcSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (hasMessage) { - size += pb::CodedOutputStream.ComputeStringSize(1, Message); - } - size += UnknownFields.SerializedSize; - memoizedSerializedSize = size; - return size; - } - public static HelloReply ParseFrom(pb::ByteString data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static HelloReply ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static HelloReply ParseFrom(byte[] data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static HelloReply ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static HelloReply ParseFrom(global::System.IO.Stream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static HelloReply ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - public static HelloReply ParseDelimitedFrom(global::System.IO.Stream input) { - return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); - } - public static HelloReply ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); - } - public static HelloReply ParseFrom(pb::ICodedInputStream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static HelloReply ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - private HelloReply MakeReadOnly() { - return this; - } - - public static Builder CreateBuilder() { return new Builder(); } - public override Builder ToBuilder() { return CreateBuilder(this); } - public override Builder CreateBuilderForType() { return new Builder(); } - public static Builder CreateBuilder(HelloReply prototype) { - return new Builder(prototype); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Builder : pb::GeneratedBuilder { - protected override Builder ThisBuilder { - get { return this; } - } - public Builder() { - result = DefaultInstance; - resultIsReadOnly = true; - } - internal Builder(HelloReply cloneFrom) { - result = cloneFrom; - resultIsReadOnly = true; - } - - private bool resultIsReadOnly; - private HelloReply result; - - private HelloReply PrepareBuilder() { - if (resultIsReadOnly) { - HelloReply original = result; - result = new HelloReply(); - resultIsReadOnly = false; - MergeFrom(original); - } - return result; - } - - public override bool IsInitialized { - get { return result.IsInitialized; } - } - - protected override HelloReply MessageBeingBuilt { - get { return PrepareBuilder(); } - } - - public override Builder Clear() { - result = DefaultInstance; - resultIsReadOnly = true; - return this; - } - - public override Builder Clone() { - if (resultIsReadOnly) { - return new Builder(result); - } else { - return new Builder().MergeFrom(result); - } - } - - public override pbd::MessageDescriptor DescriptorForType { - get { return global::helloworld.HelloReply.Descriptor; } - } - - public override HelloReply DefaultInstanceForType { - get { return global::helloworld.HelloReply.DefaultInstance; } - } - - public override HelloReply BuildPartial() { - if (resultIsReadOnly) { - return result; - } - resultIsReadOnly = true; - return result.MakeReadOnly(); - } - - public override Builder MergeFrom(pb::IMessage other) { - if (other is HelloReply) { - return MergeFrom((HelloReply) other); - } else { - base.MergeFrom(other); - return this; - } - } - - public override Builder MergeFrom(HelloReply other) { - if (other == global::helloworld.HelloReply.DefaultInstance) return this; - PrepareBuilder(); - if (other.HasMessage) { - Message = other.Message; - } - this.MergeUnknownFields(other.UnknownFields); - return this; - } - - public override Builder MergeFrom(pb::ICodedInputStream input) { - return MergeFrom(input, pb::ExtensionRegistry.Empty); - } - - public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - PrepareBuilder(); - pb::UnknownFieldSet.Builder unknownFields = null; - uint tag; - string field_name; - while (input.ReadTag(out tag, out field_name)) { - if(tag == 0 && field_name != null) { - int field_ordinal = global::System.Array.BinarySearch(_helloReplyFieldNames, field_name, global::System.StringComparer.Ordinal); - if(field_ordinal >= 0) - tag = _helloReplyFieldTags[field_ordinal]; - else { - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - continue; - } - } - switch (tag) { - case 0: { - throw pb::InvalidProtocolBufferException.InvalidTag(); - } - default: { - if (pb::WireFormat.IsEndGroupTag(tag)) { - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - break; - } - case 10: { - result.hasMessage = input.ReadString(ref result.message_); - break; - } - } - } - - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - - - public bool HasMessage { - get { return result.hasMessage; } - } - public string Message { - get { return result.Message; } - set { SetMessage(value); } - } - public Builder SetMessage(string value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasMessage = true; - result.message_ = value; - return this; - } - public Builder ClearMessage() { - PrepareBuilder(); - result.hasMessage = false; - result.message_ = ""; - return this; - } - } - static HelloReply() { - object.ReferenceEquals(global::helloworld.Helloworld.Descriptor, null); - } - } - - #endregion - -} - -#endregion Designer generated code diff --git a/csharp/Greeter/HelloworldGrpc.cs b/csharp/Greeter/HelloworldGrpc.cs deleted file mode 100644 index 1ca9d2899b..0000000000 --- a/csharp/Greeter/HelloworldGrpc.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: helloworld.proto -#region Designer generated code - -using System; -using System.Threading; -using System.Threading.Tasks; -using Grpc.Core; - -namespace helloworld { - public static class Greeter - { - static readonly string __ServiceName = "helloworld.Greeter"; - - static readonly Marshaller __Marshaller_HelloRequest = Marshallers.Create((arg) => arg.ToByteArray(), global::helloworld.HelloRequest.ParseFrom); - static readonly Marshaller __Marshaller_HelloReply = Marshallers.Create((arg) => arg.ToByteArray(), global::helloworld.HelloReply.ParseFrom); - - static readonly Method __Method_SayHello = new Method( - MethodType.Unary, - "SayHello", - __Marshaller_HelloRequest, - __Marshaller_HelloReply); - - // client-side stub interface - public interface IGreeterClient - { - global::helloworld.HelloReply SayHello(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)); - Task SayHelloAsync(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)); - } - - // server-side interface - public interface IGreeter - { - Task SayHello(ServerCallContext context, global::helloworld.HelloRequest request); - } - - // client stub - public class GreeterClient : AbstractStub, IGreeterClient - { - public GreeterClient(Channel channel) : this(channel, StubConfiguration.Default) - { - } - public GreeterClient(Channel channel, StubConfiguration config) : base(channel, config) - { - } - public global::helloworld.HelloReply SayHello(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)) - { - var call = CreateCall(__ServiceName, __Method_SayHello); - return Calls.BlockingUnaryCall(call, request, token); - } - public Task SayHelloAsync(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)) - { - var call = CreateCall(__ServiceName, __Method_SayHello); - return Calls.AsyncUnaryCall(call, request, token); - } - } - - // creates service definition that can be registered with a server - public static ServerServiceDefinition BindService(IGreeter serviceImpl) - { - return ServerServiceDefinition.CreateBuilder(__ServiceName) - .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build(); - } - - // creates a new client stub - public static IGreeterClient NewStub(Channel channel) - { - return new GreeterClient(channel); - } - - // creates a new client stub - public static IGreeterClient NewStub(Channel channel, StubConfiguration config) - { - return new GreeterClient(channel, config); - } - } -} -#endregion diff --git a/csharp/Greeter/Properties/AssemblyInfo.cs b/csharp/Greeter/Properties/AssemblyInfo.cs deleted file mode 100644 index b9d0dc264d..0000000000 --- a/csharp/Greeter/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. -[assembly: AssemblyTitle("Greeter")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("jtattermusch")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. -[assembly: AssemblyVersion("1.0.*")] -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/csharp/Greeter/packages.config b/csharp/Greeter/packages.config deleted file mode 100644 index 5922553bc3..0000000000 --- a/csharp/Greeter/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/csharp/Greeter/protos/helloworld.proto b/csharp/Greeter/protos/helloworld.proto deleted file mode 100644 index e02ebd94e7..0000000000 --- a/csharp/Greeter/protos/helloworld.proto +++ /dev/null @@ -1,52 +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. - -// TODO(jtattermusch): as of now, C# protobufs don't officially support -// proto3. -syntax = "proto2"; - -option java_package = "io.grpc.examples"; - -package helloworld; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - optional string name = 1; -} - -// The response message containing the greetings -message HelloReply { - optional string message = 1; -} diff --git a/csharp/GreeterClient/.gitignore b/csharp/GreeterClient/.gitignore deleted file mode 100644 index 1746e3269e..0000000000 --- a/csharp/GreeterClient/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -bin -obj diff --git a/csharp/GreeterClient/GreeterClient.csproj b/csharp/GreeterClient/GreeterClient.csproj deleted file mode 100644 index 59b768af01..0000000000 --- a/csharp/GreeterClient/GreeterClient.csproj +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {ACCF4597-3748-4117-8633-1CB767F8CCC3} - Exe - GreeterClient - GreeterClient - v4.5 - 985ca8be - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - - - full - true - bin\Release - prompt - 4 - true - - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - - - False - ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll - - - - False - ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - - - ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll - - - - - - - - - - {724DFC8C-4B57-4C3F-811C-0463BE2A2829} - Greeter - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - \ No newline at end of file diff --git a/csharp/GreeterClient/Program.cs b/csharp/GreeterClient/Program.cs deleted file mode 100644 index 61c29762b1..0000000000 --- a/csharp/GreeterClient/Program.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using Grpc.Core; -using helloworld; - -namespace GreeterClient -{ - class ClientMainClass - { - public static void Main(string[] args) - { - GrpcEnvironment.Initialize(); - - using (Channel channel = new Channel("127.0.0.1:50051")) - { - var client = Greeter.NewStub(channel); - String user = "you"; - - var reply = client.SayHello(new HelloRequest.Builder { Name = user }.Build()); - Console.WriteLine("Greeting: " + reply.Message); - } - - GrpcEnvironment.Shutdown(); - } - } -} diff --git a/csharp/GreeterClient/Properties/AssemblyInfo.cs b/csharp/GreeterClient/Properties/AssemblyInfo.cs deleted file mode 100644 index 1422e952d8..0000000000 --- a/csharp/GreeterClient/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. -[assembly: AssemblyTitle("GreeterClient")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("jtattermusch")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. -[assembly: AssemblyVersion("1.0.*")] -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/csharp/GreeterClient/packages.config b/csharp/GreeterClient/packages.config deleted file mode 100644 index 5922553bc3..0000000000 --- a/csharp/GreeterClient/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/csharp/GreeterServer/.gitignore b/csharp/GreeterServer/.gitignore deleted file mode 100644 index 1746e3269e..0000000000 --- a/csharp/GreeterServer/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -bin -obj diff --git a/csharp/GreeterServer/GreeterServer.csproj b/csharp/GreeterServer/GreeterServer.csproj deleted file mode 100644 index cd50d6cd52..0000000000 --- a/csharp/GreeterServer/GreeterServer.csproj +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {A7706C84-92D2-4B7A-B779-76B64D2950EC} - Exe - GreeterServer - GreeterServer - v4.5 - a1eeb1d8 - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - - - full - true - bin\Release - prompt - 4 - true - - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - - - False - ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll - - - - False - ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - - - ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll - - - - - - - - - - {724DFC8C-4B57-4C3F-811C-0463BE2A2829} - Greeter - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - \ No newline at end of file diff --git a/csharp/GreeterServer/Program.cs b/csharp/GreeterServer/Program.cs deleted file mode 100644 index 9482797c3b..0000000000 --- a/csharp/GreeterServer/Program.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Threading.Tasks; -using Grpc.Core; -using helloworld; - -namespace GreeterServer -{ - class GreeterImpl : Greeter.IGreeter - { - // Server side handler of the SayHello RPC - public Task SayHello(ServerCallContext context, HelloRequest request) - { - var reply = new HelloReply.Builder { Message = "Hello " + request.Name }.Build(); - return Task.FromResult(reply); - } - } - - class ServerMainClass - { - public static void Main(string[] args) - { - GrpcEnvironment.Initialize(); - - Server server = new Server(); - server.AddServiceDefinition(Greeter.BindService(new GreeterImpl())); - int port = server.AddListeningPort("localhost", 50051); - server.Start(); - - Console.WriteLine("Greeter server listening on port " + port); - Console.WriteLine("Press any key to stop the server..."); - Console.ReadKey(); - - server.ShutdownAsync().Wait(); - GrpcEnvironment.Shutdown(); - } - } -} diff --git a/csharp/GreeterServer/Properties/AssemblyInfo.cs b/csharp/GreeterServer/Properties/AssemblyInfo.cs deleted file mode 100644 index f8a8d521d8..0000000000 --- a/csharp/GreeterServer/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. -[assembly: AssemblyTitle("GreeterServer")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("jtattermusch")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. -[assembly: AssemblyVersion("1.0.*")] -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/csharp/GreeterServer/packages.config b/csharp/GreeterServer/packages.config deleted file mode 100644 index 5922553bc3..0000000000 --- a/csharp/GreeterServer/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/csharp/README.md b/csharp/README.md deleted file mode 100644 index 77d1aaf2e6..0000000000 --- a/csharp/README.md +++ /dev/null @@ -1,72 +0,0 @@ -gRPC in 3 minutes (C#) -======================== - -BACKGROUND -------------- -For this sample, we've already generated the server and client stubs from `helloworld.proto`. -Example projects depend on NuGet packages `Grpc` and `Google.ProtocolBuffers` which have been already added to the project for you. - -PREREQUISITES -------------- -**Windows** -- .NET 4.5+ -- VS 2013 (with NuGet plugin installed) - -**Linux (Mono)** -- Mono -- Monodevelop 5.9 with NuGet Add-in installed (older versions might work) - -**MacOS (Mono)** -- Xamarin Studio (with NuGet plugin installed) - -BUILD -------- - -**Windows** -- Clone this repository. - -- Open solution `Greeter.sln` with Visual Studio - -- Build the solution (this will automatically download NuGet dependencies) - -**Linux (Mono)** -- Clone this repository. - -- Install gRPC C Core using instructions in https://github.com/grpc/homebrew-grpc - -- gRPC C# depends on native shared library `libgrpc_csharp_ext.so`. To make it visible - to Mono runtime, follow instructions in [Using gRPC C# on Linux](https://github.com/grpc/grpc/tree/master/src/csharp#usage-linux-mono) - -- Open solution `Greeter.sln` in MonoDevelop (you need to manually restore dependencies by using `mono nuget.exe restore` if you don't have NuGet add-in) - -- Build the solution. - -**MacOS (Mono)** -- See [Using gRPC C# on MacOS](https://github.com/grpc/grpc/tree/master/src/csharp#usage-macos-mono) for more info - on MacOS support. - -Try it! -------- - -- Run the server - - ``` - > cd GreeterServer/bin/Debug - > GreeterServer.exe - ``` - -- Run the client - - ``` - > cd GreeterClient/bin/Debug - > GreeterClient.exe - ``` - -You can also run the server and client directly from Visual Studio. - -On Linux or Mac, use `mono GreeterServer.exe` and `mono GreeterClient.exe` to run the server and client. - -Tutorial --------- - -You can find a more detailed tutorial in [gRPC Basics: C#](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/README.md) diff --git a/csharp/route_guide/.gitignore b/csharp/route_guide/.gitignore deleted file mode 100644 index 585000ea2d..0000000000 --- a/csharp/route_guide/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -bin/ -obj/ -packages/ -*.suo -*.userprefs diff --git a/csharp/route_guide/.nuget/packages.config b/csharp/route_guide/.nuget/packages.config deleted file mode 100644 index b14373069f..0000000000 --- a/csharp/route_guide/.nuget/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/csharp/route_guide/README.md b/csharp/route_guide/README.md deleted file mode 100644 index 35c6024bcf..0000000000 --- a/csharp/route_guide/README.md +++ /dev/null @@ -1,409 +0,0 @@ -#gRPC Basics: C# # - -This tutorial provides a basic C# programmer's introduction to working with gRPC. By walking through this example you'll learn how to: - -- Define a service in a .proto file. -- Generate server and client code using the protocol buffer compiler. -- Use the C# gRPC API to write a simple client and server for your service. - -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial only uses the proto2 version of the protocol buffers language, as proto3 support for C# is not ready yet (see [protobuf C# README](https://github.com/google/protobuf/tree/master/csharp#proto2--proto3)). - -This isn't a comprehensive guide to using gRPC in C#: more reference documentation is coming soon. - -## Why use gRPC? - -Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. - -With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. - -## Example code and setup - -The example code for our tutorial is in [grpc/grpc-common/csharp/route_guide](https://github.com/grpc/grpc-common/tree/master/csharp/route_guide). To download the example, clone the `grpc-common` repository by running the following command: -```shell -$ git clone https://github.com/google/grpc-common.git -``` - -All the files for this tutorial are in the directory `grpc-common/csharp/route_guide`. -Open the solution `grpc-common/csharp/route_guide/RouteGuide.sln` from Visual Studio (or Monodevelop on Linux). - -On Windows, you should not need to do anything besides opening the solution. All the needed dependencies will be restored -for you automatically by the `Grpc` NuGet package upon building the solution. - -On Linux (or MacOS), you will first need to install protobuf and gRPC C Core using Linuxbrew (or Homebrew) tool in order to be -able to generate the server and client interface code and run the examples. Follow the instructions for [Linux](https://github.com/grpc/grpc/tree/master/src/csharp#usage-linux-mono) or [MacOS](https://github.com/grpc/grpc/tree/master/src/csharp#usage-macos-mono). - -## Defining the service - -Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/csharp/route_guide/RouteGuide/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/sharp/route_guide/RouteGuide/protos/route_guide.proto). - -To define a service, you specify a named `service` in your .proto file: - -```protobuf -service RouteGuide { - ... -} -``` - -Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: - -- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. -```protobuf - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} -``` - -- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. -```protobuf - // Obtains the Features available within the given Rectangle. Results are - // streamed rather than returned at once (e.g. in a response message with a - // repeated field), as the rectangle may cover a large area and contain a - // huge number of features. - rpc ListFeatures(Rectangle) returns (stream Feature) {} -``` - -- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. -```protobuf - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} -``` - -- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -```protobuf - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -``` - -Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -```protobuf -// 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; -} -``` - - -## Generating client and server code - -Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C# plugin. - -If you want to run this yourself, make sure you've installed protoc and gRPC C# plugin. The instructions vary based on your OS: -- For Windows, the `Grpc.Tools` NuGet package contains the binaries you will need to generate the code. -- For Linux, make sure you've [installed gRPC C Core using Linuxbrew](https://github.com/grpc/grpc/tree/master/src/csharp#usage-linux-mono) -- For MacOS, make sure you've [installed gRPC C Core using Homebrew](https://github.com/grpc/grpc/tree/master/src/csharp#usage-macos-mono) - -Once that's done, the following command can be used to generate the C# code. - -To generate the code on Windows, we use `protoc.exe` and `grpc_csharp_plugin.exe` binaries that are shipped with the `Grpc.Tools` NuGet package under the `tools` directory. -Normally you would need to add the `Grpc.Tools` package to the solution yourself, but in this tutorial it has been already done for you. Following command should be run from the `csharp/route_guide` directory: -``` -> packages\Grpc.Tools.0.5.1\tools\protoc -I RouteGuide/protos --csharp_out=RouteGuide --grpc_out=RouteGuide --plugin=protoc-gen-grpc=packages\Grpc.Tools.0.5.1\tools\grpc_csharp_plugin.exe RouteGuide/protos/route_guide.proto -``` - -On Linux/MacOS, we rely on `protoc` and `grpc_csharp_plugin` being installed by Linuxbrew/Homebrew. Run this command from the route_guide directory: -```shell -$ protoc -I RouteGuide/protos --csharp_out=RouteGuide --grpc_out=RouteGuide --plugin=protoc-gen-grpc=`which grpc_csharp_plugin` RouteGuide/protos/route_guide.proto -``` - -Running one of the previous commands regenerates the following files in the RouteGuide directory: -- `RouteGuide/RouteGuide.cs` defines a namespace `examples` - - This contains all the protocol buffer code to populate, serialize, and retrieve our request and response message types -- `RouteGuide/RouteGuideGrpc.cs`, provides stub and service classes - - an interface `RouteGuide.IRouteGuide` to inherit from when defining RouteGuide service implementations - - a class `RouteGuide.RouteGuideClient` that can be used to access remote RouteGuide instances - - - -## Creating the server - -First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). - -There are two parts to making our `RouteGuide` service do its job: -- Implementing the service interface generated from our service definition: doing the actual "work" of our service. -- Running a gRPC server to listen for requests from clients and return the service responses. - -You can find our example `RouteGuide` server in [grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/RouteGuideServer/RouteGuideServerImpl.cs). Let's take a closer look at how it works. - -### Implementing RouteGuide - -As you can see, our server has a `RouteGuideImpl` class that implements the generated `RouteGuide.IRouteGuide`: - -```csharp -// RouteGuideImpl provides an implementation of the RouteGuide service. -public class RouteGuideImpl : RouteGuide.IRouteGuide -``` - -#### Simple RPC - -`RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. - -```csharp - public Task GetFeature(Grpc.Core.ServerCallContext context, Point request) - { - return Task.FromResult(CheckFeature(request)); - } -``` - -The method is passed a context for the RPC (which is empty in the alpha release), the client's `Point` protocol buffer request, and returns a `Feature` protocol buffer. In the method we create the `Feature` with the appropriate information, and then return it. To allow asynchronous -implementation, the method returns `Task` rather than just `Feature`. You are free to perform your computations synchronously and return -the result once you've finished, just as we do in the example. - -#### Server-side streaming RPC - -Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature` protocol buffers to our client. - -```csharp - // in RouteGuideImpl - public async Task ListFeatures(Grpc.Core.ServerCallContext context, Rectangle request, - Grpc.Core.IServerStreamWriter responseStream) - { - int left = Math.Min(request.Lo.Longitude, request.Hi.Longitude); - int right = Math.Max(request.Lo.Longitude, request.Hi.Longitude); - int top = Math.Max(request.Lo.Latitude, request.Hi.Latitude); - int bottom = Math.Min(request.Lo.Latitude, request.Hi.Latitude); - - foreach (var feature in features) - { - if (!RouteGuideUtil.Exists(feature)) - { - continue; - } - - int lat = feature.Location.Latitude; - int lon = feature.Location.Longitude; - if (lon >= left && lon <= right && lat >= bottom && lat <= top) - { - await responseStream.WriteAsync(feature); - } - } - } -``` - -As you can see, here the request object is a `Rectangle` in which our client wants to find `Feature`s, but instead of returning a simple response we need to write responses to an asynchronous stream `IServerStreamWriter` using async method `WriteAsync`. - -#### Client-side streaming RPC - -Similarly, the client-side streaming method `RecordRoute` uses an [IAsyncEnumerator](https://github.com/Reactive-Extensions/Rx.NET/blob/master/Ix.NET/Source/System.Interactive.Async/IAsyncEnumerator.cs), to read the stream of requests using the async method `MoveNext` and the `Current` property. - -```csharp - public async Task RecordRoute(Grpc.Core.ServerCallContext context, - Grpc.Core.IAsyncStreamReader requestStream) - { - int pointCount = 0; - int featureCount = 0; - int distance = 0; - Point previous = null; - var stopwatch = new Stopwatch(); - stopwatch.Start(); - - while (await requestStream.MoveNext()) - { - var point = requestStream.Current; - pointCount++; - if (RouteGuideUtil.Exists(CheckFeature(point))) - { - featureCount++; - } - if (previous != null) - { - distance += (int) CalcDistance(previous, point); - } - previous = point; - } - - stopwatch.Stop(); - return RouteSummary.CreateBuilder().SetPointCount(pointCount) - .SetFeatureCount(featureCount).SetDistance(distance) - .SetElapsedTime((int) (stopwatch.ElapsedMilliseconds / 1000)).Build(); - } -``` - -#### Bidirectional streaming RPC - -Finally, let's look at our bidirectional streaming RPC `RouteChat`. - -```csharp - public async Task RouteChat(Grpc.Core.ServerCallContext context, - Grpc.Core.IAsyncStreamReader requestStream, Grpc.Core.IServerStreamWriter responseStream) - { - while (await requestStream.MoveNext()) - { - var note = requestStream.Current; - List notes = GetOrCreateNotes(note.Location); - - List prevNotes; - lock (notes) - { - prevNotes = new List(notes); - } - - foreach (var prevNote in prevNotes) - { - await responseStream.WriteAsync(prevNote); - } - - lock (notes) - { - notes.Add(note); - } - } - } -``` - -Here the method receives both `requestStream` and `responseStream` arguments. Reading the requests is done the same way as in the client-side streaming method `RecordRoute`. Writing the responses is done the same way as in the server-side streaming method `ListFeatures`. - -### Starting the server - -Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: - -```csharp -var features = RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile); -GrpcEnvironment.Initialize(); - -Server server = new Server(); -server.AddServiceDefinition(RouteGuide.BindService(new RouteGuideImpl(features))); -int port = server.AddListeningPort("localhost", 50052); -server.Start(); - -Console.WriteLine("RouteGuide server listening on port " + port); -Console.WriteLine("Press any key to stop the server..."); -Console.ReadKey(); - -server.ShutdownAsync().Wait(); -GrpcEnvironment.Shutdown(); -``` -As you can see, we build and start our server using `Grpc.Core.Server` class. To do this, we: - -1. Create an instance of `Grpc.Core.Server`. -1. Create an instance of our service implementation class `RouteGuideImpl`. -3. Register our service implementation with the server using the `AddServiceDefinition` method and the generated method `RouteGuide.BindService`. -2. Specify the address and port we want to use to listen for client requests using the `AddListeningPort` method. -4. Call `Start` on the server instance to start an RPC server for our service. - - -## Creating the client - -In this section, we'll look at creating a C# client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/csharp/route_guide/RouteGuideClient/Program.cs](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/RouteGuideClient/Program.cs). - -### Creating a stub - -To call service methods, we first need to create a *stub*. - -First, we need to create a gRPC client channel that will connect to gRPC server. Then, we use the `RouteGuide.NewStub` method of the `RouteGuide` class generated from our .proto. - -```csharp -GrpcEnvironment.Initialize(); - -using (Channel channel = new Channel("127.0.0.1:50052")) -{ - var client = RouteGuide.NewStub(channel); - - // YOUR CODE GOES HERE -} - -GrpcEnvironment.Shutdown(); -``` - -### Calling service methods - -Now let's look at how we call our service methods. gRPC C# provides asynchronous versions of each of the supported method types. For convenience, -gRPC C# also provides a synchronous method stub, but only for simple (single request/single response) RPCs. - -#### Simple RPC - -Calling the simple RPC `GetFeature` in a synchronous way is nearly as straightforward as calling a local method. - -```csharp -Point request = Point.CreateBuilder().SetLatitude(409146138).SetLongitude(-746188906).Build(); -Feature feature = client.GetFeature(request); -``` - -As you can see, we create and populate a request protocol buffer object (in our case `Point`), and call the desired method on the client object, passing it the request. If the RPC finishes with success, the response protocol buffer (in our case `Feature`) will be returned. Otherwise, an exception of type `RpcException` will be thrown, indicating the status code of the problem. - -Alternatively, if you are in async context, you can call an asynchronous version of the method (and use `await` keyword to await the result): -```csharp -Point request = Point.CreateBuilder().SetLatitude(409146138).SetLongitude(-746188906).Build(); -Feature feature = await client.GetFeatureAsync(request); -``` - -#### Streaming RPCs - -Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. The difference with respect to simple call is that the client methods return an instance of a call object, that provides access to request/response streams and/or asynchronous result (depending on the streaming type you are using). - -Here's where we call the server-side streaming method `ListFeatures`, which has property `ReponseStream` of type `IAsyncEnumerator` - -```csharp -using (var call = client.ListFeatures(request)) -{ - while (await call.ResponseStream.MoveNext()) - { - Feature feature = call.ResponseStream.Current; - Console.WriteLine("Received " + feature.ToString()); - } -} -``` - -The client-side streaming method `RecordRoute` is similar, except we use the property `RequestStream` to write the requests one by one using `WriteAsync` and eventually signal that no more request will be send using `CompleteAsync`. The method result can be obtained through the property -`Result`. -```csharp -using (var call = client.RecordRoute()) -{ - foreach (var point in points) - { - await call.RequestStream.WriteAsync(point); - } - await call.RequestStream.CompleteAsync(); - - RouteSummary summary = await call.Result; -} -``` - -Finally, let's look at our bidirectional streaming RPC `RouteChat`. In this case, we write the request to `RequestStream` and receive the responses from `ResponseStream`. As you can see from the example, the streams are independent of each other. - -```csharp - using (var call = client.RouteChat()) - { - var responseReaderTask = Task.Run(async () => - { - while (await call.ResponseStream.MoveNext()) - { - var note = call.ResponseStream.Current; - Console.WriteLine("Received " + note); - } - }); - - foreach (RouteNote request in requests) - { - await call.RequestStream.WriteAsync(request); - } - await call.RequestStream.CompleteAsync(); - await responseReaderTask; -} -``` - -## Try it out! - -Build client and server: - -Open the solution `grpc-common/csharp/route_guide/RouteGuide.sln` from Visual Studio (or Monodevelop on Linux) and hit "Build". - -Run the server, which will listen on port 50052: -``` -> cd RouteGuideServer/bin/Debug -> RouteGuideServer.exe -``` - -Run the client (in a different terminal): -``` -> cd RouteGuideClient/bin/Debug -> RouteGuideClient.exe -``` - -You can also run the server and client directly from Visual Studio. - -On Linux or Mac, use `mono RouteGuideServer.exe` and `mono RouteGuideClient.exe` to run the server and client. diff --git a/csharp/route_guide/RouteGuide.sln b/csharp/route_guide/RouteGuide.sln deleted file mode 100644 index 0b79fdc5ca..0000000000 --- a/csharp/route_guide/RouteGuide.sln +++ /dev/null @@ -1,39 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.31101.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuide", "RouteGuide\RouteGuide.csproj", "{49954D9C-5F17-4662-96B2-73BE833DD81A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideClient", "RouteGuideClient\RouteGuideClient.csproj", "{D47BE663-4DE3-4206-B7A8-EA3FA066DADC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideServer", "RouteGuideServer\RouteGuideServer.csproj", "{4B7C7794-BE24-4477-ACE7-18259EB73D27}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2F6B184B-A576-4F21-AF2E-27E73D1FC96E}" - ProjectSection(SolutionItems) = preProject - .nuget\packages.config = .nuget\packages.config - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {49954D9C-5F17-4662-96B2-73BE833DD81A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {49954D9C-5F17-4662-96B2-73BE833DD81A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {49954D9C-5F17-4662-96B2-73BE833DD81A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {49954D9C-5F17-4662-96B2-73BE833DD81A}.Release|Any CPU.Build.0 = Release|Any CPU - {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Release|Any CPU.Build.0 = Release|Any CPU - {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs b/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs deleted file mode 100644 index 9c3441e42f..0000000000 --- a/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("RouteGuide")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("RouteGuide")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("ef6b85bc-ac27-46de-8714-a658236cc6fb")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/csharp/route_guide/RouteGuide/RouteGuide.cs b/csharp/route_guide/RouteGuide/RouteGuide.cs deleted file mode 100644 index 80508bcd3f..0000000000 --- a/csharp/route_guide/RouteGuide/RouteGuide.cs +++ /dev/null @@ -1,1873 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: route_guide.proto -#pragma warning disable 1591, 0612, 3021 -#region Designer generated code - -using pb = global::Google.ProtocolBuffers; -using pbc = global::Google.ProtocolBuffers.Collections; -using pbd = global::Google.ProtocolBuffers.Descriptors; -using scg = global::System.Collections.Generic; -namespace examples { - - namespace Proto { - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public static partial class RouteGuide { - - #region Extension registration - public static void RegisterAllExtensions(pb::ExtensionRegistry registry) { - } - #endregion - #region Static variables - internal static pbd::MessageDescriptor internal__static_examples_Point__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_Point__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_examples_Rectangle__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_Rectangle__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_examples_Feature__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_Feature__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_examples_RouteNote__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_RouteNote__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_examples_RouteSummary__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_RouteSummary__FieldAccessorTable; - #endregion - #region Descriptor - public static pbd::FileDescriptor Descriptor { - get { return descriptor; } - } - private static pbd::FileDescriptor descriptor; - - static RouteGuide() { - byte[] descriptorData = global::System.Convert.FromBase64String( - string.Concat( - "ChFyb3V0ZV9ndWlkZS5wcm90bxIIZXhhbXBsZXMiLAoFUG9pbnQSEAoIbGF0", - "aXR1ZGUYASABKAUSEQoJbG9uZ2l0dWRlGAIgASgFIkUKCVJlY3RhbmdsZRIb", - "CgJsbxgBIAEoCzIPLmV4YW1wbGVzLlBvaW50EhsKAmhpGAIgASgLMg8uZXhh", - "bXBsZXMuUG9pbnQiOgoHRmVhdHVyZRIMCgRuYW1lGAEgASgJEiEKCGxvY2F0", - "aW9uGAIgASgLMg8uZXhhbXBsZXMuUG9pbnQiPwoJUm91dGVOb3RlEiEKCGxv", - "Y2F0aW9uGAEgASgLMg8uZXhhbXBsZXMuUG9pbnQSDwoHbWVzc2FnZRgCIAEo", - "CSJiCgxSb3V0ZVN1bW1hcnkSEwoLcG9pbnRfY291bnQYASABKAUSFQoNZmVh", - "dHVyZV9jb3VudBgCIAEoBRIQCghkaXN0YW5jZRgDIAEoBRIUCgxlbGFwc2Vk", - "X3RpbWUYBCABKAUy9QEKClJvdXRlR3VpZGUSMgoKR2V0RmVhdHVyZRIPLmV4", - "YW1wbGVzLlBvaW50GhEuZXhhbXBsZXMuRmVhdHVyZSIAEjoKDExpc3RGZWF0", - "dXJlcxITLmV4YW1wbGVzLlJlY3RhbmdsZRoRLmV4YW1wbGVzLkZlYXR1cmUi", - "ADABEjoKC1JlY29yZFJvdXRlEg8uZXhhbXBsZXMuUG9pbnQaFi5leGFtcGxl", - "cy5Sb3V0ZVN1bW1hcnkiACgBEjsKCVJvdXRlQ2hhdBITLmV4YW1wbGVzLlJv", - "dXRlTm90ZRoTLmV4YW1wbGVzLlJvdXRlTm90ZSIAKAEwAQ==")); - pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) { - descriptor = root; - internal__static_examples_Point__Descriptor = Descriptor.MessageTypes[0]; - internal__static_examples_Point__FieldAccessorTable = - new pb::FieldAccess.FieldAccessorTable(internal__static_examples_Point__Descriptor, - new string[] { "Latitude", "Longitude", }); - internal__static_examples_Rectangle__Descriptor = Descriptor.MessageTypes[1]; - internal__static_examples_Rectangle__FieldAccessorTable = - new pb::FieldAccess.FieldAccessorTable(internal__static_examples_Rectangle__Descriptor, - new string[] { "Lo", "Hi", }); - internal__static_examples_Feature__Descriptor = Descriptor.MessageTypes[2]; - internal__static_examples_Feature__FieldAccessorTable = - new pb::FieldAccess.FieldAccessorTable(internal__static_examples_Feature__Descriptor, - new string[] { "Name", "Location", }); - internal__static_examples_RouteNote__Descriptor = Descriptor.MessageTypes[3]; - internal__static_examples_RouteNote__FieldAccessorTable = - new pb::FieldAccess.FieldAccessorTable(internal__static_examples_RouteNote__Descriptor, - new string[] { "Location", "Message", }); - internal__static_examples_RouteSummary__Descriptor = Descriptor.MessageTypes[4]; - internal__static_examples_RouteSummary__FieldAccessorTable = - new pb::FieldAccess.FieldAccessorTable(internal__static_examples_RouteSummary__Descriptor, - new string[] { "PointCount", "FeatureCount", "Distance", "ElapsedTime", }); - pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance(); - RegisterAllExtensions(registry); - return registry; - }; - pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData, - new pbd::FileDescriptor[] { - }, assigner); - } - #endregion - - } - } - #region Messages - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Point : pb::GeneratedMessage { - private Point() { } - private static readonly Point defaultInstance = new Point().MakeReadOnly(); - private static readonly string[] _pointFieldNames = new string[] { "latitude", "longitude" }; - private static readonly uint[] _pointFieldTags = new uint[] { 8, 16 }; - public static Point DefaultInstance { - get { return defaultInstance; } - } - - public override Point DefaultInstanceForType { - get { return DefaultInstance; } - } - - protected override Point ThisMessage { - get { return this; } - } - - public static pbd::MessageDescriptor Descriptor { - get { return global::examples.Proto.RouteGuide.internal__static_examples_Point__Descriptor; } - } - - protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { - get { return global::examples.Proto.RouteGuide.internal__static_examples_Point__FieldAccessorTable; } - } - - public const int LatitudeFieldNumber = 1; - private bool hasLatitude; - private int latitude_; - public bool HasLatitude { - get { return hasLatitude; } - } - public int Latitude { - get { return latitude_; } - } - - public const int LongitudeFieldNumber = 2; - private bool hasLongitude; - private int longitude_; - public bool HasLongitude { - get { return hasLongitude; } - } - public int Longitude { - get { return longitude_; } - } - - public override bool IsInitialized { - get { - return true; - } - } - - public override void WriteTo(pb::ICodedOutputStream output) { - CalcSerializedSize(); - string[] field_names = _pointFieldNames; - if (hasLatitude) { - output.WriteInt32(1, field_names[0], Latitude); - } - if (hasLongitude) { - output.WriteInt32(2, field_names[1], Longitude); - } - UnknownFields.WriteTo(output); - } - - private int memoizedSerializedSize = -1; - public override int SerializedSize { - get { - int size = memoizedSerializedSize; - if (size != -1) return size; - return CalcSerializedSize(); - } - } - - private int CalcSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (hasLatitude) { - size += pb::CodedOutputStream.ComputeInt32Size(1, Latitude); - } - if (hasLongitude) { - size += pb::CodedOutputStream.ComputeInt32Size(2, Longitude); - } - size += UnknownFields.SerializedSize; - memoizedSerializedSize = size; - return size; - } - public static Point ParseFrom(pb::ByteString data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static Point ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static Point ParseFrom(byte[] data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static Point ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static Point ParseFrom(global::System.IO.Stream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static Point ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - public static Point ParseDelimitedFrom(global::System.IO.Stream input) { - return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); - } - public static Point ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); - } - public static Point ParseFrom(pb::ICodedInputStream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static Point ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - private Point MakeReadOnly() { - return this; - } - - public static Builder CreateBuilder() { return new Builder(); } - public override Builder ToBuilder() { return CreateBuilder(this); } - public override Builder CreateBuilderForType() { return new Builder(); } - public static Builder CreateBuilder(Point prototype) { - return new Builder(prototype); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Builder : pb::GeneratedBuilder { - protected override Builder ThisBuilder { - get { return this; } - } - public Builder() { - result = DefaultInstance; - resultIsReadOnly = true; - } - internal Builder(Point cloneFrom) { - result = cloneFrom; - resultIsReadOnly = true; - } - - private bool resultIsReadOnly; - private Point result; - - private Point PrepareBuilder() { - if (resultIsReadOnly) { - Point original = result; - result = new Point(); - resultIsReadOnly = false; - MergeFrom(original); - } - return result; - } - - public override bool IsInitialized { - get { return result.IsInitialized; } - } - - protected override Point MessageBeingBuilt { - get { return PrepareBuilder(); } - } - - public override Builder Clear() { - result = DefaultInstance; - resultIsReadOnly = true; - return this; - } - - public override Builder Clone() { - if (resultIsReadOnly) { - return new Builder(result); - } else { - return new Builder().MergeFrom(result); - } - } - - public override pbd::MessageDescriptor DescriptorForType { - get { return global::examples.Point.Descriptor; } - } - - public override Point DefaultInstanceForType { - get { return global::examples.Point.DefaultInstance; } - } - - public override Point BuildPartial() { - if (resultIsReadOnly) { - return result; - } - resultIsReadOnly = true; - return result.MakeReadOnly(); - } - - public override Builder MergeFrom(pb::IMessage other) { - if (other is Point) { - return MergeFrom((Point) other); - } else { - base.MergeFrom(other); - return this; - } - } - - public override Builder MergeFrom(Point other) { - if (other == global::examples.Point.DefaultInstance) return this; - PrepareBuilder(); - if (other.HasLatitude) { - Latitude = other.Latitude; - } - if (other.HasLongitude) { - Longitude = other.Longitude; - } - this.MergeUnknownFields(other.UnknownFields); - return this; - } - - public override Builder MergeFrom(pb::ICodedInputStream input) { - return MergeFrom(input, pb::ExtensionRegistry.Empty); - } - - public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - PrepareBuilder(); - pb::UnknownFieldSet.Builder unknownFields = null; - uint tag; - string field_name; - while (input.ReadTag(out tag, out field_name)) { - if(tag == 0 && field_name != null) { - int field_ordinal = global::System.Array.BinarySearch(_pointFieldNames, field_name, global::System.StringComparer.Ordinal); - if(field_ordinal >= 0) - tag = _pointFieldTags[field_ordinal]; - else { - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - continue; - } - } - switch (tag) { - case 0: { - throw pb::InvalidProtocolBufferException.InvalidTag(); - } - default: { - if (pb::WireFormat.IsEndGroupTag(tag)) { - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - break; - } - case 8: { - result.hasLatitude = input.ReadInt32(ref result.latitude_); - break; - } - case 16: { - result.hasLongitude = input.ReadInt32(ref result.longitude_); - break; - } - } - } - - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - - - public bool HasLatitude { - get { return result.hasLatitude; } - } - public int Latitude { - get { return result.Latitude; } - set { SetLatitude(value); } - } - public Builder SetLatitude(int value) { - PrepareBuilder(); - result.hasLatitude = true; - result.latitude_ = value; - return this; - } - public Builder ClearLatitude() { - PrepareBuilder(); - result.hasLatitude = false; - result.latitude_ = 0; - return this; - } - - public bool HasLongitude { - get { return result.hasLongitude; } - } - public int Longitude { - get { return result.Longitude; } - set { SetLongitude(value); } - } - public Builder SetLongitude(int value) { - PrepareBuilder(); - result.hasLongitude = true; - result.longitude_ = value; - return this; - } - public Builder ClearLongitude() { - PrepareBuilder(); - result.hasLongitude = false; - result.longitude_ = 0; - return this; - } - } - static Point() { - object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Rectangle : pb::GeneratedMessage { - private Rectangle() { } - private static readonly Rectangle defaultInstance = new Rectangle().MakeReadOnly(); - private static readonly string[] _rectangleFieldNames = new string[] { "hi", "lo" }; - private static readonly uint[] _rectangleFieldTags = new uint[] { 18, 10 }; - public static Rectangle DefaultInstance { - get { return defaultInstance; } - } - - public override Rectangle DefaultInstanceForType { - get { return DefaultInstance; } - } - - protected override Rectangle ThisMessage { - get { return this; } - } - - public static pbd::MessageDescriptor Descriptor { - get { return global::examples.Proto.RouteGuide.internal__static_examples_Rectangle__Descriptor; } - } - - protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { - get { return global::examples.Proto.RouteGuide.internal__static_examples_Rectangle__FieldAccessorTable; } - } - - public const int LoFieldNumber = 1; - private bool hasLo; - private global::examples.Point lo_; - public bool HasLo { - get { return hasLo; } - } - public global::examples.Point Lo { - get { return lo_ ?? global::examples.Point.DefaultInstance; } - } - - public const int HiFieldNumber = 2; - private bool hasHi; - private global::examples.Point hi_; - public bool HasHi { - get { return hasHi; } - } - public global::examples.Point Hi { - get { return hi_ ?? global::examples.Point.DefaultInstance; } - } - - public override bool IsInitialized { - get { - return true; - } - } - - public override void WriteTo(pb::ICodedOutputStream output) { - CalcSerializedSize(); - string[] field_names = _rectangleFieldNames; - if (hasLo) { - output.WriteMessage(1, field_names[1], Lo); - } - if (hasHi) { - output.WriteMessage(2, field_names[0], Hi); - } - UnknownFields.WriteTo(output); - } - - private int memoizedSerializedSize = -1; - public override int SerializedSize { - get { - int size = memoizedSerializedSize; - if (size != -1) return size; - return CalcSerializedSize(); - } - } - - private int CalcSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (hasLo) { - size += pb::CodedOutputStream.ComputeMessageSize(1, Lo); - } - if (hasHi) { - size += pb::CodedOutputStream.ComputeMessageSize(2, Hi); - } - size += UnknownFields.SerializedSize; - memoizedSerializedSize = size; - return size; - } - public static Rectangle ParseFrom(pb::ByteString data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static Rectangle ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static Rectangle ParseFrom(byte[] data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static Rectangle ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static Rectangle ParseFrom(global::System.IO.Stream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static Rectangle ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - public static Rectangle ParseDelimitedFrom(global::System.IO.Stream input) { - return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); - } - public static Rectangle ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); - } - public static Rectangle ParseFrom(pb::ICodedInputStream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static Rectangle ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - private Rectangle MakeReadOnly() { - return this; - } - - public static Builder CreateBuilder() { return new Builder(); } - public override Builder ToBuilder() { return CreateBuilder(this); } - public override Builder CreateBuilderForType() { return new Builder(); } - public static Builder CreateBuilder(Rectangle prototype) { - return new Builder(prototype); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Builder : pb::GeneratedBuilder { - protected override Builder ThisBuilder { - get { return this; } - } - public Builder() { - result = DefaultInstance; - resultIsReadOnly = true; - } - internal Builder(Rectangle cloneFrom) { - result = cloneFrom; - resultIsReadOnly = true; - } - - private bool resultIsReadOnly; - private Rectangle result; - - private Rectangle PrepareBuilder() { - if (resultIsReadOnly) { - Rectangle original = result; - result = new Rectangle(); - resultIsReadOnly = false; - MergeFrom(original); - } - return result; - } - - public override bool IsInitialized { - get { return result.IsInitialized; } - } - - protected override Rectangle MessageBeingBuilt { - get { return PrepareBuilder(); } - } - - public override Builder Clear() { - result = DefaultInstance; - resultIsReadOnly = true; - return this; - } - - public override Builder Clone() { - if (resultIsReadOnly) { - return new Builder(result); - } else { - return new Builder().MergeFrom(result); - } - } - - public override pbd::MessageDescriptor DescriptorForType { - get { return global::examples.Rectangle.Descriptor; } - } - - public override Rectangle DefaultInstanceForType { - get { return global::examples.Rectangle.DefaultInstance; } - } - - public override Rectangle BuildPartial() { - if (resultIsReadOnly) { - return result; - } - resultIsReadOnly = true; - return result.MakeReadOnly(); - } - - public override Builder MergeFrom(pb::IMessage other) { - if (other is Rectangle) { - return MergeFrom((Rectangle) other); - } else { - base.MergeFrom(other); - return this; - } - } - - public override Builder MergeFrom(Rectangle other) { - if (other == global::examples.Rectangle.DefaultInstance) return this; - PrepareBuilder(); - if (other.HasLo) { - MergeLo(other.Lo); - } - if (other.HasHi) { - MergeHi(other.Hi); - } - this.MergeUnknownFields(other.UnknownFields); - return this; - } - - public override Builder MergeFrom(pb::ICodedInputStream input) { - return MergeFrom(input, pb::ExtensionRegistry.Empty); - } - - public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - PrepareBuilder(); - pb::UnknownFieldSet.Builder unknownFields = null; - uint tag; - string field_name; - while (input.ReadTag(out tag, out field_name)) { - if(tag == 0 && field_name != null) { - int field_ordinal = global::System.Array.BinarySearch(_rectangleFieldNames, field_name, global::System.StringComparer.Ordinal); - if(field_ordinal >= 0) - tag = _rectangleFieldTags[field_ordinal]; - else { - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - continue; - } - } - switch (tag) { - case 0: { - throw pb::InvalidProtocolBufferException.InvalidTag(); - } - default: { - if (pb::WireFormat.IsEndGroupTag(tag)) { - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - break; - } - case 10: { - global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); - if (result.hasLo) { - subBuilder.MergeFrom(Lo); - } - input.ReadMessage(subBuilder, extensionRegistry); - Lo = subBuilder.BuildPartial(); - break; - } - case 18: { - global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); - if (result.hasHi) { - subBuilder.MergeFrom(Hi); - } - input.ReadMessage(subBuilder, extensionRegistry); - Hi = subBuilder.BuildPartial(); - break; - } - } - } - - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - - - public bool HasLo { - get { return result.hasLo; } - } - public global::examples.Point Lo { - get { return result.Lo; } - set { SetLo(value); } - } - public Builder SetLo(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasLo = true; - result.lo_ = value; - return this; - } - public Builder SetLo(global::examples.Point.Builder builderForValue) { - pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); - PrepareBuilder(); - result.hasLo = true; - result.lo_ = builderForValue.Build(); - return this; - } - public Builder MergeLo(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - if (result.hasLo && - result.lo_ != global::examples.Point.DefaultInstance) { - result.lo_ = global::examples.Point.CreateBuilder(result.lo_).MergeFrom(value).BuildPartial(); - } else { - result.lo_ = value; - } - result.hasLo = true; - return this; - } - public Builder ClearLo() { - PrepareBuilder(); - result.hasLo = false; - result.lo_ = null; - return this; - } - - public bool HasHi { - get { return result.hasHi; } - } - public global::examples.Point Hi { - get { return result.Hi; } - set { SetHi(value); } - } - public Builder SetHi(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasHi = true; - result.hi_ = value; - return this; - } - public Builder SetHi(global::examples.Point.Builder builderForValue) { - pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); - PrepareBuilder(); - result.hasHi = true; - result.hi_ = builderForValue.Build(); - return this; - } - public Builder MergeHi(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - if (result.hasHi && - result.hi_ != global::examples.Point.DefaultInstance) { - result.hi_ = global::examples.Point.CreateBuilder(result.hi_).MergeFrom(value).BuildPartial(); - } else { - result.hi_ = value; - } - result.hasHi = true; - return this; - } - public Builder ClearHi() { - PrepareBuilder(); - result.hasHi = false; - result.hi_ = null; - return this; - } - } - static Rectangle() { - object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Feature : pb::GeneratedMessage { - private Feature() { } - private static readonly Feature defaultInstance = new Feature().MakeReadOnly(); - private static readonly string[] _featureFieldNames = new string[] { "location", "name" }; - private static readonly uint[] _featureFieldTags = new uint[] { 18, 10 }; - public static Feature DefaultInstance { - get { return defaultInstance; } - } - - public override Feature DefaultInstanceForType { - get { return DefaultInstance; } - } - - protected override Feature ThisMessage { - get { return this; } - } - - public static pbd::MessageDescriptor Descriptor { - get { return global::examples.Proto.RouteGuide.internal__static_examples_Feature__Descriptor; } - } - - protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { - get { return global::examples.Proto.RouteGuide.internal__static_examples_Feature__FieldAccessorTable; } - } - - public const int NameFieldNumber = 1; - private bool hasName; - private string name_ = ""; - public bool HasName { - get { return hasName; } - } - public string Name { - get { return name_; } - } - - public const int LocationFieldNumber = 2; - private bool hasLocation; - private global::examples.Point location_; - public bool HasLocation { - get { return hasLocation; } - } - public global::examples.Point Location { - get { return location_ ?? global::examples.Point.DefaultInstance; } - } - - public override bool IsInitialized { - get { - return true; - } - } - - public override void WriteTo(pb::ICodedOutputStream output) { - CalcSerializedSize(); - string[] field_names = _featureFieldNames; - if (hasName) { - output.WriteString(1, field_names[1], Name); - } - if (hasLocation) { - output.WriteMessage(2, field_names[0], Location); - } - UnknownFields.WriteTo(output); - } - - private int memoizedSerializedSize = -1; - public override int SerializedSize { - get { - int size = memoizedSerializedSize; - if (size != -1) return size; - return CalcSerializedSize(); - } - } - - private int CalcSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (hasName) { - size += pb::CodedOutputStream.ComputeStringSize(1, Name); - } - if (hasLocation) { - size += pb::CodedOutputStream.ComputeMessageSize(2, Location); - } - size += UnknownFields.SerializedSize; - memoizedSerializedSize = size; - return size; - } - public static Feature ParseFrom(pb::ByteString data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static Feature ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static Feature ParseFrom(byte[] data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static Feature ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static Feature ParseFrom(global::System.IO.Stream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static Feature ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - public static Feature ParseDelimitedFrom(global::System.IO.Stream input) { - return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); - } - public static Feature ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); - } - public static Feature ParseFrom(pb::ICodedInputStream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static Feature ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - private Feature MakeReadOnly() { - return this; - } - - public static Builder CreateBuilder() { return new Builder(); } - public override Builder ToBuilder() { return CreateBuilder(this); } - public override Builder CreateBuilderForType() { return new Builder(); } - public static Builder CreateBuilder(Feature prototype) { - return new Builder(prototype); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Builder : pb::GeneratedBuilder { - protected override Builder ThisBuilder { - get { return this; } - } - public Builder() { - result = DefaultInstance; - resultIsReadOnly = true; - } - internal Builder(Feature cloneFrom) { - result = cloneFrom; - resultIsReadOnly = true; - } - - private bool resultIsReadOnly; - private Feature result; - - private Feature PrepareBuilder() { - if (resultIsReadOnly) { - Feature original = result; - result = new Feature(); - resultIsReadOnly = false; - MergeFrom(original); - } - return result; - } - - public override bool IsInitialized { - get { return result.IsInitialized; } - } - - protected override Feature MessageBeingBuilt { - get { return PrepareBuilder(); } - } - - public override Builder Clear() { - result = DefaultInstance; - resultIsReadOnly = true; - return this; - } - - public override Builder Clone() { - if (resultIsReadOnly) { - return new Builder(result); - } else { - return new Builder().MergeFrom(result); - } - } - - public override pbd::MessageDescriptor DescriptorForType { - get { return global::examples.Feature.Descriptor; } - } - - public override Feature DefaultInstanceForType { - get { return global::examples.Feature.DefaultInstance; } - } - - public override Feature BuildPartial() { - if (resultIsReadOnly) { - return result; - } - resultIsReadOnly = true; - return result.MakeReadOnly(); - } - - public override Builder MergeFrom(pb::IMessage other) { - if (other is Feature) { - return MergeFrom((Feature) other); - } else { - base.MergeFrom(other); - return this; - } - } - - public override Builder MergeFrom(Feature other) { - if (other == global::examples.Feature.DefaultInstance) return this; - PrepareBuilder(); - if (other.HasName) { - Name = other.Name; - } - if (other.HasLocation) { - MergeLocation(other.Location); - } - this.MergeUnknownFields(other.UnknownFields); - return this; - } - - public override Builder MergeFrom(pb::ICodedInputStream input) { - return MergeFrom(input, pb::ExtensionRegistry.Empty); - } - - public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - PrepareBuilder(); - pb::UnknownFieldSet.Builder unknownFields = null; - uint tag; - string field_name; - while (input.ReadTag(out tag, out field_name)) { - if(tag == 0 && field_name != null) { - int field_ordinal = global::System.Array.BinarySearch(_featureFieldNames, field_name, global::System.StringComparer.Ordinal); - if(field_ordinal >= 0) - tag = _featureFieldTags[field_ordinal]; - else { - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - continue; - } - } - switch (tag) { - case 0: { - throw pb::InvalidProtocolBufferException.InvalidTag(); - } - default: { - if (pb::WireFormat.IsEndGroupTag(tag)) { - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - break; - } - case 10: { - result.hasName = input.ReadString(ref result.name_); - break; - } - case 18: { - global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); - if (result.hasLocation) { - subBuilder.MergeFrom(Location); - } - input.ReadMessage(subBuilder, extensionRegistry); - Location = subBuilder.BuildPartial(); - break; - } - } - } - - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - - - public bool HasName { - get { return result.hasName; } - } - public string Name { - get { return result.Name; } - set { SetName(value); } - } - public Builder SetName(string value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasName = true; - result.name_ = value; - return this; - } - public Builder ClearName() { - PrepareBuilder(); - result.hasName = false; - result.name_ = ""; - return this; - } - - public bool HasLocation { - get { return result.hasLocation; } - } - public global::examples.Point Location { - get { return result.Location; } - set { SetLocation(value); } - } - public Builder SetLocation(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasLocation = true; - result.location_ = value; - return this; - } - public Builder SetLocation(global::examples.Point.Builder builderForValue) { - pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); - PrepareBuilder(); - result.hasLocation = true; - result.location_ = builderForValue.Build(); - return this; - } - public Builder MergeLocation(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - if (result.hasLocation && - result.location_ != global::examples.Point.DefaultInstance) { - result.location_ = global::examples.Point.CreateBuilder(result.location_).MergeFrom(value).BuildPartial(); - } else { - result.location_ = value; - } - result.hasLocation = true; - return this; - } - public Builder ClearLocation() { - PrepareBuilder(); - result.hasLocation = false; - result.location_ = null; - return this; - } - } - static Feature() { - object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class RouteNote : pb::GeneratedMessage { - private RouteNote() { } - private static readonly RouteNote defaultInstance = new RouteNote().MakeReadOnly(); - private static readonly string[] _routeNoteFieldNames = new string[] { "location", "message" }; - private static readonly uint[] _routeNoteFieldTags = new uint[] { 10, 18 }; - public static RouteNote DefaultInstance { - get { return defaultInstance; } - } - - public override RouteNote DefaultInstanceForType { - get { return DefaultInstance; } - } - - protected override RouteNote ThisMessage { - get { return this; } - } - - public static pbd::MessageDescriptor Descriptor { - get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteNote__Descriptor; } - } - - protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { - get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteNote__FieldAccessorTable; } - } - - public const int LocationFieldNumber = 1; - private bool hasLocation; - private global::examples.Point location_; - public bool HasLocation { - get { return hasLocation; } - } - public global::examples.Point Location { - get { return location_ ?? global::examples.Point.DefaultInstance; } - } - - public const int MessageFieldNumber = 2; - private bool hasMessage; - private string message_ = ""; - public bool HasMessage { - get { return hasMessage; } - } - public string Message { - get { return message_; } - } - - public override bool IsInitialized { - get { - return true; - } - } - - public override void WriteTo(pb::ICodedOutputStream output) { - CalcSerializedSize(); - string[] field_names = _routeNoteFieldNames; - if (hasLocation) { - output.WriteMessage(1, field_names[0], Location); - } - if (hasMessage) { - output.WriteString(2, field_names[1], Message); - } - UnknownFields.WriteTo(output); - } - - private int memoizedSerializedSize = -1; - public override int SerializedSize { - get { - int size = memoizedSerializedSize; - if (size != -1) return size; - return CalcSerializedSize(); - } - } - - private int CalcSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (hasLocation) { - size += pb::CodedOutputStream.ComputeMessageSize(1, Location); - } - if (hasMessage) { - size += pb::CodedOutputStream.ComputeStringSize(2, Message); - } - size += UnknownFields.SerializedSize; - memoizedSerializedSize = size; - return size; - } - public static RouteNote ParseFrom(pb::ByteString data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static RouteNote ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static RouteNote ParseFrom(byte[] data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static RouteNote ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static RouteNote ParseFrom(global::System.IO.Stream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static RouteNote ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - public static RouteNote ParseDelimitedFrom(global::System.IO.Stream input) { - return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); - } - public static RouteNote ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); - } - public static RouteNote ParseFrom(pb::ICodedInputStream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static RouteNote ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - private RouteNote MakeReadOnly() { - return this; - } - - public static Builder CreateBuilder() { return new Builder(); } - public override Builder ToBuilder() { return CreateBuilder(this); } - public override Builder CreateBuilderForType() { return new Builder(); } - public static Builder CreateBuilder(RouteNote prototype) { - return new Builder(prototype); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Builder : pb::GeneratedBuilder { - protected override Builder ThisBuilder { - get { return this; } - } - public Builder() { - result = DefaultInstance; - resultIsReadOnly = true; - } - internal Builder(RouteNote cloneFrom) { - result = cloneFrom; - resultIsReadOnly = true; - } - - private bool resultIsReadOnly; - private RouteNote result; - - private RouteNote PrepareBuilder() { - if (resultIsReadOnly) { - RouteNote original = result; - result = new RouteNote(); - resultIsReadOnly = false; - MergeFrom(original); - } - return result; - } - - public override bool IsInitialized { - get { return result.IsInitialized; } - } - - protected override RouteNote MessageBeingBuilt { - get { return PrepareBuilder(); } - } - - public override Builder Clear() { - result = DefaultInstance; - resultIsReadOnly = true; - return this; - } - - public override Builder Clone() { - if (resultIsReadOnly) { - return new Builder(result); - } else { - return new Builder().MergeFrom(result); - } - } - - public override pbd::MessageDescriptor DescriptorForType { - get { return global::examples.RouteNote.Descriptor; } - } - - public override RouteNote DefaultInstanceForType { - get { return global::examples.RouteNote.DefaultInstance; } - } - - public override RouteNote BuildPartial() { - if (resultIsReadOnly) { - return result; - } - resultIsReadOnly = true; - return result.MakeReadOnly(); - } - - public override Builder MergeFrom(pb::IMessage other) { - if (other is RouteNote) { - return MergeFrom((RouteNote) other); - } else { - base.MergeFrom(other); - return this; - } - } - - public override Builder MergeFrom(RouteNote other) { - if (other == global::examples.RouteNote.DefaultInstance) return this; - PrepareBuilder(); - if (other.HasLocation) { - MergeLocation(other.Location); - } - if (other.HasMessage) { - Message = other.Message; - } - this.MergeUnknownFields(other.UnknownFields); - return this; - } - - public override Builder MergeFrom(pb::ICodedInputStream input) { - return MergeFrom(input, pb::ExtensionRegistry.Empty); - } - - public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - PrepareBuilder(); - pb::UnknownFieldSet.Builder unknownFields = null; - uint tag; - string field_name; - while (input.ReadTag(out tag, out field_name)) { - if(tag == 0 && field_name != null) { - int field_ordinal = global::System.Array.BinarySearch(_routeNoteFieldNames, field_name, global::System.StringComparer.Ordinal); - if(field_ordinal >= 0) - tag = _routeNoteFieldTags[field_ordinal]; - else { - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - continue; - } - } - switch (tag) { - case 0: { - throw pb::InvalidProtocolBufferException.InvalidTag(); - } - default: { - if (pb::WireFormat.IsEndGroupTag(tag)) { - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - break; - } - case 10: { - global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); - if (result.hasLocation) { - subBuilder.MergeFrom(Location); - } - input.ReadMessage(subBuilder, extensionRegistry); - Location = subBuilder.BuildPartial(); - break; - } - case 18: { - result.hasMessage = input.ReadString(ref result.message_); - break; - } - } - } - - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - - - public bool HasLocation { - get { return result.hasLocation; } - } - public global::examples.Point Location { - get { return result.Location; } - set { SetLocation(value); } - } - public Builder SetLocation(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasLocation = true; - result.location_ = value; - return this; - } - public Builder SetLocation(global::examples.Point.Builder builderForValue) { - pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); - PrepareBuilder(); - result.hasLocation = true; - result.location_ = builderForValue.Build(); - return this; - } - public Builder MergeLocation(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - if (result.hasLocation && - result.location_ != global::examples.Point.DefaultInstance) { - result.location_ = global::examples.Point.CreateBuilder(result.location_).MergeFrom(value).BuildPartial(); - } else { - result.location_ = value; - } - result.hasLocation = true; - return this; - } - public Builder ClearLocation() { - PrepareBuilder(); - result.hasLocation = false; - result.location_ = null; - return this; - } - - public bool HasMessage { - get { return result.hasMessage; } - } - public string Message { - get { return result.Message; } - set { SetMessage(value); } - } - public Builder SetMessage(string value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasMessage = true; - result.message_ = value; - return this; - } - public Builder ClearMessage() { - PrepareBuilder(); - result.hasMessage = false; - result.message_ = ""; - return this; - } - } - static RouteNote() { - object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class RouteSummary : pb::GeneratedMessage { - private RouteSummary() { } - private static readonly RouteSummary defaultInstance = new RouteSummary().MakeReadOnly(); - private static readonly string[] _routeSummaryFieldNames = new string[] { "distance", "elapsed_time", "feature_count", "point_count" }; - private static readonly uint[] _routeSummaryFieldTags = new uint[] { 24, 32, 16, 8 }; - public static RouteSummary DefaultInstance { - get { return defaultInstance; } - } - - public override RouteSummary DefaultInstanceForType { - get { return DefaultInstance; } - } - - protected override RouteSummary ThisMessage { - get { return this; } - } - - public static pbd::MessageDescriptor Descriptor { - get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteSummary__Descriptor; } - } - - protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { - get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteSummary__FieldAccessorTable; } - } - - public const int PointCountFieldNumber = 1; - private bool hasPointCount; - private int pointCount_; - public bool HasPointCount { - get { return hasPointCount; } - } - public int PointCount { - get { return pointCount_; } - } - - public const int FeatureCountFieldNumber = 2; - private bool hasFeatureCount; - private int featureCount_; - public bool HasFeatureCount { - get { return hasFeatureCount; } - } - public int FeatureCount { - get { return featureCount_; } - } - - public const int DistanceFieldNumber = 3; - private bool hasDistance; - private int distance_; - public bool HasDistance { - get { return hasDistance; } - } - public int Distance { - get { return distance_; } - } - - public const int ElapsedTimeFieldNumber = 4; - private bool hasElapsedTime; - private int elapsedTime_; - public bool HasElapsedTime { - get { return hasElapsedTime; } - } - public int ElapsedTime { - get { return elapsedTime_; } - } - - public override bool IsInitialized { - get { - return true; - } - } - - public override void WriteTo(pb::ICodedOutputStream output) { - CalcSerializedSize(); - string[] field_names = _routeSummaryFieldNames; - if (hasPointCount) { - output.WriteInt32(1, field_names[3], PointCount); - } - if (hasFeatureCount) { - output.WriteInt32(2, field_names[2], FeatureCount); - } - if (hasDistance) { - output.WriteInt32(3, field_names[0], Distance); - } - if (hasElapsedTime) { - output.WriteInt32(4, field_names[1], ElapsedTime); - } - UnknownFields.WriteTo(output); - } - - private int memoizedSerializedSize = -1; - public override int SerializedSize { - get { - int size = memoizedSerializedSize; - if (size != -1) return size; - return CalcSerializedSize(); - } - } - - private int CalcSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (hasPointCount) { - size += pb::CodedOutputStream.ComputeInt32Size(1, PointCount); - } - if (hasFeatureCount) { - size += pb::CodedOutputStream.ComputeInt32Size(2, FeatureCount); - } - if (hasDistance) { - size += pb::CodedOutputStream.ComputeInt32Size(3, Distance); - } - if (hasElapsedTime) { - size += pb::CodedOutputStream.ComputeInt32Size(4, ElapsedTime); - } - size += UnknownFields.SerializedSize; - memoizedSerializedSize = size; - return size; - } - public static RouteSummary ParseFrom(pb::ByteString data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static RouteSummary ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static RouteSummary ParseFrom(byte[] data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static RouteSummary ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static RouteSummary ParseFrom(global::System.IO.Stream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static RouteSummary ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - public static RouteSummary ParseDelimitedFrom(global::System.IO.Stream input) { - return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); - } - public static RouteSummary ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); - } - public static RouteSummary ParseFrom(pb::ICodedInputStream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static RouteSummary ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - private RouteSummary MakeReadOnly() { - return this; - } - - public static Builder CreateBuilder() { return new Builder(); } - public override Builder ToBuilder() { return CreateBuilder(this); } - public override Builder CreateBuilderForType() { return new Builder(); } - public static Builder CreateBuilder(RouteSummary prototype) { - return new Builder(prototype); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Builder : pb::GeneratedBuilder { - protected override Builder ThisBuilder { - get { return this; } - } - public Builder() { - result = DefaultInstance; - resultIsReadOnly = true; - } - internal Builder(RouteSummary cloneFrom) { - result = cloneFrom; - resultIsReadOnly = true; - } - - private bool resultIsReadOnly; - private RouteSummary result; - - private RouteSummary PrepareBuilder() { - if (resultIsReadOnly) { - RouteSummary original = result; - result = new RouteSummary(); - resultIsReadOnly = false; - MergeFrom(original); - } - return result; - } - - public override bool IsInitialized { - get { return result.IsInitialized; } - } - - protected override RouteSummary MessageBeingBuilt { - get { return PrepareBuilder(); } - } - - public override Builder Clear() { - result = DefaultInstance; - resultIsReadOnly = true; - return this; - } - - public override Builder Clone() { - if (resultIsReadOnly) { - return new Builder(result); - } else { - return new Builder().MergeFrom(result); - } - } - - public override pbd::MessageDescriptor DescriptorForType { - get { return global::examples.RouteSummary.Descriptor; } - } - - public override RouteSummary DefaultInstanceForType { - get { return global::examples.RouteSummary.DefaultInstance; } - } - - public override RouteSummary BuildPartial() { - if (resultIsReadOnly) { - return result; - } - resultIsReadOnly = true; - return result.MakeReadOnly(); - } - - public override Builder MergeFrom(pb::IMessage other) { - if (other is RouteSummary) { - return MergeFrom((RouteSummary) other); - } else { - base.MergeFrom(other); - return this; - } - } - - public override Builder MergeFrom(RouteSummary other) { - if (other == global::examples.RouteSummary.DefaultInstance) return this; - PrepareBuilder(); - if (other.HasPointCount) { - PointCount = other.PointCount; - } - if (other.HasFeatureCount) { - FeatureCount = other.FeatureCount; - } - if (other.HasDistance) { - Distance = other.Distance; - } - if (other.HasElapsedTime) { - ElapsedTime = other.ElapsedTime; - } - this.MergeUnknownFields(other.UnknownFields); - return this; - } - - public override Builder MergeFrom(pb::ICodedInputStream input) { - return MergeFrom(input, pb::ExtensionRegistry.Empty); - } - - public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - PrepareBuilder(); - pb::UnknownFieldSet.Builder unknownFields = null; - uint tag; - string field_name; - while (input.ReadTag(out tag, out field_name)) { - if(tag == 0 && field_name != null) { - int field_ordinal = global::System.Array.BinarySearch(_routeSummaryFieldNames, field_name, global::System.StringComparer.Ordinal); - if(field_ordinal >= 0) - tag = _routeSummaryFieldTags[field_ordinal]; - else { - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - continue; - } - } - switch (tag) { - case 0: { - throw pb::InvalidProtocolBufferException.InvalidTag(); - } - default: { - if (pb::WireFormat.IsEndGroupTag(tag)) { - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - break; - } - case 8: { - result.hasPointCount = input.ReadInt32(ref result.pointCount_); - break; - } - case 16: { - result.hasFeatureCount = input.ReadInt32(ref result.featureCount_); - break; - } - case 24: { - result.hasDistance = input.ReadInt32(ref result.distance_); - break; - } - case 32: { - result.hasElapsedTime = input.ReadInt32(ref result.elapsedTime_); - break; - } - } - } - - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - - - public bool HasPointCount { - get { return result.hasPointCount; } - } - public int PointCount { - get { return result.PointCount; } - set { SetPointCount(value); } - } - public Builder SetPointCount(int value) { - PrepareBuilder(); - result.hasPointCount = true; - result.pointCount_ = value; - return this; - } - public Builder ClearPointCount() { - PrepareBuilder(); - result.hasPointCount = false; - result.pointCount_ = 0; - return this; - } - - public bool HasFeatureCount { - get { return result.hasFeatureCount; } - } - public int FeatureCount { - get { return result.FeatureCount; } - set { SetFeatureCount(value); } - } - public Builder SetFeatureCount(int value) { - PrepareBuilder(); - result.hasFeatureCount = true; - result.featureCount_ = value; - return this; - } - public Builder ClearFeatureCount() { - PrepareBuilder(); - result.hasFeatureCount = false; - result.featureCount_ = 0; - return this; - } - - public bool HasDistance { - get { return result.hasDistance; } - } - public int Distance { - get { return result.Distance; } - set { SetDistance(value); } - } - public Builder SetDistance(int value) { - PrepareBuilder(); - result.hasDistance = true; - result.distance_ = value; - return this; - } - public Builder ClearDistance() { - PrepareBuilder(); - result.hasDistance = false; - result.distance_ = 0; - return this; - } - - public bool HasElapsedTime { - get { return result.hasElapsedTime; } - } - public int ElapsedTime { - get { return result.ElapsedTime; } - set { SetElapsedTime(value); } - } - public Builder SetElapsedTime(int value) { - PrepareBuilder(); - result.hasElapsedTime = true; - result.elapsedTime_ = value; - return this; - } - public Builder ClearElapsedTime() { - PrepareBuilder(); - result.hasElapsedTime = false; - result.elapsedTime_ = 0; - return this; - } - } - static RouteSummary() { - object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); - } - } - - #endregion - -} - -#endregion Designer generated code diff --git a/csharp/route_guide/RouteGuide/RouteGuide.csproj b/csharp/route_guide/RouteGuide/RouteGuide.csproj deleted file mode 100644 index 8358974aac..0000000000 --- a/csharp/route_guide/RouteGuide/RouteGuide.csproj +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - Debug - AnyCPU - {49954D9C-5F17-4662-96B2-73BE833DD81A} - Library - Properties - RouteGuide - RouteGuide - v4.5 - 512 - 214cccda - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - - - False - ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll - - - False - ..\packages\Newtonsoft.Json.7.0.1-beta2\lib\net45\Newtonsoft.Json.dll - - - - False - ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - - - - ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll - - - - - - - - - - - - - - - - - - PreserveNewest - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - - \ No newline at end of file diff --git a/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs b/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs deleted file mode 100644 index c4b3900dca..0000000000 --- a/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs +++ /dev/null @@ -1,123 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: route_guide.proto -#region Designer generated code - -using System; -using System.Threading; -using System.Threading.Tasks; -using Grpc.Core; - -namespace examples { - public static class RouteGuide - { - static readonly string __ServiceName = "examples.RouteGuide"; - - static readonly Marshaller __Marshaller_Point = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.Point.ParseFrom); - static readonly Marshaller __Marshaller_Feature = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.Feature.ParseFrom); - static readonly Marshaller __Marshaller_Rectangle = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.Rectangle.ParseFrom); - static readonly Marshaller __Marshaller_RouteSummary = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.RouteSummary.ParseFrom); - static readonly Marshaller __Marshaller_RouteNote = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.RouteNote.ParseFrom); - - static readonly Method __Method_GetFeature = new Method( - MethodType.Unary, - "GetFeature", - __Marshaller_Point, - __Marshaller_Feature); - - static readonly Method __Method_ListFeatures = new Method( - MethodType.ServerStreaming, - "ListFeatures", - __Marshaller_Rectangle, - __Marshaller_Feature); - - static readonly Method __Method_RecordRoute = new Method( - MethodType.ClientStreaming, - "RecordRoute", - __Marshaller_Point, - __Marshaller_RouteSummary); - - static readonly Method __Method_RouteChat = new Method( - MethodType.DuplexStreaming, - "RouteChat", - __Marshaller_RouteNote, - __Marshaller_RouteNote); - - // client-side stub interface - public interface IRouteGuideClient - { - global::examples.Feature GetFeature(global::examples.Point request, CancellationToken token = default(CancellationToken)); - Task GetFeatureAsync(global::examples.Point request, CancellationToken token = default(CancellationToken)); - AsyncServerStreamingCall ListFeatures(global::examples.Rectangle request, CancellationToken token = default(CancellationToken)); - AsyncClientStreamingCall RecordRoute(CancellationToken token = default(CancellationToken)); - AsyncDuplexStreamingCall RouteChat(CancellationToken token = default(CancellationToken)); - } - - // server-side interface - public interface IRouteGuide - { - Task GetFeature(ServerCallContext context, global::examples.Point request); - Task ListFeatures(ServerCallContext context, global::examples.Rectangle request, IServerStreamWriter responseStream); - Task RecordRoute(ServerCallContext context, IAsyncStreamReader requestStream); - Task RouteChat(ServerCallContext context, IAsyncStreamReader requestStream, IServerStreamWriter responseStream); - } - - // client stub - public class RouteGuideClient : AbstractStub, IRouteGuideClient - { - public RouteGuideClient(Channel channel) : this(channel, StubConfiguration.Default) - { - } - public RouteGuideClient(Channel channel, StubConfiguration config) : base(channel, config) - { - } - public global::examples.Feature GetFeature(global::examples.Point request, CancellationToken token = default(CancellationToken)) - { - var call = CreateCall(__ServiceName, __Method_GetFeature); - return Calls.BlockingUnaryCall(call, request, token); - } - public Task GetFeatureAsync(global::examples.Point request, CancellationToken token = default(CancellationToken)) - { - var call = CreateCall(__ServiceName, __Method_GetFeature); - return Calls.AsyncUnaryCall(call, request, token); - } - public AsyncServerStreamingCall ListFeatures(global::examples.Rectangle request, CancellationToken token = default(CancellationToken)) - { - var call = CreateCall(__ServiceName, __Method_ListFeatures); - return Calls.AsyncServerStreamingCall(call, request, token); - } - public AsyncClientStreamingCall RecordRoute(CancellationToken token = default(CancellationToken)) - { - var call = CreateCall(__ServiceName, __Method_RecordRoute); - return Calls.AsyncClientStreamingCall(call, token); - } - public AsyncDuplexStreamingCall RouteChat(CancellationToken token = default(CancellationToken)) - { - var call = CreateCall(__ServiceName, __Method_RouteChat); - return Calls.AsyncDuplexStreamingCall(call, token); - } - } - - // creates service definition that can be registered with a server - public static ServerServiceDefinition BindService(IRouteGuide serviceImpl) - { - return ServerServiceDefinition.CreateBuilder(__ServiceName) - .AddMethod(__Method_GetFeature, serviceImpl.GetFeature) - .AddMethod(__Method_ListFeatures, serviceImpl.ListFeatures) - .AddMethod(__Method_RecordRoute, serviceImpl.RecordRoute) - .AddMethod(__Method_RouteChat, serviceImpl.RouteChat).Build(); - } - - // creates a new client stub - public static IRouteGuideClient NewStub(Channel channel) - { - return new RouteGuideClient(channel); - } - - // creates a new client stub - public static IRouteGuideClient NewStub(Channel channel, StubConfiguration config) - { - return new RouteGuideClient(channel, config); - } - } -} -#endregion diff --git a/csharp/route_guide/RouteGuide/RouteGuideUtil.cs b/csharp/route_guide/RouteGuide/RouteGuideUtil.cs deleted file mode 100644 index 6fb8b1e28a..0000000000 --- a/csharp/route_guide/RouteGuide/RouteGuideUtil.cs +++ /dev/null @@ -1,67 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace examples -{ - public static class RouteGuideUtil - { - public const string DefaultFeaturesFile = "route_guide_db.json"; - - private const double CoordFactor = 1e7; - - /// - /// Indicates whether the given feature exists (i.e. has a valid name). - /// - public static bool Exists(Feature feature) - { - return feature != null && (feature.Name.Length != 0); - } - - public static double GetLatitude(Point point) - { - return point.Latitude / CoordFactor; - } - - public static double GetLongitude(Point point) - { - return point.Longitude / CoordFactor; - } - - /// - /// Parses features from a JSON file. - /// - public static List ParseFeatures(string filename) - { - var features = new List(); - var jsonFeatures = JsonConvert.DeserializeObject>(File.ReadAllText(filename)); - - - foreach(var jsonFeature in jsonFeatures) - { - features.Add(Feature.CreateBuilder().SetName(jsonFeature.name).SetLocation( - Point.CreateBuilder() - .SetLongitude(jsonFeature.location.longitude) - .SetLatitude(jsonFeature.location.latitude).Build()).Build()); - } - return features; - } - - private class JsonFeature - { - public string name; - public JsonLocation location; - } - - private class JsonLocation - { - public int longitude; - public int latitude; - } - } -} diff --git a/csharp/route_guide/RouteGuide/packages.config b/csharp/route_guide/RouteGuide/packages.config deleted file mode 100644 index 79abe0aa65..0000000000 --- a/csharp/route_guide/RouteGuide/packages.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/csharp/route_guide/RouteGuide/protos/route_guide.proto b/csharp/route_guide/RouteGuide/protos/route_guide.proto deleted file mode 100644 index f4110b5515..0000000000 --- a/csharp/route_guide/RouteGuide/protos/route_guide.proto +++ /dev/null @@ -1,123 +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. - -// TODO(jtattermusch): as of now, C# protobufs don't officially support -// proto3. -syntax = "proto2"; - -package examples; - -// Interface exported by the server. -service RouteGuide { - // A simple RPC. - // - // Obtains the feature at a given position. - // - // A feature with an empty name is returned if there's no feature at the given - // position. - rpc GetFeature(Point) returns (Feature) {} - - // A server-to-client streaming RPC. - // - // Obtains the Features available within the given Rectangle. Results are - // streamed rather than returned at once (e.g. in a response message with a - // repeated field), as the rectangle may cover a large area and contain a - // huge number of features. - rpc ListFeatures(Rectangle) returns (stream Feature) {} - - // A client-to-server streaming RPC. - // - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} - - // A Bidirectional streaming RPC. - // - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -} - -// Points are represented as latitude-longitude pairs in the E7 representation -// (degrees multiplied by 10**7 and rounded to the nearest integer). -// Latitudes should be in the range +/- 90 degrees and longitude should be in -// the range +/- 180 degrees (inclusive). -message Point { - optional int32 latitude = 1; - optional int32 longitude = 2; -} - -// A latitude-longitude rectangle, represented as two diagonally opposite -// points "lo" and "hi". -message Rectangle { - // One corner of the rectangle. - optional Point lo = 1; - - // The other corner of the rectangle. - optional Point hi = 2; -} - -// A feature names something at a given point. -// -// If a feature could not be named, the name is empty. -message Feature { - // The name of the feature. - optional string name = 1; - - // The point where the feature is detected. - optional Point location = 2; -} - -// A RouteNote is a message sent while at a given point. -message RouteNote { - // The location from which the message is sent. - optional Point location = 1; - - // The message to be sent. - optional string message = 2; -} - -// A RouteSummary is received in response to a RecordRoute rpc. -// -// It contains the number of individual points received, the number of -// detected features, and the total distance covered as the cumulative sum of -// the distance between each point. -message RouteSummary { - // The number of points received. - optional int32 point_count = 1; - - // The number of known features passed while traversing the route. - optional int32 feature_count = 2; - - // The distance covered in metres. - optional int32 distance = 3; - - // The duration of the traversal in seconds. - optional int32 elapsed_time = 4; -} diff --git a/csharp/route_guide/RouteGuide/route_guide_db.json b/csharp/route_guide/RouteGuide/route_guide_db.json deleted file mode 100644 index 209f016259..0000000000 --- a/csharp/route_guide/RouteGuide/route_guide_db.json +++ /dev/null @@ -1,601 +0,0 @@ -[{ - "location": { - "latitude": 407838351, - "longitude": -746143763 - }, - "name": "Patriots Path, Mendham, NJ 07945, USA" -}, { - "location": { - "latitude": 408122808, - "longitude": -743999179 - }, - "name": "101 New Jersey 10, Whippany, NJ 07981, USA" -}, { - "location": { - "latitude": 413628156, - "longitude": -749015468 - }, - "name": "U.S. 6, Shohola, PA 18458, USA" -}, { - "location": { - "latitude": 419999544, - "longitude": -740371136 - }, - "name": "5 Conners Road, Kingston, NY 12401, USA" -}, { - "location": { - "latitude": 414008389, - "longitude": -743951297 - }, - "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" -}, { - "location": { - "latitude": 419611318, - "longitude": -746524769 - }, - "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" -}, { - "location": { - "latitude": 406109563, - "longitude": -742186778 - }, - "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" -}, { - "location": { - "latitude": 416802456, - "longitude": -742370183 - }, - "name": "352 South Mountain Road, Wallkill, NY 12589, USA" -}, { - "location": { - "latitude": 412950425, - "longitude": -741077389 - }, - "name": "Bailey Turn Road, Harriman, NY 10926, USA" -}, { - "location": { - "latitude": 412144655, - "longitude": -743949739 - }, - "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" -}, { - "location": { - "latitude": 415736605, - "longitude": -742847522 - }, - "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" -}, { - "location": { - "latitude": 413843930, - "longitude": -740501726 - }, - "name": "162 Merrill Road, Highland Mills, NY 10930, USA" -}, { - "location": { - "latitude": 410873075, - "longitude": -744459023 - }, - "name": "Clinton Road, West Milford, NJ 07480, USA" -}, { - "location": { - "latitude": 412346009, - "longitude": -744026814 - }, - "name": "16 Old Brook Lane, Warwick, NY 10990, USA" -}, { - "location": { - "latitude": 402948455, - "longitude": -747903913 - }, - "name": "3 Drake Lane, Pennington, NJ 08534, USA" -}, { - "location": { - "latitude": 406337092, - "longitude": -740122226 - }, - "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" -}, { - "location": { - "latitude": 406421967, - "longitude": -747727624 - }, - "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" -}, { - "location": { - "latitude": 416318082, - "longitude": -749677716 - }, - "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" -}, { - "location": { - "latitude": 415301720, - "longitude": -748416257 - }, - "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" -}, { - "location": { - "latitude": 402647019, - "longitude": -747071791 - }, - "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" -}, { - "location": { - "latitude": 412567807, - "longitude": -741058078 - }, - "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" -}, { - "location": { - "latitude": 416855156, - "longitude": -744420597 - }, - "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" -}, { - "location": { - "latitude": 404663628, - "longitude": -744820157 - }, - "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" -}, { - "location": { - "latitude": 407113723, - "longitude": -749746483 - }, - "name": "" -}, { - "location": { - "latitude": 402133926, - "longitude": -743613249 - }, - "name": "" -}, { - "location": { - "latitude": 400273442, - "longitude": -741220915 - }, - "name": "" -}, { - "location": { - "latitude": 411236786, - "longitude": -744070769 - }, - "name": "" -}, { - "location": { - "latitude": 411633782, - "longitude": -746784970 - }, - "name": "211-225 Plains Road, Augusta, NJ 07822, USA" -}, { - "location": { - "latitude": 415830701, - "longitude": -742952812 - }, - "name": "" -}, { - "location": { - "latitude": 413447164, - "longitude": -748712898 - }, - "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" -}, { - "location": { - "latitude": 405047245, - "longitude": -749800722 - }, - "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" -}, { - "location": { - "latitude": 418858923, - "longitude": -746156790 - }, - "name": "" -}, { - "location": { - "latitude": 417951888, - "longitude": -748484944 - }, - "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" -}, { - "location": { - "latitude": 407033786, - "longitude": -743977337 - }, - "name": "26 East 3rd Street, New Providence, NJ 07974, USA" -}, { - "location": { - "latitude": 417548014, - "longitude": -740075041 - }, - "name": "" -}, { - "location": { - "latitude": 410395868, - "longitude": -744972325 - }, - "name": "" -}, { - "location": { - "latitude": 404615353, - "longitude": -745129803 - }, - "name": "" -}, { - "location": { - "latitude": 406589790, - "longitude": -743560121 - }, - "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" -}, { - "location": { - "latitude": 414653148, - "longitude": -740477477 - }, - "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" -}, { - "location": { - "latitude": 405957808, - "longitude": -743255336 - }, - "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" -}, { - "location": { - "latitude": 411733589, - "longitude": -741648093 - }, - "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" -}, { - "location": { - "latitude": 412676291, - "longitude": -742606606 - }, - "name": "1270 Lakes Road, Monroe, NY 10950, USA" -}, { - "location": { - "latitude": 409224445, - "longitude": -748286738 - }, - "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" -}, { - "location": { - "latitude": 406523420, - "longitude": -742135517 - }, - "name": "652 Garden Street, Elizabeth, NJ 07202, USA" -}, { - "location": { - "latitude": 401827388, - "longitude": -740294537 - }, - "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" -}, { - "location": { - "latitude": 410564152, - "longitude": -743685054 - }, - "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" -}, { - "location": { - "latitude": 408472324, - "longitude": -740726046 - }, - "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" -}, { - "location": { - "latitude": 412452168, - "longitude": -740214052 - }, - "name": "5 White Oak Lane, Stony Point, NY 10980, USA" -}, { - "location": { - "latitude": 409146138, - "longitude": -746188906 - }, - "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" -}, { - "location": { - "latitude": 404701380, - "longitude": -744781745 - }, - "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" -}, { - "location": { - "latitude": 409642566, - "longitude": -746017679 - }, - "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" -}, { - "location": { - "latitude": 408031728, - "longitude": -748645385 - }, - "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" -}, { - "location": { - "latitude": 413700272, - "longitude": -742135189 - }, - "name": "367 Prospect Road, Chester, NY 10918, USA" -}, { - "location": { - "latitude": 404310607, - "longitude": -740282632 - }, - "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" -}, { - "location": { - "latitude": 409319800, - "longitude": -746201391 - }, - "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" -}, { - "location": { - "latitude": 406685311, - "longitude": -742108603 - }, - "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" -}, { - "location": { - "latitude": 419018117, - "longitude": -749142781 - }, - "name": "43 Dreher Road, Roscoe, NY 12776, USA" -}, { - "location": { - "latitude": 412856162, - "longitude": -745148837 - }, - "name": "Swan Street, Pine Island, NY 10969, USA" -}, { - "location": { - "latitude": 416560744, - "longitude": -746721964 - }, - "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" -}, { - "location": { - "latitude": 405314270, - "longitude": -749836354 - }, - "name": "" -}, { - "location": { - "latitude": 414219548, - "longitude": -743327440 - }, - "name": "" -}, { - "location": { - "latitude": 415534177, - "longitude": -742900616 - }, - "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" -}, { - "location": { - "latitude": 406898530, - "longitude": -749127080 - }, - "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" -}, { - "location": { - "latitude": 407586880, - "longitude": -741670168 - }, - "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" -}, { - "location": { - "latitude": 400106455, - "longitude": -742870190 - }, - "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" -}, { - "location": { - "latitude": 400066188, - "longitude": -746793294 - }, - "name": "" -}, { - "location": { - "latitude": 418803880, - "longitude": -744102673 - }, - "name": "40 Mountain Road, Napanoch, NY 12458, USA" -}, { - "location": { - "latitude": 414204288, - "longitude": -747895140 - }, - "name": "" -}, { - "location": { - "latitude": 414777405, - "longitude": -740615601 - }, - "name": "" -}, { - "location": { - "latitude": 415464475, - "longitude": -747175374 - }, - "name": "48 North Road, Forestburgh, NY 12777, USA" -}, { - "location": { - "latitude": 404062378, - "longitude": -746376177 - }, - "name": "" -}, { - "location": { - "latitude": 405688272, - "longitude": -749285130 - }, - "name": "" -}, { - "location": { - "latitude": 400342070, - "longitude": -748788996 - }, - "name": "" -}, { - "location": { - "latitude": 401809022, - "longitude": -744157964 - }, - "name": "" -}, { - "location": { - "latitude": 404226644, - "longitude": -740517141 - }, - "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" -}, { - "location": { - "latitude": 410322033, - "longitude": -747871659 - }, - "name": "" -}, { - "location": { - "latitude": 407100674, - "longitude": -747742727 - }, - "name": "" -}, { - "location": { - "latitude": 418811433, - "longitude": -741718005 - }, - "name": "213 Bush Road, Stone Ridge, NY 12484, USA" -}, { - "location": { - "latitude": 415034302, - "longitude": -743850945 - }, - "name": "" -}, { - "location": { - "latitude": 411349992, - "longitude": -743694161 - }, - "name": "" -}, { - "location": { - "latitude": 404839914, - "longitude": -744759616 - }, - "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" -}, { - "location": { - "latitude": 414638017, - "longitude": -745957854 - }, - "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" -}, { - "location": { - "latitude": 412127800, - "longitude": -740173578 - }, - "name": "" -}, { - "location": { - "latitude": 401263460, - "longitude": -747964303 - }, - "name": "" -}, { - "location": { - "latitude": 412843391, - "longitude": -749086026 - }, - "name": "" -}, { - "location": { - "latitude": 418512773, - "longitude": -743067823 - }, - "name": "" -}, { - "location": { - "latitude": 404318328, - "longitude": -740835638 - }, - "name": "42-102 Main Street, Belford, NJ 07718, USA" -}, { - "location": { - "latitude": 419020746, - "longitude": -741172328 - }, - "name": "" -}, { - "location": { - "latitude": 404080723, - "longitude": -746119569 - }, - "name": "" -}, { - "location": { - "latitude": 401012643, - "longitude": -744035134 - }, - "name": "" -}, { - "location": { - "latitude": 404306372, - "longitude": -741079661 - }, - "name": "" -}, { - "location": { - "latitude": 403966326, - "longitude": -748519297 - }, - "name": "" -}, { - "location": { - "latitude": 405002031, - "longitude": -748407866 - }, - "name": "" -}, { - "location": { - "latitude": 409532885, - "longitude": -742200683 - }, - "name": "" -}, { - "location": { - "latitude": 416851321, - "longitude": -742674555 - }, - "name": "" -}, { - "location": { - "latitude": 406411633, - "longitude": -741722051 - }, - "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" -}, { - "location": { - "latitude": 413069058, - "longitude": -744597778 - }, - "name": "261 Van Sickle Road, Goshen, NY 10924, USA" -}, { - "location": { - "latitude": 418465462, - "longitude": -746859398 - }, - "name": "" -}, { - "location": { - "latitude": 411733222, - "longitude": -744228360 - }, - "name": "" -}, { - "location": { - "latitude": 410248224, - "longitude": -747127767 - }, - "name": "3 Hasta Way, Newton, NJ 07860, USA" -}] \ No newline at end of file diff --git a/csharp/route_guide/RouteGuideClient/App.config b/csharp/route_guide/RouteGuideClient/App.config deleted file mode 100644 index 8e15646352..0000000000 --- a/csharp/route_guide/RouteGuideClient/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/csharp/route_guide/RouteGuideClient/Program.cs b/csharp/route_guide/RouteGuideClient/Program.cs deleted file mode 100644 index 0352c78020..0000000000 --- a/csharp/route_guide/RouteGuideClient/Program.cs +++ /dev/null @@ -1,223 +0,0 @@ -using Grpc.Core; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace examples -{ - class Program - { - /// - /// Sample client code that makes gRPC calls to the server. - /// - public class RouteGuideClient - { - readonly RouteGuide.IRouteGuideClient client; - - public RouteGuideClient(RouteGuide.IRouteGuideClient client) - { - this.client = client; - } - - /// - /// Blocking unary call example. Calls GetFeature and prints the response. - /// - public void GetFeature(int lat, int lon) - { - try - { - Log("*** GetFeature: lat={0} lon={1}", lat, lon); - - Point request = Point.CreateBuilder().SetLatitude(lat).SetLongitude(lon).Build(); - - Feature feature = client.GetFeature(request); - if (RouteGuideUtil.Exists(feature)) - { - Log("Found feature called \"{0}\" at {1}, {2}", - feature.Name, - RouteGuideUtil.GetLatitude(feature.Location), - RouteGuideUtil.GetLongitude(feature.Location)); - } - else - { - Log("Found no feature at {0}, {1}", - RouteGuideUtil.GetLatitude(feature.Location), - RouteGuideUtil.GetLongitude(feature.Location)); - } - } - catch (RpcException e) - { - Log("RPC failed " + e); - throw e; - } - } - - - /// - /// Server-streaming example. Calls listFeatures with a rectangle of interest. Prints each response feature as it arrives. - /// - public async Task ListFeatures(int lowLat, int lowLon, int hiLat, int hiLon) - { - try - { - Log("*** ListFeatures: lowLat={0} lowLon={1} hiLat={2} hiLon={3}", lowLat, lowLon, hiLat, - hiLon); - - Rectangle request = - Rectangle.CreateBuilder() - .SetLo(Point.CreateBuilder().SetLatitude(lowLat).SetLongitude(lowLon).Build()) - .SetHi(Point.CreateBuilder().SetLatitude(hiLat).SetLongitude(hiLon).Build()).Build(); - - using (var call = client.ListFeatures(request)) - { - StringBuilder responseLog = new StringBuilder("Result: "); - - while (await call.ResponseStream.MoveNext()) - { - Feature feature = call.ResponseStream.Current; - responseLog.Append(feature.ToString()); - } - Log(responseLog.ToString()); - } - } - catch (RpcException e) - { - Log("RPC failed " + e); - throw e; - } - } - - /// - /// Client-streaming example. Sends numPoints randomly chosen points from features - /// with a variable delay in between. Prints the statistics when they are sent from the server. - /// - public async Task RecordRoute(List features, int numPoints) - { - try - { - Log("*** RecordRoute"); - using (var call = client.RecordRoute()) - { - // Send numPoints points randomly selected from the features list. - StringBuilder numMsg = new StringBuilder(); - Random rand = new Random(); - for (int i = 0; i < numPoints; ++i) - { - int index = rand.Next(features.Count); - Point point = features[index].Location; - Log("Visiting point {0}, {1}", RouteGuideUtil.GetLatitude(point), - RouteGuideUtil.GetLongitude(point)); - - await call.RequestStream.WriteAsync(point); - - // A bit of delay before sending the next one. - await Task.Delay(rand.Next(1000) + 500); - } - await call.RequestStream.CompleteAsync(); - - RouteSummary summary = await call.Result; - Log("Finished trip with {0} points. Passed {1} features. " - + "Travelled {2} meters. It took {3} seconds.", summary.PointCount, - summary.FeatureCount, summary.Distance, summary.ElapsedTime); - - Log("Finished RecordRoute"); - } - } - catch (RpcException e) - { - Log("RPC failed", e); - throw e; - } - } - - /// - /// Bi-directional streaming example. Send some chat messages, and print any - /// chat messages that are sent from the server. - /// - public async Task RouteChat() - { - try - { - Log("*** RouteChat"); - var requests = - new List { NewNote("First message", 0, 0), NewNote("Second message", 0, 1), NewNote("Third message", 1, 0), NewNote("Fourth message", 1, 1) }; - - using (var call = client.RouteChat()) - { - var responseReaderTask = Task.Run(async () => - { - while (await call.ResponseStream.MoveNext()) - { - var note = call.ResponseStream.Current; - Log("Got message \"{0}\" at {1}, {2}", note.Message, - note.Location.Latitude, note.Location.Longitude); - } - }); - - foreach (RouteNote request in requests) - { - Log("Sending message \"{0}\" at {1}, {2}", request.Message, - request.Location.Latitude, request.Location.Longitude); - - await call.RequestStream.WriteAsync(request); - } - await call.RequestStream.CompleteAsync(); - await responseReaderTask; - - Log("Finished RouteChat"); - } - } - catch (RpcException e) - { - Log("RPC failed", e); - throw e; - } - } - - private void Log(string s, params object[] args) - { - Console.WriteLine(string.Format(s, args)); - } - - private void Log(string s) - { - Console.WriteLine(s); - } - - private RouteNote NewNote(string message, int lat, int lon) - { - return RouteNote.CreateBuilder().SetMessage(message).SetLocation( - Point.CreateBuilder().SetLatitude(lat).SetLongitude(lat).Build()).Build(); - } - } - - static void Main(string[] args) - { - GrpcEnvironment.Initialize(); - - using (Channel channel = new Channel("127.0.0.1:50052")) - { - var client = new RouteGuideClient(RouteGuide.NewStub(channel)); - - // Looking for a valid feature - client.GetFeature(409146138, -746188906); - - // Feature missing. - client.GetFeature(0, 0); - - // Looking for features between 40, -75 and 42, -73. - client.ListFeatures(400000000, -750000000, 420000000, -730000000).Wait(); - - // Record a few randomly selected points from the features file. - client.RecordRoute(RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile), 10).Wait(); - - // Send and receive some notes. - client.RouteChat().Wait(); - } - - GrpcEnvironment.Shutdown(); - } - } -} diff --git a/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs b/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs deleted file mode 100644 index a17e164a78..0000000000 --- a/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("RouteGuideClient")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("RouteGuideClient")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("914644eb-47cd-4a37-9fba-5e62dd432333")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj b/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj deleted file mode 100644 index 78034a9145..0000000000 --- a/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - Debug - AnyCPU - {D47BE663-4DE3-4206-B7A8-EA3FA066DADC} - Exe - Properties - RouteGuideClient - RouteGuideClient - v4.5 - 512 - 794416d0 - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - - - False - ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll - - - - False - ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - - - - ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll - - - - - - - - - - - - - - - - - - {49954d9c-5f17-4662-96b2-73be833dd81a} - RouteGuide - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - - \ No newline at end of file diff --git a/csharp/route_guide/RouteGuideClient/packages.config b/csharp/route_guide/RouteGuideClient/packages.config deleted file mode 100644 index 5922553bc3..0000000000 --- a/csharp/route_guide/RouteGuideClient/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/csharp/route_guide/RouteGuideServer/App.config b/csharp/route_guide/RouteGuideServer/App.config deleted file mode 100644 index 8e15646352..0000000000 --- a/csharp/route_guide/RouteGuideServer/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/csharp/route_guide/RouteGuideServer/Program.cs b/csharp/route_guide/RouteGuideServer/Program.cs deleted file mode 100644 index e00b4d6723..0000000000 --- a/csharp/route_guide/RouteGuideServer/Program.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Grpc.Core; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace examples -{ - class Program - { - static void Main(string[] args) - { - var features = RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile); - GrpcEnvironment.Initialize(); - - Server server = new Server(); - server.AddServiceDefinition(RouteGuide.BindService(new RouteGuideImpl(features))); - int port = server.AddListeningPort("localhost", 50052); - server.Start(); - - Console.WriteLine("RouteGuide server listening on port " + port); - Console.WriteLine("Press any key to stop the server..."); - Console.ReadKey(); - - server.ShutdownAsync().Wait(); - GrpcEnvironment.Shutdown(); - } - } -} diff --git a/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs b/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs deleted file mode 100644 index a161b1d602..0000000000 --- a/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("RouteGuideServer")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("RouteGuideServer")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("908bdeef-05cc-42bf-9498-c4c573df8925")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs b/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs deleted file mode 100644 index 0bdf386fc3..0000000000 --- a/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs +++ /dev/null @@ -1,184 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace examples -{ - /// - /// Example implementation of RouteGuide server. - /// - public class RouteGuideImpl : RouteGuide.IRouteGuide - { - readonly List features; - private readonly ConcurrentDictionary> routeNotes = - new ConcurrentDictionary>(); - - public RouteGuideImpl(List features) - { - this.features = features; - } - - /// - /// Gets the feature at the requested point. If no feature at that location - /// exists, an unnammed feature is returned at the provided location. - /// - public Task GetFeature(Grpc.Core.ServerCallContext context, Point request) - { - return Task.FromResult(CheckFeature(request)); - } - - /// - /// Gets all features contained within the given bounding rectangle. - /// - public async Task ListFeatures(Grpc.Core.ServerCallContext context, Rectangle request, Grpc.Core.IServerStreamWriter responseStream) - { - int left = Math.Min(request.Lo.Longitude, request.Hi.Longitude); - int right = Math.Max(request.Lo.Longitude, request.Hi.Longitude); - int top = Math.Max(request.Lo.Latitude, request.Hi.Latitude); - int bottom = Math.Min(request.Lo.Latitude, request.Hi.Latitude); - - foreach (var feature in features) - { - if (!RouteGuideUtil.Exists(feature)) - { - continue; - } - - int lat = feature.Location.Latitude; - int lon = feature.Location.Longitude; - if (lon >= left && lon <= right && lat >= bottom && lat <= top) - { - await responseStream.WriteAsync(feature); - } - } - } - - /// - /// Gets a stream of points, and responds with statistics about the "trip": number of points, - /// number of known features visited, total distance traveled, and total time spent. - /// - public async Task RecordRoute(Grpc.Core.ServerCallContext context, Grpc.Core.IAsyncStreamReader requestStream) - { - int pointCount = 0; - int featureCount = 0; - int distance = 0; - Point previous = null; - var stopwatch = new Stopwatch(); - stopwatch.Start(); - - while (await requestStream.MoveNext()) - { - var point = requestStream.Current; - pointCount++; - if (RouteGuideUtil.Exists(CheckFeature(point))) - { - featureCount++; - } - if (previous != null) - { - distance += (int) CalcDistance(previous, point); - } - previous = point; - } - - stopwatch.Stop(); - return RouteSummary.CreateBuilder().SetPointCount(pointCount) - .SetFeatureCount(featureCount).SetDistance(distance) - .SetElapsedTime((int) (stopwatch.ElapsedMilliseconds / 1000)).Build(); - } - - /// - /// Receives a stream of message/location pairs, and responds with a stream of all previous - /// messages at each of those locations. - /// - public async Task RouteChat(Grpc.Core.ServerCallContext context, Grpc.Core.IAsyncStreamReader requestStream, Grpc.Core.IServerStreamWriter responseStream) - { - while (await requestStream.MoveNext()) - { - var note = requestStream.Current; - List notes = GetOrCreateNotes(note.Location); - - List prevNotes; - lock (notes) - { - prevNotes = new List(notes); - } - - foreach (var prevNote in prevNotes) - { - await responseStream.WriteAsync(prevNote); - } - - lock (notes) - { - notes.Add(note); - } - } - } - - - /// - /// Get the notes list for the given location. If missing, create it. - /// - private List GetOrCreateNotes(Point location) - { - List notes = new List(); - routeNotes.TryAdd(location, notes); - return routeNotes[location]; - } - - /// - /// Gets the feature at the given point. - /// - /// the location to check - /// The feature object at the point Note that an empty name indicates no feature. - private Feature CheckFeature(Point location) - { - foreach (var feature in features) - { - if (feature.Location.Latitude == location.Latitude - && feature.Location.Longitude == location.Longitude) - { - return feature; - } - } - - // No feature was found, return an unnamed feature. - return Feature.CreateBuilder().SetName("").SetLocation(location).Build(); - } - - /// - /// Calculate the distance between two points using the "haversine" formula. - /// This code was taken from http://www.movable-type.co.uk/scripts/latlong.html. - /// - /// the starting point - /// the end point - /// the distance between the points in meters - private static double CalcDistance(Point start, Point end) - { - double lat1 = RouteGuideUtil.GetLatitude(start); - double lat2 = RouteGuideUtil.GetLatitude(end); - double lon1 = RouteGuideUtil.GetLongitude(start); - double lon2 = RouteGuideUtil.GetLongitude(end); - int r = 6371000; // metres - double φ1 = ToRadians(lat1); - double φ2 = ToRadians(lat2); - double Δφ = ToRadians(lat2 - lat1); - double Δλ = ToRadians(lon2 - lon1); - - double a = Math.Sin(Δφ / 2) * Math.Sin(Δφ / 2) + Math.Cos(φ1) * Math.Cos(φ2) * Math.Sin(Δλ / 2) * Math.Sin(Δλ / 2); - double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); - - return r * c; - } - - private static double ToRadians(double val) - { - return (Math.PI / 180) * val; - } - } -} diff --git a/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj b/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj deleted file mode 100644 index 9ac1cfbf4d..0000000000 --- a/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - Debug - AnyCPU - {4B7C7794-BE24-4477-ACE7-18259EB73D27} - Exe - Properties - RouteGuideServer - RouteGuideServer - v4.5 - 512 - 74781d8b - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - - - False - ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll - - - - False - ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - - - - ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll - - - - - - - - - - - - - - - - - - - {49954d9c-5f17-4662-96b2-73be833dd81a} - RouteGuide - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - - \ No newline at end of file diff --git a/csharp/route_guide/RouteGuideServer/packages.config b/csharp/route_guide/RouteGuideServer/packages.config deleted file mode 100644 index 5922553bc3..0000000000 --- a/csharp/route_guide/RouteGuideServer/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/go/README.md b/go/README.md deleted file mode 100644 index 79db479ec5..0000000000 --- a/go/README.md +++ /dev/null @@ -1,53 +0,0 @@ -gRPC in 3 minutes (Go) -====================== - -BACKGROUND -------------- -For this sample, we've already generated the server and client stubs from [helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). - -PREREQUISITES -------------- - -- This requires Go 1.4 -- Requires that [GOPATH is set](https://golang.org/doc/code.html#GOPATH) -```sh -$ go help gopath -$ # ensure the PATH contains $GOPATH/bin -$ export PATH=$PATH:$GOPATH/bin -``` - -INSTALL -------- - -```sh -$ go get -u github.com/grpc/grpc-common/go/greeter_client -$ go get -u github.com/grpc/grpc-common/go/greeter_server -``` - -TRY IT! -------- - -- Run the server -```sh -$ greeter_server & -``` - -- Run the client -```sh -$ greeter_client -``` - -OPTIONAL - Rebuilding the generated code ----------------------------------------- - -1 First [install protoc](https://github.com/google/protobuf/blob/master/INSTALL.txt) - - For now, this needs to be installed from source - - This is will change once proto3 is officially released - -2 Install the protoc Go plugin. -```sh -$ go get -a github.com/golang/protobuf/protoc-gen-go -$ -$ # from this dir; invoke protoc -$ protoc -I ../protos ../protos/helloworld.proto --go_out=plugins=grpc:helloworld -``` diff --git a/go/gotutorial.md b/go/gotutorial.md deleted file mode 100644 index 63f0ad9058..0000000000 --- a/go/gotutorial.md +++ /dev/null @@ -1,431 +0,0 @@ -#gRPC Basics: Go - -This tutorial provides a basic Go programmer's introduction to working with gRPC. By walking through this example you'll learn how to: - -- Define a service in a .proto file. -- Generate server and client code using the protocol buffer compiler. -- Use the Go gRPC API to write a simple client and server for your service. - -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. - -This isn't a comprehensive guide to using gRPC in Go: more reference documentation is coming soon. - -## Why use gRPC? - -Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. - -With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. - -## Example code and setup - -The example code for our tutorial is in [grpc/grpc-go/examples/route_guide](https://github.com/grpc/grpc-go/tree/master/examples/route_guide). To download the example, clone the `grpc-go` repository by running the following command: -```shell -$ go get google.golang.org/grpc -``` - -Then change your current directory to `grpc-go/examples/route_guide`: -```shell -$ cd $GOPATH/src/google.golang.org/grpc/examples/route_guide -``` - -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Go quick start guide](https://github.com/grpc/grpc-common/tree/master/go). - - -## Defining the service - -Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). - -To define a service, you specify a named `service` in your .proto file: - -```proto -service RouteGuide { - ... -} -``` - -Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: - -- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. -```proto - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} -``` - -- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. -```proto - // Obtains the Features available within the given Rectangle. Results are - // streamed rather than returned at once (e.g. in a response message with a - // repeated field), as the rectangle may cover a large area and contain a - // huge number of features. - rpc ListFeatures(Rectangle) returns (stream Feature) {} -``` - -- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a client-side streaming method by placing the `stream` keyword before the *request* type. -```proto - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} -``` - -- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -```proto - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -``` - -Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -```proto -// 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; -} -``` - - -## Generating client and server code - -Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC Go plugin. - -For simplicity, we've provided a [bash script](https://github.com/grpc/grpc-go/blob/master/codegen.sh) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this by yourself, make sure you've installed protoc and followed the gRPC-Go [installation instructions](https://github.com/grpc/grpc-go/blob/master/README.md) first): - -```shell -$ codegen.sh route_guide.proto -``` - -which actually runs: - -```shell -$ protoc --go_out=plugins=grpc:. route_guide.proto -``` - -Running this command generates the following file in your current directory: -- `route_guide.pb.go` - -This contains: -- All the protocol buffer code to populate, serialize, and retrieve our request and response message types -- An interface type (or *stub*) for clients to call with the methods defined in the `RouteGuide` service. -- An interface type for servers to implement, also with the methods defined in the `RouteGuide` service. - - - -## Creating the server - -First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). - -There are two parts to making our `RouteGuide` service do its job: -- Implementing the service interface generated from our service definition: doing the actual "work" of our service. -- Running a gRPC server to listen for requests from clients and dispatch them to the right service implementation. - -You can find our example `RouteGuide` server in [grpc-go/examples/route_guide/server/server.go](https://github.com/grpc/grpc-go/tree/master/examples/route_guide/server/server.go). Let's take a closer look at how it works. - -### Implementing RouteGuide - -As you can see, our server has a `routeGuideServer` struct type that implements the generated `RouteGuideServer` interface: - -```go -type routeGuideServer struct { - ... -} -... - -func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) { - ... -} -... - -func (s *routeGuideServer) ListFeatures(rect *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer) error { - ... -} -... - -func (s *routeGuideServer) RecordRoute(stream pb.RouteGuide_RecordRouteServer) error { - ... -} -... - -func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error { - ... -} -... -``` - -#### Simple RPC -`routeGuideServer` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. - -```go -func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) { - for _, feature := range s.savedFeatures { - if proto.Equal(feature.Location, point) { - return feature, nil - } - } - // No feature was found, return an unnamed feature - return &pb.Feature{"", point}, nil -} -``` - -The method is passed a context object for the RPC and the client's `Point` protocol buffer request. It returns a `Feature` protocol buffer object with the response information and an `error`. In the method we populate the `Feature` with the appropriate information, and then `return` it along with an `nil` error to tell gRPC that we've finished dealing with the RPC and that the `Feature` can be returned to the client. - -#### Server-side streaming RPC -Now let's look at one of our streaming RPCs. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. - -```go -func (s *routeGuideServer) ListFeatures(rect *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer) error { - for _, feature := range s.savedFeatures { - if inRange(feature.Location, rect) { - if err := stream.Send(feature); err != nil { - return err - } - } - } - return nil -} -``` - -As you can see, instead of getting simple request and response objects in our method parameters, this time we get a request object (the `Rectangle` in which our client wants to find `Feature`s) and a special `RouteGuide_ListFeaturesServer` object to write our responses. - -In the method, we populate as many `Feature` objects as we need to return, writing them to the `RouteGuide_ListFeaturesServer` using its `Send()` method. Finally, as in our simple RPC, we return a `nil` error to tell gRPC that we've finished writing responses. Should any error happen in this call, we return a non-`nil` error; the gRPC layer will translate it into an appropriate RPC status to be sent on the wire. - -#### Client-side streaming RPC -Now let's look at something a little more complicated: the client-side streaming method `RecordRoute`, where we get a stream of `Point`s from the client and return a single `RouteSummary` with information about their trip. As you can see, this time the method doesn't have a request parameter at all. Instead, it gets a `RouteGuide_RecordRouteServer` stream, which the server can use to both read *and* write messages - it can receive client messages using its `Recv()` method and return its single response using its `SendAndClose()` method. - -```go -func (s *routeGuideServer) RecordRoute(stream pb.RouteGuide_RecordRouteServer) error { - var pointCount, featureCount, distance int32 - var lastPoint *pb.Point - startTime := time.Now() - for { - point, err := stream.Recv() - if err == io.EOF { - endTime := time.Now() - return stream.SendAndClose(&pb.RouteSummary{ - PointCount: pointCount, - FeatureCount: featureCount, - Distance: distance, - ElapsedTime: int32(endTime.Sub(startTime).Seconds()), - }) - } - if err != nil { - return err - } - pointCount++ - for _, feature := range s.savedFeatures { - if proto.Equal(feature.Location, point) { - featureCount++ - } - } - if lastPoint != nil { - distance += calcDistance(lastPoint, point) - } - lastPoint = point - } -} -``` - -In the method body we use the `RouteGuide_RecordRouteServer`s `Recv()` method to repeatedly read in our client's requests to a request object (in this case a `Point`) until there are no more messages: the server needs to check the the error returned from `Read()` after each call. If this is `nil`, the stream is still good and it can continue reading; if it's `io.EOF` the message stream has ended and the server can return its `RouteSummary`. If it has any other value, we return the error "as is" so that it'll be translated to an RPC status by the gRPC layer. - -#### Bidirectional streaming RPC -Finally, let's look at our bidirectional streaming RPC `RouteChat()`. - -```go -func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error { - for { - in, err := stream.Recv() - if err == io.EOF { - return nil - } - if err != nil { - return err - } - key := serialize(in.Location) - ... // look for notes to be sent to client - for _, note := range s.routeNotes[key] { - if err := stream.Send(note); err != nil { - return err - } - } - } -} -``` - -This time we get a `RouteGuide_RouteChatServer` stream that, as in our client-side streaming example, can be used to read and write messages. However, this time we return values via our method's stream while the client is still writing messages to *their* message stream. - -The syntax for reading and writing here is very similar to our client-streaming method, except the server uses the stream's `Send()` method rather than `SendAndClose()` because it's writing multiple responses. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. - -### Starting the server - -Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: - -```go -flag.Parse() -lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port)) -if err != nil { - log.Fatalf("failed to listen: %v", err) -} -grpcServer := grpc.NewServer() -pb.RegisterRouteGuideServer(grpcServer, &routeGuideServer{}) -... // determine whether to use TLS -grpcServer.Serve(lis) -``` -To build and start a server, we: - -1. Specify the port we want to use to listen for client requests using `lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))`. -2. Create an instance of the gRPC server using `grpc.NewServer()`. -3. Register our service implementation with the gRPC server. -4. Call `Serve()` on the server with our port details to do a blocking wait until the process is killed or `Stop()` is called. - - -## Creating the client - -In this section, we'll look at creating a Go client for our `RouteGuide` service. You can see our complete example client code in [grpc-go/examples/route_guide/client/client.go](https://github.com/grpc/grpc-go/tree/master/examples/route_guide/client/client.go). - -### Creating a stub - -To call service methods, we first need to create a gRPC *channel* to communicate with the server. We create this by passing the server address and port number to `grpc.Dial()` as follows: - -```go -conn, err := grpc.Dial(*serverAddr) -if err != nil { - ... -} -defer conn.Close() -``` - -You can use `DialOptions` to set the auth credentials (e.g., TLS, GCE credentials, JWT credentials) in `grpc.Dial` if the service you request requires that - however, we don't need to do this for our `RouteGuide` service. - -Once the gRPC *channel* is setup, we need a client *stub* to perform RPCs. We get this using the `NewRouteGuideClient` method provided in the `pb` package we generated from our .proto. - -```go -client := pb.NewRouteGuideClient(conn) -``` - -### Calling service methods - -Now let's look at how we call our service methods. Note that in gRPC-Go, RPCs operate in a blocking/synchronous mode, which means that the RPC call waits for the server to respond, and will either return a response or an error. - -#### Simple RPC - -Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. - -```go -feature, err := client.GetFeature(context.Background(), &pb.Point{409146138, -746188906}) -if err != nil { - ... -} -``` - -As you can see, we call the method on the stub we got earlier. In our method parameters we create and populate a request protocol buffer object (in our case `Point`). We also pass a `context.Context` object which lets us change our RPC's behaviour if necessary, such as time-out/cancel an RPC in flight. If the call doesn't return an error, then we can read the response information from the server from the first return value. - -```go -log.Println(feature) -``` - -#### Server-side streaming RPC - -Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. - -```go -rect := &pb.Rectangle{ ... } // initialize a pb.Rectangle -stream, err := client.ListFeatures(context.Background(), rect) -if err != nil { - ... -} -for { - feature, err := stream.Recv() - if err == io.EOF { - break - } - if err != nil { - log.Fatalf("%v.ListFeatures(_) = _, %v", client, err) - } - log.Println(feature) -} -``` - -As in the simple RPC, we pass the method a context and a request. However, instead of getting a response object back, we get back an instance of `RouteGuide_ListFeaturesClient`. The client can use the `RouteGuide_ListFeaturesClient` stream to read the server's responses. - -We use the `RouteGuide_ListFeaturesClient`'s `Recv()` method to repeatedly read in the server's responses to a response protocol buffer object (in this case a `Feature`) until there are no more messages: the client needs to check the error `err` returned from `Recv()` after each call. If `nil`, the stream is still good and it can continue reading; if it's `io.EOF` then the message stream has ended; otherwise there must be an RPC error, which is passed over through `err`. - -#### Client-side streaming RPC - -The client-side streaming method `RecordRoute` is similar to the server-side method, except that we only pass the method a context and get a `RouteGuide_RecordRouteClient` stream back, which we can use to both write *and* read messages. - -```go -// Create a random number of random points -r := rand.New(rand.NewSource(time.Now().UnixNano())) -pointCount := int(r.Int31n(100)) + 2 // Traverse at least two points -var points []*pb.Point -for i := 0; i < pointCount; i++ { - points = append(points, randomPoint(r)) -} -log.Printf("Traversing %d points.", len(points)) -stream, err := client.RecordRoute(context.Background()) -if err != nil { - log.Fatalf("%v.RecordRoute(_) = _, %v", client, err) -} -for _, point := range points { - if err := stream.Send(point); err != nil { - log.Fatalf("%v.Send(%v) = %v", stream, point, err) - } -} -reply, err := stream.CloseAndRecv() -if err != nil { - log.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, nil) -} -log.Printf("Route summary: %v", reply) -``` - -The `RouteGuide_RecordRouteClient` has a `Send()` method that we can use to send requests to the server. Once we've finished writing our client's requests to the stream using `Send()`, we need to call `CloseAndRecv()` on the stream to let gRPC know that we've finished writing and are expecting to receive a response. We get our RPC status from the `err` returned from `CloseAndRecv()`. If the status is `nil`, then the first return value from `CloseAndRecv()` will be a valid server response. - -#### Bidirectional streaming RPC - -Finally, let's look at our bidirectional streaming RPC `RouteChat()`. As in the case of `RecordRoute`, we only pass the method a context object and get back a stream that we can use to both write and read messages. However, this time we return values via our method's stream while the server is still writing messages to *their* message stream. - -```go -stream, err := client.RouteChat(context.Background()) -waitc := make(chan struct{}) -go func() { - for { - in, err := stream.Recv() - if err == io.EOF { - // read done. - close(waitc) - return - } - if err != nil { - log.Fatalf("Failed to receive a note : %v", err) - } - log.Printf("Got message %s at point(%d, %d)", in.Message, in.Location.Latitude, in.Location.Longitude) - } -}() -for _, note := range notes { - if err := stream.Send(note); err != nil { - log.Fatalf("Failed to send a note: %v", err) - } -} -stream.CloseSend() -<-waitc -``` - -The syntax for reading and writing here is very similar to our client-side streaming method, except we use the stream's `CloseSend()` method once we've finished our call. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. - -## Try it out! - -To compile and run the server, assuming you are in the folder -`$GOPATH/src/google.golang.org/grpc/examples/route_guide`, simply: - -```sh -$ go run server/server.go -``` - -Likewise, to run the client: - -```sh -$ go run client/client.go -``` - diff --git a/go/greeter_client/main.go b/go/greeter_client/main.go deleted file mode 100644 index 065ae852bc..0000000000 --- a/go/greeter_client/main.go +++ /dev/null @@ -1,69 +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. - * - */ - -package main - -import ( - "log" - "os" - - pb "github.com/grpc/grpc-common/go/helloworld" - "golang.org/x/net/context" - "google.golang.org/grpc" -) - -const ( - address = "localhost:50051" - defaultName = "world" -) - -func main() { - // Set up a connection to the server. - conn, err := grpc.Dial(address) - if err != nil { - log.Fatalf("did not connect: %v", err) - } - defer conn.Close() - c := pb.NewGreeterClient(conn) - - // Contact the server and print out its response. - name := defaultName - if len(os.Args) > 1 { - name = os.Args[1] - } - r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name}) - if err != nil { - log.Fatalf("could not greet: %v", err) - } - log.Printf("Greeting: %s", r.Message) -} diff --git a/go/greeter_server/main.go b/go/greeter_server/main.go deleted file mode 100644 index c7fa06ad18..0000000000 --- a/go/greeter_server/main.go +++ /dev/null @@ -1,65 +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. - * - */ - -package main - -import ( - "log" - "net" - - pb "github.com/grpc/grpc-common/go/helloworld" - "golang.org/x/net/context" - "google.golang.org/grpc" -) - -const ( - port = ":50051" -) - -// server is used to implement hellowrld.GreeterServer. -type server struct{} - -// SayHello implements helloworld.GreeterServer -func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { - return &pb.HelloReply{Message: "Hello " + in.Name}, nil -} - -func main() { - lis, err := net.Listen("tcp", port) - if err != nil { - log.Fatalf("failed to listen: %v", err) - } - s := grpc.NewServer() - pb.RegisterGreeterServer(s, &server{}) - s.Serve(lis) -} diff --git a/go/helloworld/helloworld.pb.go b/go/helloworld/helloworld.pb.go deleted file mode 100644 index 1ff931a384..0000000000 --- a/go/helloworld/helloworld.pb.go +++ /dev/null @@ -1,109 +0,0 @@ -// Code generated by protoc-gen-go. -// source: helloworld.proto -// DO NOT EDIT! - -/* -Package helloworld is a generated protocol buffer package. - -It is generated from these files: - helloworld.proto - -It has these top-level messages: - HelloRequest - HelloReply -*/ -package helloworld - -import proto "github.com/golang/protobuf/proto" - -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal - -// The request message containing the user's name. -type HelloRequest struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` -} - -func (m *HelloRequest) Reset() { *m = HelloRequest{} } -func (m *HelloRequest) String() string { return proto.CompactTextString(m) } -func (*HelloRequest) ProtoMessage() {} - -// The response message containing the greetings -type HelloReply struct { - Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` -} - -func (m *HelloReply) Reset() { *m = HelloReply{} } -func (m *HelloReply) String() string { return proto.CompactTextString(m) } -func (*HelloReply) ProtoMessage() {} - -func init() { -} - -// Client API for Greeter service - -type GreeterClient interface { - // Sends a greeting - SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) -} - -type greeterClient struct { - cc *grpc.ClientConn -} - -func NewGreeterClient(cc *grpc.ClientConn) GreeterClient { - return &greeterClient{cc} -} - -func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) { - out := new(HelloReply) - err := grpc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Greeter service - -type GreeterServer interface { - // Sends a greeting - SayHello(context.Context, *HelloRequest) (*HelloReply, error) -} - -func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) { - s.RegisterService(&_Greeter_serviceDesc, srv) -} - -func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { - in := new(HelloRequest) - if err := codec.Unmarshal(buf, in); err != nil { - return nil, err - } - out, err := srv.(GreeterServer).SayHello(ctx, in) - if err != nil { - return nil, err - } - return out, nil -} - -var _Greeter_serviceDesc = grpc.ServiceDesc{ - ServiceName: "helloworld.Greeter", - HandlerType: (*GreeterServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "SayHello", - Handler: _Greeter_SayHello_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, -} diff --git a/grpc-auth-support.md b/grpc-auth-support.md deleted file mode 100644 index b9ef299332..0000000000 --- a/grpc-auth-support.md +++ /dev/null @@ -1,289 +0,0 @@ -#gRPC Authentication support - -gRPC is designed to plug-in a number of authentication mechanisms. This document -provides a quick overview of the various auth mechanisms supported, discusses -the API with some examples, and concludes with a discussion of extensibility. -More documentation and examples are coming soon! - -## Supported auth mechanisms - -###SSL/TLS -gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the -server, and encrypt all the data exchanged between the client and the server. -Optional mechanisms are available for clients to provide certificates to -accomplish mutual authentication. - -###OAuth 2.0 -gRPC provides a generic mechanism (described below) to attach metadata to -requests and responses. This mechanism can be used to attach OAuth 2.0 Access -Tokens to RPCs being made at a client. Additional support for acquiring Access -Tokens while accessing Google APIs through gRPC is provided for certain auth -flows, demonstrated through code examples below. - -## API -To reduce complexity and minimize API clutter, gRPC works with a unified concept -of a Credentials object. Users construct gRPC credentials using corresponding -bootstrap credentials (e.g., SSL client certs or Service Account Keys), and use -the credentials while creating a gRPC channel to any server. Depending on the -type of credential supplied, the channel uses the credentials during the initial -SSL/TLS handshake with the server, or uses the credential to generate and -attach Access Tokens to each request being made on the channel. - -###SSL/TLS for server authentication and encryption -This is the simplest authentication scenario, where a client just wants to -authenticate the server and encrypt all data. - -```cpp -SslCredentialsOptions ssl_opts; // Options to override SSL params, empty by default -// Create the credentials object by providing service account key in constructor -std::unique_ptr creds = CredentialsFactory::SslCredentials(ssl_opts); -// Create a channel using the credentials created in the previous step -std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); -// Create a stub on the channel -std::unique_ptr stub(Greeter::NewStub(channel)); -// Make actual RPC calls on the stub. -grpc::Status s = stub->sayHello(&context, *request, response); -``` - -For advanced use cases such as modifying the root CA or using client certs, -the corresponding options can be set in the SslCredentialsOptions parameter -passed to the factory method. - - -###Authenticating with Google - -gRPC applications can use a simple API to create a credential that works in various deployment scenarios. - -```cpp -std::unique_ptr creds = CredentialsFactory::GoogleDefaultCredentials(); -// Create a channel, stub and make RPC calls (same as in the previous example) -std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); -std::unique_ptr stub(Greeter::NewStub(channel)); -grpc::Status s = stub->sayHello(&context, *request, response); -``` - -This credential works for applications using Service Accounts as well as for -applications running in [Google Compute Engine (GCE)](https://cloud.google.com/compute/). In the former case, the -service account’s private keys are loaded from the file named in the environment -variable `GOOGLE_APPLICATION_CREDENTIALS`. The -keys are used to generate bearer tokens that are attached to each outgoing RPC -on the corresponding channel. - -For applications running in GCE, a default service account and corresponding -OAuth scopes can be configured during VM setup. At run-time, this credential -handles communication with the authentication systems to obtain OAuth2 access -tokens and attaches them to each outgoing RPC on the corresponding channel. -Extending gRPC to support other authentication mechanisms -The gRPC protocol is designed with a general mechanism for sending metadata -associated with RPC. Clients can send metadata at the beginning of an RPC and -servers can send back metadata at the beginning and end of the RPC. This -provides a natural mechanism to support OAuth2 and other authentication -mechanisms that need attach bearer tokens to individual request. - -In the simplest case, there is a single line of code required on the client -to add a specific token as metadata to an RPC and a corresponding access on -the server to retrieve this piece of metadata. The generation of the token -on the client side and its verification at the server can be done separately. - -A deeper integration can be achieved by plugging in a gRPC credentials implementation for any custom authentication mechanism that needs to attach per-request tokens. gRPC internals also allow switching out SSL/TLS with other encryption mechanisms. - -## Examples - -These authentication mechanisms will be available in all gRPC's supported languages. -The following sections demonstrate how authentication and authorization features described above appear in each language: more languages are coming soon. - -###SSL/TLS for server authentication and encryption (Ruby) -```ruby -# Base case - No encryption -stub = Helloworld::Greeter::Stub.new('localhost:50051') -... - -# With server authentication SSL/TLS -creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file -stub = Helloworld::Greeter::Stub.new('localhost:50051', creds: creds) -``` - -###SSL/TLS for server authentication and encryption (C#) -```csharp -// Base case - No encryption -var channel = new Channel("localhost:50051"); -var client = new Greeter.GreeterClient(channel); -... - -// With server authentication SSL/TLS -var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file -var channel = new Channel("localhost:50051", credentials); -var client = new Greeter.GreeterClient(channel); -``` - -###SSL/TLS for server authentication and encryption (Objective-C) - -The default for Objective-C is to use SSL/TLS, as that's the most common use case when accessing -remote APIs. - -```objective-c -// Base case - With server authentication SSL/TLS -HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"localhost:50051"]; -// Same as using @"https://localhost:50051". -... - -// No encryption -HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"http://localhost:50051"]; -// Specifying the HTTP scheme explicitly forces no encryption. -``` - -###SSL/TLS for server authentication and encryption (Python) -```python -# Base case - No encryption -stub = early_adopter_create_GreeterService_stub('localhost', 50051) -... - -# With server authentication SSL/TLS -stub = early_adopter_create_GreeterService_stub( - 'localhost', 50051, secure=True, root_certificates=open('ca.pem').read()) -... -``` -n.b.: the beta API will look different - -###Authenticating with Google (Ruby) -```ruby -# Base case - No encryption/authorization -stub = Helloworld::Greeter::Stub.new('localhost:50051') -... - -# Authenticating with Google -require 'googleauth' # from http://www.rubydoc.info/gems/googleauth/0.1.0 -... -creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file -scope = 'https://www.googleapis.com/auth/grpc-testing' -authorization = Google::Auth.get_application_default(scope) -stub = Helloworld::Greeter::Stub.new('localhost:50051', - creds: creds, - update_metadata: authorization.updater_proc) -``` - -###Authenticating with Google (Node.js) - -```node -// Base case - No encryption/authorization -var stub = new helloworld.Greeter('localhost:50051'); -... -// Authenticating with Google -var GoogleAuth = require('google-auth-library'); // from https://www.npmjs.com/package/google-auth-library -... -var creds = grpc.Credentials.createSsl(load_certs); // load_certs typically loads a CA roots file -var scope = 'https://www.googleapis.com/auth/grpc-testing'; -(new GoogleAuth()).getApplicationDefault(function(err, auth) { - if (auth.createScopeRequired()) { - auth = auth.createScoped(scope); - } - var stub = new helloworld.Greeter('localhost:50051', - {credentials: creds}, - grpc.getGoogleAuthDelegate(auth)); -}); -``` - -###Authenticating with Google (C#) -```csharp -// Base case - No encryption/authorization -var channel = new Channel("localhost:50051"); -var client = new Greeter.GreeterClient(channel); -... - -// Authenticating with Google -using Grpc.Auth; // from Grpc.Auth NuGet package -... -var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file -var channel = new Channel("localhost:50051", credentials); - -string scope = "https://www.googleapis.com/auth/grpc-testing"; -var authorization = GoogleCredential.GetApplicationDefault(); -if (authorization.IsCreateScopedRequired) -{ - authorization = credential.CreateScoped(new[] { scope }); -} -var client = new Greeter.GreeterClient(channel, - new StubConfiguration(OAuth2InterceptorFactory.Create(credential))); -``` - -###Authenticating with Google (PHP) -```php -// Base case - No encryption/authorization -$client = new helloworld\GreeterClient( - new Grpc\BaseStub('localhost:50051', [])); -... - -// Authenticating with Google -// the environment variable "GOOGLE_APPLICATION_CREDENTIALS" needs to be set -$scope = "https://www.googleapis.com/auth/grpc-testing"; -$auth = Google\Auth\ApplicationDefaultCredentials::getCredentials($scope); -$opts = [ - 'credentials' => Grpc\Credentials::createSsl(file_get_contents('ca.pem')); - 'update_metadata' => $auth->getUpdateMetadataFunc(), -]; - -$client = new helloworld\GreeterClient( - new Grpc\BaseStub('localhost:50051', $opts)); - -``` - -###Authenticating with Google (Objective-C) - -This example uses the [Google iOS Sign-In library](https://developers.google.com/identity/sign-in/ios/), -but it's easily extrapolated to any other OAuth2 library. - -```objective-c -// Base case - No authentication -[client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { - ... -}]; - -... - -// Authenticating with Google - -// When signing the user in, ask her for the relevant scopes. -GIDSignIn.sharedInstance.scopes = @[@"https://www.googleapis.com/auth/grpc-testing"]; - -... - -#import - -// Create a not-yet-started RPC. We want to set the request headers on this object before starting -// it. -ProtoRPC *call = - [client RPCToSayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { - ... - }]; - -// Set the access token to be used. -NSString *accessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken; -call.requestMetadata[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken]}]; - -// Start the RPC. -[call start]; -``` - -You can see a working example app, with a more detailed explanation, [here](https://github.com/grpc/grpc-common/tree/master/objective-c/auth_sample). - -### Authenticating with Google (Python) -```python -# Base case - No encryption -stub = early_adopter_create_GreeterService_stub('localhost', 50051) -... - -# With server authentication SSL/TLS -import oauth2client.client -credentials = oauth2client.GoogleCredentials.get_application_default() -scope = 'https://www.googleapis.com/auth/grpc-testing' -scoped_credentials = credentials.create_scoped([scope]) -access_token = scoped_credentials.get_access_token().access_token -metadata_transformer = ( - lambda x: [('Authorization', 'Bearer {}'.format(access_token))]) - -stub = early_adopter_create_GreeterService_stub( - 'localhost', 50051, secure=True, root_certificates=open('ca.pem').read(), - metadata_transformer=metadata_transformer) -... -``` -n.b.: the beta API will look different diff --git a/grpc-common/LICENSE b/grpc-common/LICENSE new file mode 100644 index 0000000000..05b6a757da --- /dev/null +++ b/grpc-common/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2015, grpc +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 grpc-common 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 HOLDER 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. + diff --git a/grpc-common/PATENTS b/grpc-common/PATENTS new file mode 100644 index 0000000000..619f9dbfe6 --- /dev/null +++ b/grpc-common/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the GRPC project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of GRPC, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of GRPC. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of GRPC or any code incorporated within this +implementation of GRPC constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of GRPC +shall terminate as of the date such litigation is filed. diff --git a/grpc-common/PROTOCOL-HTTP2.md b/grpc-common/PROTOCOL-HTTP2.md new file mode 100644 index 0000000000..d3fbb60d60 --- /dev/null +++ b/grpc-common/PROTOCOL-HTTP2.md @@ -0,0 +1,192 @@ +# gRPC over HTTP2 + +## Introduction +This document serves as a detailed description for an implementation of gRPC carried over HTTP2 draft 17 framing. It assumes familiarity with the HTTP2 specification. + +## Protocol +Production rules are using ABNF syntax. + +### Outline + +The following is the general sequence of message atoms in a GRPC request & response message stream + +* Request → Request-Headers *Delimited-Message EOS +* Response → (Response-Headers *Delimited-Message Trailers) / Trailers-Only + + +### Requests + +* Request → Request-Headers *Delimited-Message EOS + +Request-Headers are delivered as HTTP2 headers in HEADERS + CONTINUATION frames. + +* **Request-Headers** → Call-Definition *Custom-Metadata +* **Call-Definition** → Method Scheme Path TE [Authority] [Timeout] [Content-Type] [Message-Type] [Message-Encoding] [Message-Accept-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_})] +* **Content-Coding** → “gzip” / “deflate” / “snappy” / {_custom_} +* **Message-Encoding** → “grpc-encoding” Content-Coding +* **Message-Accept-Encoding** → “grpc-accept-encoding” Content-Coding *("," Content-Coding) +* **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] [Message-Accept-Encoding] Content-Type *Custom-Metadata +* **Trailers-Only** → HTTP-Status Content-Type Trailers +* **Trailers** → Status [Status-Message] *Custom-Metadata +* **HTTP-Status** → “:status 200” +* **Status** → “grpc-status” +* **Status-Message** → “grpc-message” + +**Response-Headers** & **Trailers-Only** are each delivered in a single HTTP2 HEADERS frame block. Most responses are expected to have both headers and trailers but **Trailers-Only** is permitted for calls that produce an immediate error. Status must be sent in **Trailers** even if the status code is OK. + +For responses end-of-stream is indicated by the presence of the END_STREAM flag on the last received HEADERS frame that carries **Trailers**. + +Implementations should expect broken deployments to send non-200 HTTP status codes in responses as well as a variety of non-GRPC content-types and to omit **Status** & **Status-Message**. Implementations must synthesize a **Status** & **Status-Message** to propagate to the application layer when this occurs. + +####Example + +Sample unary-call showing HTTP2 framing sequence + +**Request** + +``` +HEADERS (flags = END_HEADERS) +:method = POST +:scheme = http +:path = /google.pubsub.v2.PublisherService/CreateTopic +:authority = pubsub.googleapis.com +grpc-timeout = 1S +content-type = application/grpc+proto +grpc-encoding = gzip +authorization = Bearer y235.wef315yfh138vh31hv93hv8h3v + +DATA (flags = END_STREAM) + +``` +**Response** +``` +HEADERS (flags = END_HEADERS) +:status = 200 +grpc-encoding = gzip + +DATA + + +HEADERS (flags = END_STREAM, END_HEADERS) +grpc-status = 0 # OK +trace-proto-bin = jher831yy13JHy3hc +``` +####User Agents + +While the protocol does not require a user-agent to function it is recommended that clients provide a structured user-agent string that provides a basic description of the calling library, version & platform to facilitate issue diagnosis in heterogeneous environments. The following structure is recommended to library developers +``` +User-Agent → “grpc-” Language ?(“-” Variant) “/” Version ?( “ (“ *(AdditionalProperty “;”) “)” ) +``` +E.g. + +``` +grpc-java/1.2.3 +grpc-ruby/1.2.3 +grpc-ruby-jruby/1.3.4 +grpc-java-android/0.9.1 (gingerbread/1.2.4; nexus5; tmobile) +``` +####HTTP2 Transport Mapping + +#####Stream Identification +All GRPC calls need to specify an internal ID. We will use HTTP2 stream-ids as call identifiers in this scheme. NOTE: These id’s are contextual to an open HTTP2 session and will not be unique within a given process that is handling more than one HTTP2 session nor can they be used as GUIDs. + +#####Data Frames +DATA frame boundaries have no relation to **Delimited-Message** boundaries and implementations should make no assumptions about their alignment. + +#####Errors + +When an application or runtime error occurs during an RPC a **Status** and **Status-Message** are delivered in **Trailers**. + +In some cases it is possible that the framing of the message stream has become corrupt and the RPC runtime will choose to use an **RST_STREAM** frame to indicate this state to its peer. RPC runtime implementations should interpret RST_STREAM as immediate full-closure of the stream and should propagate an error up to the calling application layer. + +The following mapping from RST_STREAM error codes to GRPC error codes is applied. + +HTTP2 Code|GRPC Code +----------|----------- +NO_ERROR(0)|INTERNAL - An explicit GRPC status of OK should have been sent but this might be used to aggressively lameduck in some scenarios. +PROTOCOL_ERROR(1)|INTERNAL +INTERNAL_ERROR(2)|INTERNAL +FLOW_CONTROL_ERROR(3)|INTERNAL +SETTINGS_TIMEOUT(4)|INTERNAL +STREAM_CLOSED|No mapping as there is no open stream to propagate to. Implementations should log. +FRAME_SIZE_ERROR|INTERNAL +REFUSED_STREAM|UNAVAILABLE - Indicates that no processing occurred and the request can be retried, possibly elsewhere. +CANCEL(8)|Mapped to call cancellation when sent by a client.Mapped to CANCELLED when sent by a server. Note that servers should only use this mechanism when they need to cancel a call but the payload byte sequence is incomplete. +COMPRESSION_ERROR|INTERNAL +CONNECT_ERROR|INTERNAL +ENHANCE_YOUR_CALM|RESOURCE_EXHAUSTED ...with additional error detail provided by runtime to indicate that the exhausted resource is bandwidth. +INADEQUATE_SECURITY| PERMISSION_DENIED … with additional detail indicating that permission was denied as protocol is not secure enough for call. + + +#####Security + +The HTTP2 specification mandates the use of TLS 1.2 or higher when TLS is used with HTTP2. It also places some additional constraints on the allowed ciphers in deployments to avoid known-problems as well as requiring SNI support. It is also expected that HTTP2 will be used in conjunction with proprietary transport security mechanisms about which the specification can make no meaningful recommendations. + +#####Connection Management +######GOAWAY Frame +Sent by servers to clients to indicate that they will no longer accept any new streams on the associated connections. This frame includes the id of the last successfully accepted stream by the server. Clients should consider any stream initiated after the last successfully accepted stream as UNAVAILABLE and retry the call elsewhere. Clients are free to continue working with the already accepted streams until they complete or the connection is terminated. + +Servers should send GOAWAY before terminating a connection to reliably inform clients which work has been accepted by the server and is being executed. + +######PING Frame +Both clients and servers can send a PING frame that the peer must respond to by precisely echoing what they received. This is used to assert that the connection is still live as well as providing a means to estimate end-to-end latency. If a server initiated PING does not receive a response within the deadline expected by the runtime all outstanding calls on the server will be closed with a CANCELLED status. An expired client initiated PING will cause all calls to be closed with an UNAVAILABLE status. Note that the frequency of PINGs is highly dependent on the network environment, implementations are free to adjust PING frequency based on network and application requirements. + +######Connection failure +If a detectable connection failure occurs on the client all calls will be closed with an UNAVAILABLE status. For servers open calls will be closed with a CANCELLED status. + + +### Appendix A - GRPC for Protobuf + +The service interfaces declared by protobuf are easily mapped onto GRPC by code generation extensions to protoc. The following defines the mapping to be used + + +* **Path** → / Service-Name / {_method name_} +* **Service-Name** → ?( {_proto package name_} "." ) {_service name_} +* **Message-Type** → {_fully qualified proto message name_} +* **Content-Type** → "application/grpc+proto" + + diff --git a/grpc-common/README.md b/grpc-common/README.md new file mode 100644 index 0000000000..5939db3ab5 --- /dev/null +++ b/grpc-common/README.md @@ -0,0 +1,449 @@ + +# Getting started + +Welcome to the developer documentation for gRPC, a language-neutral, +platform-neutral remote procedure call (RPC) system developed at Google. + +This document introduces you to gRPC with a quick overview and a simple +Hello World example. You'll find more tutorials and reference docs in this repository - more documentation is coming soon! + + +## Quick start +You can find quick start guides for each language, including installation instructions, examples, and tutorials here: +* [C++](https://github.com/grpc/grpc-common/tree/master/cpp) +* [Java](https://github.com/grpc/grpc-common/tree/master/java) +* [Go](https://github.com/grpc/grpc-common/tree/master/go) +* [Ruby](https://github.com/grpc/grpc-common/tree/master/ruby) +* [Node.js](https://github.com/grpc/grpc-common/tree/master/node) +* [Android Java](https://github.com/grpc/grpc-common/tree/master/java/android) +* [Python](https://github.com/grpc/grpc-common/tree/master/python/helloworld) +* [C#](https://github.com/grpc/grpc-common/tree/master/csharp) +* [Objective-C](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide) + +## What's in this repository? + +The `grpc-common` repository contains documentation, resources, and examples +for all gRPC users. You can find examples and instructions specific to your +favourite language in the relevant subdirectory. + +You can find out about the gRPC source code repositories in +[`grpc`](https://github.com/grpc/grpc). Each repository provides instructions +for building the appropriate libraries for your language. + + +## What is gRPC? + +In gRPC a *client* application can directly call +methods on a *server* application on a different machine as if it was a +local object, making it easier for you to create distributed applications and +services. As in many RPC systems, gRPC is based around the idea of defining +a *service*, specifying the methods that can be called remotely with their +parameters and return types. On the server side, the server implements this +interface and runs a gRPC server to handle client calls. On the client side, +the client has a *stub* that provides exactly the same methods as the server. + + + +gRPC clients and servers can run and talk to each other in a variety of +environments - from servers inside Google to your own desktop - and can +be written in any of gRPC's [supported languages](#quickstart). So, for +example, you can easily create a gRPC server in Java with clients in Go, +Python, or Ruby. In addition, the latest Google APIs will have gRPC versions +of their interfaces, letting you easily build Google functionality into +your applications. + + +### Working with protocol buffers + +By default gRPC uses *protocol buffers*, Google’s +mature open source mechanism for serializing structured data (although it +can be used with other data formats such as JSON). As you'll +see in our example below, you define gRPC services using *proto files*, +with method parameters and return types specified as protocol buffer message +types. You +can find out lots more about protocol buffers in the [Protocol Buffers +documentation](https://developers.google.com/protocol-buffers/docs/overview). + +#### Protocol buffer versions + +While protocol buffers have been available for open source users for some +time, our examples use a new flavour of protocol buffers called proto3, +which has a slightly simplified syntax, some useful new features, and supports +lots more languages. This is currently available as an alpha release in +Java, C++, Java_nano (Android Java), Python, and Ruby from [the protocol buffers Github +repo](https://github.com/google/protobuf/releases), as well as a Go language +generator from [the golang/protobuf Github repo](https://github.com/golang/protobuf), with more languages in development. You can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3), and see +the major differences from the current default version in the [release notes](https://github.com/google/protobuf/releases). More proto3 documentation is coming soon. + +In general, while you *can* use proto2 (the current default protocol buffers version), we recommend that you use proto3 with gRPC as it lets you use the full range of gRPC-supported languages, as well as avoiding compatibility +issues with proto2 clients talking to proto3 servers and vice versa. + + +## Hello gRPC! + +Now that you know a bit more about gRPC, the easiest way to see how it +works is to look at a simple example. Our Hello World walks you through the +construction of a simple gRPC client-server application, showing you how to: + +- Create a protocol buffers schema that defines a simple RPC service with +a single +Hello World method. +- Create a Java server that implements this interface. +- Create a Java client that accesses the Java server. +- Create a Go client that accesses +the same Java server. + +The complete code for the example is available in the `grpc-common` GitHub +repository. We use the Git versioning system for source code management: +however, you don't need to know anything about Git to follow along other +than how to install and run a few git commands. + +This is an introductory example rather than a comprehensive tutorial, so +don't worry if you're not a Go or +Java developer - the concepts are similar for all languages, and you can +find more implementations of our Hello World example in other languages (and full tutorials where available) in +the [language-specific folders](#quickstart) in this repository. Complete tutorials and +reference documentation for all gRPC languages are coming soon. + + +### Setup + +This section explains how to set up your local machine to work with +the example code. If you just want to read the example, you can go straight +to the [next step](#servicedef). + +#### Install Git + +You can download and install Git from http://git-scm.com/download. Once +installed you should have access to the git command line tool. The main +commands that you will need to use are: + +- git clone ... : clone a remote repository onto your local machine +- git checkout ... : check out a particular branch or a tagged version of +the code to hack on + +#### Install gRPC + +To build and install gRPC plugins and related tools: +- For Java, see the [Java quick start](https://github.com/grpc/grpc-java). +- For Go, see the [Go quick start](https://github.com/grpc/grpc-go). + +#### Get the source code + +The example code for our Java example lives in the `grpc-java` +GitHub repository. Clone this repository to your local machine by running the +following command: + + +``` +git clone https://github.com/grpc/grpc-java.git +``` + +Change your current directory to grpc-java/examples + +``` +cd grpc-java/examples +``` + + + + +### Defining a service + +The first step in creating our example is to define a *service*: an RPC +service specifies the methods that can be called remotely with their parameters +and return types. As you saw in the +[overview](#protocolbuffers) above, gRPC does this using [protocol +buffers](https://developers.google.com/protocol-buffers/docs/overview). We +use the protocol buffers interface definition language (IDL) to define our +service methods, and define the parameters and return +types as protocol buffer message types. Both the client and the +server use interface code generated from the service definition. + +Here's our example service definition, defined using protocol buffers IDL in +[helloworld.proto](https://github.com/grpc/grpc-java/tree/master/examples/src/main/proto). The `Greeter` +service has one method, `SayHello`, that lets the server receive a single +`HelloRequest` +message from the remote client containing the user's name, then send back +a greeting in a single `HelloReply`. This is the simplest type of RPC you +can specify in gRPC - you can find out about other types in the tutorial for your chosen language. + +```proto +syntax = "proto3"; + +option java_package = "io.grpc.examples"; + +package helloworld; + +// The greeter service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} + +``` + + +### Generating gRPC code + +Once we've defined our service, we use the protocol buffer compiler +`protoc` to generate the special client and server code we need to create +our application - right now we're going to generate Java code, though you +can generate gRPC code in any gRPC-supported language (as you'll see later +in this example). The generated code contains both stub code for clients to +use and an abstract interface for servers to implement, both with the method +defined in our `Greeter` service. + +(If you didn't install the gRPC plugins and protoc on your system and are just reading along with +the example, you can skip this step and move +onto the next one where we examine the generated code.) + +For simplicity, we've provided a [Gradle build file](https://github.com/grpc/grpc-java/blob/master/examples/build.gradle) with our Java examples that runs `protoc` for you with the appropriate plugin, input, and output: + +```shell +../gradlew build +``` + +This generates the following classes from our .proto, which contain all the generated code +we need to create our example: + +- `Helloworld.java`, which +has all the protocol buffer code to populate, serialize, and retrieve our +`HelloRequest` and `HelloReply` message types +- `GreeterGrpc.java`, which contains (along with some other useful code): + - an interface for `Greeter` servers to implement + + ```java + public static interface Greeter { + public void sayHello(io.grpc.examples.Helloworld.HelloRequest request, + io.grpc.stub.StreamObserver responseObserver); + } + ``` + + - _stub_ classes that clients can use to talk to a `Greeter` server. As you can see, they also implement the `Greeter` interface. + + ```java + public static class GreeterStub extends + io.grpc.stub.AbstractStub + implements Greeter { + ... + } + ``` + + +### Writing a server + +Now let's write some code! First we'll create a server application to implement +our service. Note that we're not going to go into a lot of detail about how +to create a server in this section. More detailed information will be in the +tutorial for your chosen language: check if there's one available yet in the relevant [quick start](#quickstart). + +Our server application has two classes: + +- a main server class that hosts the service implementation and allows access over the +network: [HelloWorldServer.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java). + + +- a simple service implementation class [GreeterImpl.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java#L51). + + +#### Service implementation + +[GreeterImpl.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java#L51) +actually implements our `Greeter` service's required behaviour. + +As you can see, the class `GreeterImpl` implements the interface +`GreeterGrpc.Greeter` that we [generated](#generating) from our proto +[IDL](https://github.com/grpc/grpc-java/tree/master/examples/src/main/proto) by implementing the method `sayHello`: + +```java + @Override + public void sayHello(HelloRequest req, StreamObserver responseObserver) { + HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build(); + responseObserver.onValue(reply); + responseObserver.onCompleted(); + } +``` +- `sayHello` takes two parameters: + - `HelloRequest`: the request + - `StreamObserver`: a response observer, which is + a special interface for the server to call with its response + +To return our response to the client and complete the call: + +1. We construct and populate a `HelloReply` response object with our exciting +message, as specified in our interface definition. +2. We return the `HelloReply` to the client and then specify that we've finished dealing with the RPC. + + +#### Server implementation + +[HelloWorldServer.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java) +shows the other main feature required to provide a gRPC service; making the service +implementation available from the network. + +```java + /* The port on which the server should run */ + private int port = 50051; + private ServerImpl server; + + private void start() throws Exception { + server = NettyServerBuilder.forPort(port) + .addService(GreeterGrpc.bindService(new GreeterImpl())) + .build().start(); + logger.info("Server started, listening on " + port); + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + // Use stderr here since the logger may have been reset by its JVM shutdown hook. + System.err.println("*** shutting down gRPC server since JVM is shutting down"); + HelloWorldServer.this.stop(); + System.err.println("*** server shut down"); + } + }); + } + +``` + +Here we create an appropriate gRPC server, binding the `Greeter` service +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. + + +### Writing a client + +Client-side gRPC is pretty simple. In this step, we'll use the generated code +to write a simple client that can access the `Greeter` server we created +in the [previous section](#server). You can see the complete client code in +[HelloWorldClient.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldClient.java). + +Again, we're not going to go into much detail about how to implement a client; +we'll leave that for the tutorial. + +#### Connecting to the service + +First let's look at how we connect to the `Greeter` server. First we need +to create a gRPC channel, specifying the hostname and port of the server we +want to connect to. Then we use the channel to construct the stub instance. + + +```java + private final ChannelImpl channel; + private final GreeterGrpc.GreeterBlockingStub blockingStub; + + public HelloWorldClient(String host, int port) { + channel = + NettyChannelBuilder.forAddress(host, port).negotiationType(NegotiationType.PLAINTEXT) + .build(); + blockingStub = GreeterGrpc.newBlockingStub(channel); + } + +``` + +In this case, we create a blocking stub. This means that the RPC call waits +for the server to respond, and will either return a response or raise an +exception. gRPC Java has other kinds of stubs that make non-blocking calls +to the server, where the response is returned asynchronously. + +#### Calling an RPC + +Now we can contact the service and obtain a greeting: + +1. We construct and fill in a `HelloRequest` to send to the service. +2. We call the stub's `hello()` RPC with our request and get a `HelloReply` +back, from which we can get our greeting. + + +```java + HelloRequest req = HelloRequest.newBuilder().setName(name).build(); + HelloReply reply = blockingStub.sayHello(req); + +``` + + +### Try it out! + +Our [Gradle build file](https://github.com/grpc/grpc-java/blob/master/examples/build.gradle) simplifies building and running the examples. + +You can build and run the server from the `grpc-java` root folder with: + +```sh +$ ./gradlew :grpc-examples:helloWorldServer +``` + +and in another terminal window confirm that it receives a message. + +```sh +$ ./gradlew :grpc-examples:helloWorldClient +``` + +### 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 looked at Java code +generated from and implementing our `Greeter` service definition. However, +as you'll see if you look at the language-specific subdirectories +in this repository, we've also generated and implemented `Greeter` +in some of gRPC's other supported languages. Each service +and client uses interface code generated from the same proto +that we used for the Java example. + +So, for example, if we visit the [`go` example +directory](https://github.com/grpc/grpc-common/tree/master/go) and look at the +[`greeter_client`](https://github.com/grpc/grpc-common/blob/master/go/greeter_client/main.go), +we can see that like the Java client, it connects to a `Greeter` service +at `localhost:50051` and uses a stub to call the `SayHello` method with a +`HelloRequest`: + +```go +const ( + address = "localhost:50051" + defaultName = "world" +) + +func main() { + // Set up a connection to the server. + conn, err := grpc.Dial(address) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + defer conn.Close() + c := pb.NewGreeterClient(conn) + + // Contact the server and print out its response. + name := defaultName + if len(os.Args) > 1 { + name = os.Args[1] + } + r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: + name}) + if err != nil { + log.Fatalf("could not greet: %v", err) + } + log.Printf("Greeting: %s", r.Message) +} +``` + + +If we run the Java server from earlier in another terminal window, we can +run the Go client and connect to it just like the Java client, even though +it's written in a different language. + +``` +$ greeter_client +``` +## Read more! + +- You can find links to language-specific tutorials, examples, and other docs in each language's [quick start](#quickstart). +- [gRPC Authentication Support](https://github.com/grpc/grpc-common/blob/master/grpc-auth-support.md) introduces authentication support in gRPC with supported mechanisms and examples. diff --git a/grpc-common/cpp/README.md b/grpc-common/cpp/README.md new file mode 100644 index 0000000000..e0a09ff8b8 --- /dev/null +++ b/grpc-common/cpp/README.md @@ -0,0 +1,65 @@ +#gRPC in 3 minutes (C++) + +## Installation + +To install gRPC on your system, follow the instructions here: +[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). + +## Hello C++ gRPC! + +Here's how to build and run the C++ implementation of the [Hello World](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto) example used in [Getting started](https://github.com/grpc/grpc-common). + +The example code for this and our other examples lives in the `grpc-common` +GitHub repository. Clone this repository to your local machine by running the +following command: + + +```sh +$ git clone https://github.com/grpc/grpc-common.git +``` + +Change your current directory to grpc-common/cpp/helloworld + +```sh +$ cd grpc-common/cpp/helloworld/ +``` + + +### Generating gRPC code + +To generate the client and server side interfaces: + +```sh +$ make helloworld.grpc.pb.cc helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + +```sh +$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto +``` + +### Client and server implementations + +The client implementation is at [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). + +The server implementation is at [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). + +### Try it! +Build client and server: +```sh +$ make +``` +Run the server, which will listen on port 50051: +```sh +$ ./greeter_server +``` +Run the client (in a different terminal): +```sh +$ ./greeter_client +``` +If things go smoothly, you will see the "Greeter received: Hello world" in the client side output. + +## Tutorial + +You can find a more detailed tutorial in [gRPC Basics: C++](https://github.com/grpc/grpc-common/blob/master/cpp/cpptutorial.md) diff --git a/grpc-common/cpp/cpptutorial.md b/grpc-common/cpp/cpptutorial.md new file mode 100644 index 0000000000..c19b472744 --- /dev/null +++ b/grpc-common/cpp/cpptutorial.md @@ -0,0 +1,365 @@ +#gRPC Basics: C++ + +This tutorial provides a basic C++ programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate server and client code using the protocol buffer compiler. +- Use the C++ gRPC API to write a simple client and server for your service. + +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. + +This isn't a comprehensive guide to using gRPC in C++: more reference documentation is coming soon. + +## Why use gRPC? + +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/cpp/route_guide](https://github.com/grpc/grpc-common/tree/master/cpp/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/cpp/route_guide`: +```shell +$ cd grpc-common/cpp/route_guide +``` + +You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the C++ quick start guide](https://github.com/grpc/grpc-common/tree/master/cpp). + + +## Defining the service + +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +``` +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +``` + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. +``` + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} +``` + +- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a client-side streaming method by placing the `stream` keyword before the *request* type. +``` + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +``` + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +``` +// 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; +} +``` + + +## Generating client and server code + +Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. + +For simplicity, we've provided a [makefile](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): + +```shell +$ make route_guide.grpc.pb.cc route_guide.pb.cc +``` + +which actually runs: + +```shell +$ protoc -I ../../protos --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ../../protos/route_guide.proto +$ protoc -I ../../protos --cpp_out=. ../../protos/route_guide.proto +``` + +Running this command generates the following files in your current directory: +- `route_guide.pb.h`, the header which declares your generated message classes +- `route_guide.pb.cc`, which contains the implementation of your message classes +- `route_guide.grpc.pb.h`, the header which declares your generated service classes +- `route_guide.grpc.pb.cc`, which contains the implementation of your service classes + +These contain: +- All the protocol buffer code to populate, serialize, and retrieve our request and response message types +- A class called `RouteGuide` that contains + - a remote interface type (or *stub*) for clients to call with the methods defined in the `RouteGuide` service. + - two abstract interfaces for servers to implement, also with the methods defined in the `RouteGuide` service. + + + +## Creating the server + +First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). + +There are two parts to making our `RouteGuide` service do its job: +- Implementing the service interface generated from our service definition: doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and return the service responses. + +You can find our example `RouteGuide` server in [grpc-common/cpp/route_guide/route_guide_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_server.cc). Let's take a closer look at how it works. + +### Implementing RouteGuide + +As you can see, our server has a `RouteGuideImpl` class that implements the generated `RouteGuide::Service` interface: + +```cpp +class RouteGuideImpl final : public RouteGuide::Service { +... +} +``` +In this case we're implementing the *synchronous* version of `RouteGuide`, which provides our default gRPC server behaviour. It's also possible to implement an asynchronous interface, `RouteGuide::AsyncService`, which allows you to further customize your server's threading behaviour, though we won't look at this in this tutorial. + +`RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. + +```cpp + Status GetFeature(ServerContext* context, const Point* point, + Feature* feature) override { + feature->set_name(GetFeatureName(*point, feature_list_)); + feature->mutable_location()->CopyFrom(*point); + return Status::OK; + } +``` + +The method is passed a context object for the RPC, the client's `Point` protocol buffer request, and a `Feature` protocol buffer to fill in with the response information. In the method we populate the `Feature` with the appropriate information, and then `return` with an `OK` status to tell gRPC that we've finished dealing with the RPC and that the `Feature` can be returned to the client. + +Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. + +```cpp + Status ListFeatures(ServerContext* context, const Rectangle* rectangle, + ServerWriter* writer) override { + auto lo = rectangle->lo(); + auto hi = rectangle->hi(); + long left = std::min(lo.longitude(), hi.longitude()); + long right = std::max(lo.longitude(), hi.longitude()); + long top = std::max(lo.latitude(), hi.latitude()); + long bottom = std::min(lo.latitude(), hi.latitude()); + for (const Feature& f : feature_list_) { + if (f.location().longitude() >= left && + f.location().longitude() <= right && + f.location().latitude() >= bottom && + f.location().latitude() <= top) { + writer->Write(f); + } + } + return Status::OK; + } +``` + +As you can see, instead of getting simple request and response objects in our method parameters, this time we get a request object (the `Rectangle` in which our client wants to find `Feature`s) and a special `ServerWriter` object. In the method, we populate as many `Feature` objects as we need to return, writing them to the `ServerWriter` using its `Write()` method. Finally, as in our simple RPC, we `return Status::OK` to tell gRPC that we've finished writing responses. + +If you look at the client-side streaming method `RecordRoute` you'll see it's quite similar, except this time we get a `ServerReader` instead of a request object and a single response. We use the `ServerReader`s `Read()` method to repeatedly read in our client's requests to a request object (in this case a `Point`) until there are no more messages: the server needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. + +```cpp +while (stream->Read(&point)) { + ...//process client input +} +``` +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. + +```cpp + Status RouteChat(ServerContext* context, + ServerReaderWriter* stream) override { + std::vector received_notes; + RouteNote note; + while (stream->Read(¬e)) { + for (const RouteNote& n : received_notes) { + if (n.location().latitude() == note.location().latitude() && + n.location().longitude() == note.location().longitude()) { + stream->Write(n); + } + } + received_notes.push_back(note); + } + + return Status::OK; + } +``` + +This time we get a `ServerReaderWriter` that can be used to read *and* write messages. The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + +### Starting the server + +Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: + +```cpp +void RunServer(const std::string& db_path) { + std::string server_address("0.0.0.0:50051"); + RouteGuideImpl service(db_path); + + ServerBuilder builder; + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + builder.RegisterService(&service); + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + server->Wait(); +} +``` +As you can see, we build and start our server using a `ServerBuilder`. To do this, we: + +1. Create an instance of our service implementation class `RouteGuideImpl`. +2. Create an instance of the factory `ServerBuilder` class. +3. Specify the address and port we want to use to listen for client requests using the builder's `AddListeningPort()` method. +4. Register our service implementation with the builder. +5. Call `BuildAndStart()` on the builder to create and start an RPC server for our service. +5. Call `Wait()` on the server to do a blocking wait until process is killed or `Shutdown()` is called. + + +## Creating the client + +In this section, we'll look at creating a C++ client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/cpp/route_guide/route_guide_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_client.cc). + +### Creating a stub + +To call service methods, we first need to create a *stub*. + +First we need to create a gRPC *channel* for our stub, specifying the server address and port we want to connect to and any special channel arguments - in our case we'll use the default `ChannelArguments` and no SSL: + +```cpp +grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), ChannelArguments()); +``` + +Now we can use the channel to create our stub using the `NewStub` method provided in the `RouteGuide` class we generated from our .proto. + +```cpp + public: + RouteGuideClient(std::shared_ptr channel, const std::string& db) + : stub_(RouteGuide::NewStub(channel)) { + ... + } +``` + +### Calling service methods + +Now let's look at how we call our service methods. Note that in this tutorial we're calling the *blocking/synchronous* versions of each method: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception. + +#### Simple RPC + +Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. + +```cpp + Point point; + Feature feature; + point = MakePoint(409146138, -746188906); + GetOneFeature(point, &feature); + +... + + bool GetOneFeature(const Point& point, Feature* feature) { + ClientContext context; + Status status = stub_->GetFeature(&context, point, feature); + ... + } +``` + +As you can see, we create and populate a request protocol buffer object (in our case `Point`), and create a response protocol buffer object for the server to fill in. We also create a `ClientContext` object for our call - you can optionally set RPC configuration values on this object, such as deadlines, though for now we'll use the default settings. Note that you cannot reuse this object between calls. Finally, we call the method on the stub, passing it the context, request, and response. If the method returns `OK`, then we can read the response information from the server from our response object. + +```cpp + std::cout << "Found feature called " << feature->name() << " at " + << feature->location().latitude()/kCoordFactor_ << ", " + << feature->location().longitude()/kCoordFactor_ << std::endl; +``` + +#### Streaming RPCs + +Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: + +```cpp + std::unique_ptr > reader( + stub_->ListFeatures(&context, rect)); + while (reader->Read(&feature)) { + std::cout << "Found feature called " + << feature.name() << " at " + << feature.location().latitude()/kCoordFactor_ << ", " + << feature.location().longitude()/kCoordFactor_ << std::endl; + } + Status status = reader->Finish(); +``` + +Instead of passing the method a context, request, and response, we pass it a context and request and get a `ClientReader` object back. The client can use the `ClientReader` to read the server's responses. We use the `ClientReader`s `Read()` method to repeatedly read in the server's responses to a response protocol buffer object (in this case a `Feature`) until there are no more messages: the client needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. Finally, we call `Finish()` on the stream to complete the call and get our RPC status. + +The client-side streaming method `RecordRoute` is similar, except there we pass the method a context and response object and get back a `ClientWriter`. + +```cpp + std::unique_ptr > writer( + stub_->RecordRoute(&context, &stats)); + for (int i = 0; i < kPoints; i++) { + const Feature& f = feature_list_[feature_distribution(generator)]; + std::cout << "Visiting point " + << f.location().latitude()/kCoordFactor_ << ", " + << f.location().longitude()/kCoordFactor_ << std::endl; + if (!writer->Write(f.location())) { + // Broken stream. + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds( + delay_distribution(generator))); + } + writer->WritesDone(); + Status status = writer->Finish(); + if (status.IsOk()) { + std::cout << "Finished trip with " << stats.point_count() << " points\n" + << "Passed " << stats.feature_count() << " features\n" + << "Travelled " << stats.distance() << " meters\n" + << "It took " << stats.elapsed_time() << " seconds" + << std::endl; + } else { + std::cout << "RecordRoute rpc failed." << std::endl; + } +``` + +Once we've finished writing our client's requests to the stream using `Write()`, we need to call `WritesDone()` on the stream to let gRPC know that we've finished writing, then `Finish()` to complete the call and get our RPC status. If the status is `OK`, our response object that we initially passed to `RecordRoute()` will be populated with the server's response. + +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. In this case, we just pass a context to the method and get back a `ClientReaderWriter`, which we can use to both write and read messages. + +```cpp + std::shared_ptr > stream( + stub_->RouteChat(&context)); +``` + +The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + +## Try it out! + +Build client and server: +```shell +$ make +``` +Run the server, which will listen on port 50051: +```shell +$ ./route_guide_server +``` +Run the client (in a different terminal): +```shell +$ ./route_guide_client +``` + diff --git a/grpc-common/cpp/helloworld/Makefile b/grpc-common/cpp/helloworld/Makefile new file mode 100644 index 0000000000..f2093afa05 --- /dev/null +++ b/grpc-common/cpp/helloworld/Makefile @@ -0,0 +1,119 @@ +# +# 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++_unsecure -lgrpc -lgpr -lprotobuf -lpthread -ldl +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` + +PROTOS_PATH = ../../protos + +vpath %.proto $(PROTOS_PATH) + +all: system-check greeter_client greeter_server greeter_async_client greeter_async_server + +greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o + $(CXX) $^ $(LDFLAGS) -o $@ + +greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o + $(CXX) $^ $(LDFLAGS) -o $@ + +greeter_async_client: helloworld.pb.o helloworld.grpc.pb.o greeter_async_client.o + $(CXX) $^ $(LDFLAGS) -o $@ + +greeter_async_server: helloworld.pb.o helloworld.grpc.pb.o greeter_async_server.o + $(CXX) $^ $(LDFLAGS) -o $@ + +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + +clean: + rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server greeter_async_client greeter_async_server + + +# The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + +PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + +SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif + +system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-alpha-1" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif diff --git a/grpc-common/cpp/helloworld/README.md b/grpc-common/cpp/helloworld/README.md new file mode 100644 index 0000000000..c406051e80 --- /dev/null +++ b/grpc-common/cpp/helloworld/README.md @@ -0,0 +1,260 @@ +# gRPC C++ Hello World Tutorial + +### Install gRPC +Make sure you have installed gRPC on your system. Follow the instructions here: +[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). + +### Get the tutorial source code + +The example code for this and our other examples lives in the `grpc-common` +GitHub repository. Clone this repository to your local machine by running the +following command: + + +```sh +$ git clone https://github.com/grpc/grpc-common.git +``` + +Change your current directory to grpc-common/cpp/helloworld + +```sh +$ cd grpc-common/cpp/helloworld/ +``` + +### Defining a service + +The first step in creating our example is to define a *service*: an RPC +service specifies the methods that can be called remotely with their parameters +and return types. As you saw in the +[overview](#protocolbuffers) above, gRPC does this using [protocol +buffers](https://developers.google.com/protocol-buffers/docs/overview). We +use the protocol buffers interface definition language (IDL) to define our +service methods, and define the parameters and return +types as protocol buffer message types. Both the client and the +server use interface code generated from the service definition. + +Here's our example service definition, defined using protocol buffers IDL in +[helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). The `Greeting` +service has one method, `hello`, that lets the server receive a single +`HelloRequest` +message from the remote client containing the user's name, then send back +a greeting in a single `HelloReply`. This is the simplest type of RPC you +can specify in gRPC - we'll look at some other types later in this document. + +``` +syntax = "proto3"; + +option java_package = "ex.grpc"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} + +``` + + +### Generating gRPC code + +Once we've defined our service, we use the protocol buffer compiler +`protoc` to generate the special client and server code we need to create +our application. The generated code contains both stub code for clients to +use and an abstract interface for servers to implement, both with the method +defined in our `Greeting` service. + +To generate the client and server side interfaces: + +```sh +$ make helloworld.grpc.pb.cc helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + +```sh +$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto +``` + +### Writing a client + +- Create a channel. A channel is a logical connection to an endpoint. A gRPC + channel can be created with the target address, credentials to use and + arguments as follows + + ``` + auto channel = CreateChannel("localhost:50051", InsecureCredentials(), ChannelArguments()); + ``` + +- Create a stub. A stub implements the rpc methods of a service and in the + generated code, a method is provided to created a stub with a channel: + + ``` + auto stub = helloworld::Greeter::NewStub(channel); + ``` + +- Make a unary rpc, with `ClientContext` and request/response proto messages. + + ``` + ClientContext context; + HelloRequest request; + request.set_name("hello"); + HelloReply reply; + Status status = stub->SayHello(&context, request, &reply); + ``` + +- Check returned status and response. + + ``` + if (status.ok()) { + // check reply.message() + } else { + // rpc failed. + } + ``` + +For a working example, refer to [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). + +### Writing a server + +- Implement the service interface + + ``` + 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; + } + }; + + ``` + +- Build a server exporting the service + + ``` + GreeterServiceImpl service; + ServerBuilder builder; + builder.AddListeningPort("0.0.0.0:50051", grpc::InsecureServerCredentials()); + builder.RegisterService(&service); + std::unique_ptr server(builder.BuildAndStart()); + ``` + +For a working example, refer to [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). + +### Writing asynchronous client and server + +gRPC uses `CompletionQueue` API for asynchronous operations. The basic work flow +is +- bind a `CompletionQueue` to a rpc call +- do something like a read or write, present with a unique `void*` tag +- call `CompletionQueue::Next` to wait for operations to complete. If a tag + appears, it indicates that the corresponding operation is complete. + +#### Async client + +The channel and stub creation code is the same as the sync client. + +- Initiate the rpc and create a handle for the rpc. Bind the rpc to a + `CompletionQueue`. + + ``` + CompletionQueue cq; + auto rpc = stub->AsyncSayHello(&context, request, &cq); + ``` + +- Ask for reply and final status, with a unique tag + + ``` + Status status; + rpc->Finish(&reply, &status, (void*)1); + ``` + +- Wait for the completion queue to return the next tag. The reply and status are + ready once the tag passed into the corresponding `Finish()` call is returned. + + ``` + void* got_tag; + bool ok = false; + cq.Next(&got_tag, &ok); + if (ok && got_tag == (void*)1) { + // check reply and status + } + ``` + +For a working example, refer to [greeter_async_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_async_client.cc). + +#### Async server + +The server implementation requests a rpc call with a tag and then wait for the +completion queue to return the tag. The basic flow is + +- Build a server exporting the async service + + ``` + helloworld::Greeter::AsyncService service; + ServerBuilder builder; + builder.AddListeningPort("0.0.0.0:50051", InsecureServerCredentials()); + builder.RegisterAsyncService(&service); + auto cq = builder.AddCompletionQueue(); + auto server = builder.BuildAndStart(); + ``` + +- Request one rpc + + ``` + ServerContext context; + HelloRequest request; + ServerAsyncResponseWriter responder; + service.RequestSayHello(&context, &request, &responder, &cq, &cq, (void*)1); + ``` + +- Wait for the completion queue to return the tag. The context, request and + responder are ready once the tag is retrieved. + + ``` + HelloReply reply; + Status status; + void* got_tag; + bool ok = false; + cq.Next(&got_tag, &ok); + if (ok && got_tag == (void*)1) { + // set reply and status + responder.Finish(reply, status, (void*)2); + } + ``` + +- Wait for the completion queue to return the tag. The rpc is finished when the + tag is back. + + ``` + void* got_tag; + bool ok = false; + cq.Next(&got_tag, &ok); + if (ok && got_tag == (void*)2) { + // clean up + } + ``` + +To handle multiple rpcs, the async server creates an object `CallData` to +maintain the state of each rpc and use the address of it as the unique tag. For +simplicity the server only uses one completion queue for all events, and runs a +main loop in `HandleRpcs` to query the queue. + +For a working example, refer to [greeter_async_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_async_server.cc). + + + + diff --git a/grpc-common/cpp/helloworld/greeter_async_client.cc b/grpc-common/cpp/helloworld/greeter_async_client.cc new file mode 100644 index 0000000000..d99f89b135 --- /dev/null +++ b/grpc-common/cpp/helloworld/greeter_async_client.cc @@ -0,0 +1,98 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "helloworld.grpc.pb.h" + +using grpc::Channel; +using grpc::ChannelArguments; +using grpc::ClientAsyncResponseReader; +using grpc::ClientContext; +using grpc::CompletionQueue; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterClient { + public: + explicit GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + std::string SayHello(const std::string& user) { + HelloRequest request; + request.set_name(user); + HelloReply reply; + ClientContext context; + CompletionQueue cq; + Status status; + + std::unique_ptr > rpc( + stub_->AsyncSayHello(&context, request, &cq)); + rpc->Finish(&reply, &status, (void*)1); + void* got_tag; + bool ok = false; + cq.Next(&got_tag, &ok); + GPR_ASSERT(ok); + GPR_ASSERT(got_tag == (void*)1); + + if (status.ok()) { + return reply.message(); + } else { + return "Rpc failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + GreeterClient greeter(grpc::CreateChannel( + "localhost:50051", grpc::InsecureCredentials(), ChannelArguments())); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter received: " << reply << std::endl; + + return 0; +} diff --git a/grpc-common/cpp/helloworld/greeter_async_server.cc b/grpc-common/cpp/helloworld/greeter_async_server.cc new file mode 100644 index 0000000000..b8a0dbf0e2 --- /dev/null +++ b/grpc-common/cpp/helloworld/greeter_async_server.cc @@ -0,0 +1,136 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "helloworld.grpc.pb.h" + +using grpc::Server; +using grpc::ServerAsyncResponseWriter; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::ServerCompletionQueue; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class ServerImpl final { + public: + ~ServerImpl() { + server_->Shutdown(); + cq_->Shutdown(); + } + + // There is no shutdown handling in this code. + void Run() { + std::string server_address("0.0.0.0:50051"); + + ServerBuilder builder; + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + builder.RegisterAsyncService(&service_); + cq_ = builder.AddCompletionQueue(); + server_ = builder.BuildAndStart(); + std::cout << "Server listening on " << server_address << std::endl; + + HandleRpcs(); + } + + private: + class CallData { + public: + CallData(Greeter::AsyncService* service, ServerCompletionQueue* cq) + : service_(service), cq_(cq), responder_(&ctx_), status_(CREATE) { + Proceed(); + } + + void Proceed() { + if (status_ == CREATE) { + service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_, + this); + status_ = PROCESS; + } else if (status_ == PROCESS) { + new CallData(service_, cq_); + std::string prefix("Hello "); + reply_.set_message(prefix + request_.name()); + responder_.Finish(reply_, Status::OK, this); + status_ = FINISH; + } else { + delete this; + } + } + + private: + Greeter::AsyncService* service_; + ServerCompletionQueue* cq_; + ServerContext ctx_; + HelloRequest request_; + HelloReply reply_; + ServerAsyncResponseWriter responder_; + enum CallStatus { CREATE, PROCESS, FINISH }; + CallStatus status_; + }; + + // This can be run in multiple threads if needed. + void HandleRpcs() { + new CallData(&service_, cq_.get()); + void* tag; + bool ok; + while (true) { + cq_->Next(&tag, &ok); + GPR_ASSERT(ok); + static_cast(tag)->Proceed(); + } + } + + std::unique_ptr cq_; + Greeter::AsyncService service_; + std::unique_ptr server_; +}; + +int main(int argc, char** argv) { + ServerImpl server; + server.Run(); + + return 0; +} diff --git a/grpc-common/cpp/helloworld/greeter_client.cc b/grpc-common/cpp/helloworld/greeter_client.cc new file mode 100644 index 0000000000..dd0358ac95 --- /dev/null +++ b/grpc-common/cpp/helloworld/greeter_client.cc @@ -0,0 +1,85 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include "helloworld.grpc.pb.h" + +using grpc::Channel; +using grpc::ChannelArguments; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterClient { + public: + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + std::string SayHello(const std::string& user) { + HelloRequest request; + request.set_name(user); + HelloReply reply; + ClientContext context; + + Status status = stub_->SayHello(&context, request, &reply); + if (status.ok()) { + return reply.message(); + } else { + return "Rpc failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + GreeterClient greeter( + grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), + ChannelArguments())); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter received: " << reply << std::endl; + + return 0; +} diff --git a/grpc-common/cpp/helloworld/greeter_server.cc b/grpc-common/cpp/helloworld/greeter_server.cc new file mode 100644 index 0000000000..c1efdf563c --- /dev/null +++ b/grpc-common/cpp/helloworld/greeter_server.cc @@ -0,0 +1,78 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include "helloworld.grpc.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.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + builder.RegisterService(&service); + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} diff --git a/grpc-common/cpp/route_guide/Makefile b/grpc-common/cpp/route_guide/Makefile new file mode 100644 index 0000000000..b906177af3 --- /dev/null +++ b/grpc-common/cpp/route_guide/Makefile @@ -0,0 +1,113 @@ +# +# 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++_unsecure -lgrpc -lgpr -lprotobuf -lpthread -ldl +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` + +PROTOS_PATH = ../../protos + +vpath %.proto $(PROTOS_PATH) + +all: system-check route_guide_client route_guide_server + +route_guide_client: route_guide.pb.o route_guide.grpc.pb.o route_guide_client.o helper.o + $(CXX) $^ $(LDFLAGS) -o $@ + +route_guide_server: route_guide.pb.o route_guide.grpc.pb.o route_guide_server.o helper.o + $(CXX) $^ $(LDFLAGS) -o $@ + +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + +clean: + rm -f *.o *.pb.cc *.pb.h route_guide_client route_guide_server + + +# The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + +PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + +SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif + +system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-alpha-1" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif diff --git a/grpc-common/cpp/route_guide/helper.cc b/grpc-common/cpp/route_guide/helper.cc new file mode 100644 index 0000000000..c2415afdf7 --- /dev/null +++ b/grpc-common/cpp/route_guide/helper.cc @@ -0,0 +1,178 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "route_guide.grpc.pb.h" + +namespace examples { + +std::string GetDbFileContent(int argc, char** argv) { + std::string db_path; + std::string arg_str("--db_path"); + if (argc > 1) { + std::string argv_1 = argv[1]; + size_t start_position = argv_1.find(arg_str); + if (start_position != std::string::npos) { + start_position += arg_str.size(); + if (argv_1[start_position] == ' ' || + argv_1[start_position] == '=') { + db_path = argv_1.substr(start_position + 1); + } + } + } else { + db_path = "route_guide_db.json"; + } + std::ifstream db_file(db_path); + if (!db_file.is_open()) { + std::cout << "Failed to open " << db_path << std::endl; + return ""; + } + std::stringstream db; + db << db_file.rdbuf(); + return db.str(); +} + +// A simple parser for the json db file. It requires the db file to have the +// exact form of [{"location": { "latitude": 123, "longitude": 456}, "name": +// "the name can be empty" }, { ... } ... The spaces will be stripped. +class Parser { + public: + explicit Parser(const std::string& db) : db_(db) { + // Remove all spaces. + db_.erase( + std::remove_if(db_.begin(), db_.end(), isspace), + db_.end()); + if (!Match("[")) { + SetFailedAndReturnFalse(); + } + } + + bool Finished() { + return current_ >= db_.size(); + } + + bool TryParseOne(Feature* feature) { + if (failed_ || Finished() || !Match("{")) { + return SetFailedAndReturnFalse(); + } + if (!Match(location_) || !Match("{") || !Match(latitude_)) { + return SetFailedAndReturnFalse(); + } + long temp = 0; + ReadLong(&temp); + feature->mutable_location()->set_latitude(temp); + if (!Match(",") || !Match(longitude_)) { + return SetFailedAndReturnFalse(); + } + ReadLong(&temp); + feature->mutable_location()->set_longitude(temp); + if (!Match("},") || !Match(name_) || !Match("\"")) { + return SetFailedAndReturnFalse(); + } + size_t name_start = current_; + while (current_ != db_.size() && db_[current_++] != '"') { + } + if (current_ == db_.size()) { + return SetFailedAndReturnFalse(); + } + feature->set_name(db_.substr(name_start, current_-name_start-1)); + if (!Match("},")) { + if (db_[current_ - 1] == ']' && current_ == db_.size()) { + return true; + } + return SetFailedAndReturnFalse(); + } + return true; + } + + private: + + bool SetFailedAndReturnFalse() { + failed_ = true; + return false; + } + + bool Match(const std::string& prefix) { + bool eq = db_.substr(current_, prefix.size()) == prefix; + current_ += prefix.size(); + return eq; + } + + void ReadLong(long* l) { + size_t start = current_; + while (current_ != db_.size() && db_[current_] != ',' && db_[current_] != '}') { + current_++; + } + // It will throw an exception if fails. + *l = std::stol(db_.substr(start, current_ - start)); + } + + bool failed_ = false; + std::string db_; + size_t current_ = 0; + const std::string location_ = "\"location\":"; + const std::string latitude_ = "\"latitude\":"; + const std::string longitude_ = "\"longitude\":"; + const std::string name_ = "\"name\":"; +}; + +void ParseDb(const std::string& db, std::vector* feature_list) { + feature_list->clear(); + std::string db_content(db); + db_content.erase( + std::remove_if(db_content.begin(), db_content.end(), isspace), + db_content.end()); + + Parser parser(db_content); + Feature feature; + while (!parser.Finished()) { + feature_list->push_back(Feature()); + if (!parser.TryParseOne(&feature_list->back())) { + std::cout << "Error parsing the db file"; + feature_list->clear(); + break; + } + } + std::cout << "DB parsed, loaded " << feature_list->size() + << " features." << std::endl; +} + + +} // namespace examples + diff --git a/grpc-common/cpp/route_guide/helper.h b/grpc-common/cpp/route_guide/helper.h new file mode 100644 index 0000000000..65c93c1d34 --- /dev/null +++ b/grpc-common/cpp/route_guide/helper.h @@ -0,0 +1,50 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_ +#define GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_ + +#include +#include + +namespace examples { +class Feature; + +std::string GetDbFileContent(int argc, char** argv); + +void ParseDb(const std::string& db, std::vector* feature_list); + +} // namespace examples + +#endif // GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_ + diff --git a/grpc-common/cpp/route_guide/route_guide_client.cc b/grpc-common/cpp/route_guide/route_guide_client.cc new file mode 100644 index 0000000000..814def27f3 --- /dev/null +++ b/grpc-common/cpp/route_guide/route_guide_client.cc @@ -0,0 +1,252 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "helper.h" +#include "route_guide.grpc.pb.h" + +using grpc::Channel; +using grpc::ChannelArguments; +using grpc::ClientContext; +using grpc::ClientReader; +using grpc::ClientReaderWriter; +using grpc::ClientWriter; +using grpc::Status; +using examples::Point; +using examples::Feature; +using examples::Rectangle; +using examples::RouteSummary; +using examples::RouteNote; +using examples::RouteGuide; + +Point MakePoint(long latitude, long longitude) { + Point p; + p.set_latitude(latitude); + p.set_longitude(longitude); + return p; +} + +Feature MakeFeature(const std::string& name, + long latitude, long longitude) { + Feature f; + f.set_name(name); + f.mutable_location()->CopyFrom(MakePoint(latitude, longitude)); + return f; +} + +RouteNote MakeRouteNote(const std::string& message, + long latitude, long longitude) { + RouteNote n; + n.set_message(message); + n.mutable_location()->CopyFrom(MakePoint(latitude, longitude)); + return n; +} + +class RouteGuideClient { + public: + RouteGuideClient(std::shared_ptr channel, const std::string& db) + : stub_(RouteGuide::NewStub(channel)) { + examples::ParseDb(db, &feature_list_); + } + + void GetFeature() { + Point point; + Feature feature; + point = MakePoint(409146138, -746188906); + GetOneFeature(point, &feature); + point = MakePoint(0, 0); + GetOneFeature(point, &feature); + } + + void ListFeatures() { + examples::Rectangle rect; + Feature feature; + ClientContext context; + + rect.mutable_lo()->set_latitude(400000000); + rect.mutable_lo()->set_longitude(-750000000); + rect.mutable_hi()->set_latitude(420000000); + rect.mutable_hi()->set_longitude(-730000000); + std::cout << "Looking for features between 40, -75 and 42, -73" + << std::endl; + + std::unique_ptr > reader( + stub_->ListFeatures(&context, rect)); + while (reader->Read(&feature)) { + std::cout << "Found feature called " + << feature.name() << " at " + << feature.location().latitude()/kCoordFactor_ << ", " + << feature.location().longitude()/kCoordFactor_ << std::endl; + } + Status status = reader->Finish(); + if (status.ok()) { + std::cout << "ListFeatures rpc succeeded." << std::endl; + } else { + std::cout << "ListFeatures rpc failed." << std::endl; + } + } + + void RecordRoute() { + Point point; + RouteSummary stats; + ClientContext context; + const int kPoints = 10; + unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); + + std::default_random_engine generator(seed); + std::uniform_int_distribution feature_distribution( + 0, feature_list_.size() - 1); + std::uniform_int_distribution delay_distribution( + 500, 1500); + + std::unique_ptr > writer( + stub_->RecordRoute(&context, &stats)); + for (int i = 0; i < kPoints; i++) { + const Feature& f = feature_list_[feature_distribution(generator)]; + std::cout << "Visiting point " + << f.location().latitude()/kCoordFactor_ << ", " + << f.location().longitude()/kCoordFactor_ << std::endl; + if (!writer->Write(f.location())) { + // Broken stream. + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds( + delay_distribution(generator))); + } + writer->WritesDone(); + Status status = writer->Finish(); + if (status.ok()) { + std::cout << "Finished trip with " << stats.point_count() << " points\n" + << "Passed " << stats.feature_count() << " features\n" + << "Travelled " << stats.distance() << " meters\n" + << "It took " << stats.elapsed_time() << " seconds" + << std::endl; + } else { + std::cout << "RecordRoute rpc failed." << std::endl; + } + } + + void RouteChat() { + ClientContext context; + + std::shared_ptr > stream( + stub_->RouteChat(&context)); + + std::thread writer([stream]() { + std::vector notes{ + MakeRouteNote("First message", 0, 0), + MakeRouteNote("Second message", 0, 1), + MakeRouteNote("Third message", 1, 0), + MakeRouteNote("Fourth message", 0, 0)}; + for (const RouteNote& note : notes) { + std::cout << "Sending message " << note.message() + << " at " << note.location().latitude() << ", " + << note.location().longitude() << std::endl; + stream->Write(note); + } + stream->WritesDone(); + }); + + RouteNote server_note; + while (stream->Read(&server_note)) { + std::cout << "Got message " << server_note.message() + << " at " << server_note.location().latitude() << ", " + << server_note.location().longitude() << std::endl; + } + writer.join(); + Status status = stream->Finish(); + if (!status.ok()) { + std::cout << "RouteChat rpc failed." << std::endl; + } + } + + private: + + bool GetOneFeature(const Point& point, Feature* feature) { + ClientContext context; + Status status = stub_->GetFeature(&context, point, feature); + if (!status.ok()) { + std::cout << "GetFeature rpc failed." << std::endl; + return false; + } + if (!feature->has_location()) { + std::cout << "Server returns incomplete feature." << std::endl; + return false; + } + if (feature->name().empty()) { + std::cout << "Found no feature at " + << feature->location().latitude()/kCoordFactor_ << ", " + << feature->location().longitude()/kCoordFactor_ << std::endl; + } else { + std::cout << "Found feature called " << feature->name() << " at " + << feature->location().latitude()/kCoordFactor_ << ", " + << feature->location().longitude()/kCoordFactor_ << std::endl; + } + return true; + } + + const float kCoordFactor_ = 10000000.0; + std::unique_ptr stub_; + std::vector feature_list_; +}; + +int main(int argc, char** argv) { + // Expect only arg: --db_path=path/to/route_guide_db.json. + std::string db = examples::GetDbFileContent(argc, argv); + RouteGuideClient guide( + grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), + ChannelArguments()), + db); + + std::cout << "-------------- GetFeature --------------" << std::endl; + guide.GetFeature(); + std::cout << "-------------- ListFeatures --------------" << std::endl; + guide.ListFeatures(); + std::cout << "-------------- RecordRoute --------------" << std::endl; + guide.RecordRoute(); + std::cout << "-------------- RouteChat --------------" << std::endl; + guide.RouteChat(); + + return 0; +} diff --git a/grpc-common/cpp/route_guide/route_guide_db.json b/grpc-common/cpp/route_guide/route_guide_db.json new file mode 100644 index 0000000000..9d6a980ab7 --- /dev/null +++ b/grpc-common/cpp/route_guide/route_guide_db.json @@ -0,0 +1,601 @@ +[{ + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" +}, { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" +}, { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" +}, { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" +}, { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" +}, { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" +}, { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" +}, { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" +}, { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" +}, { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" +}, { + "location": { + "latitude": 415736605, + "longitude": -742847522 + }, + "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" +}, { + "location": { + "latitude": 413843930, + "longitude": -740501726 + }, + "name": "162 Merrill Road, Highland Mills, NY 10930, USA" +}, { + "location": { + "latitude": 410873075, + "longitude": -744459023 + }, + "name": "Clinton Road, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 412346009, + "longitude": -744026814 + }, + "name": "16 Old Brook Lane, Warwick, NY 10990, USA" +}, { + "location": { + "latitude": 402948455, + "longitude": -747903913 + }, + "name": "3 Drake Lane, Pennington, NJ 08534, USA" +}, { + "location": { + "latitude": 406337092, + "longitude": -740122226 + }, + "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" +}, { + "location": { + "latitude": 406421967, + "longitude": -747727624 + }, + "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" +}, { + "location": { + "latitude": 416318082, + "longitude": -749677716 + }, + "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" +}, { + "location": { + "latitude": 415301720, + "longitude": -748416257 + }, + "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" +}, { + "location": { + "latitude": 402647019, + "longitude": -747071791 + }, + "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" +}, { + "location": { + "latitude": 412567807, + "longitude": -741058078 + }, + "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" +}, { + "location": { + "latitude": 416855156, + "longitude": -744420597 + }, + "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" +}, { + "location": { + "latitude": 404663628, + "longitude": -744820157 + }, + "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" +}, { + "location": { + "latitude": 407113723, + "longitude": -749746483 + }, + "name": "" +}, { + "location": { + "latitude": 402133926, + "longitude": -743613249 + }, + "name": "" +}, { + "location": { + "latitude": 400273442, + "longitude": -741220915 + }, + "name": "" +}, { + "location": { + "latitude": 411236786, + "longitude": -744070769 + }, + "name": "" +}, { + "location": { + "latitude": 411633782, + "longitude": -746784970 + }, + "name": "211-225 Plains Road, Augusta, NJ 07822, USA" +}, { + "location": { + "latitude": 415830701, + "longitude": -742952812 + }, + "name": "" +}, { + "location": { + "latitude": 413447164, + "longitude": -748712898 + }, + "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" +}, { + "location": { + "latitude": 405047245, + "longitude": -749800722 + }, + "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" +}, { + "location": { + "latitude": 418858923, + "longitude": -746156790 + }, + "name": "" +}, { + "location": { + "latitude": 417951888, + "longitude": -748484944 + }, + "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" +}, { + "location": { + "latitude": 407033786, + "longitude": -743977337 + }, + "name": "26 East 3rd Street, New Providence, NJ 07974, USA" +}, { + "location": { + "latitude": 417548014, + "longitude": -740075041 + }, + "name": "" +}, { + "location": { + "latitude": 410395868, + "longitude": -744972325 + }, + "name": "" +}, { + "location": { + "latitude": 404615353, + "longitude": -745129803 + }, + "name": "" +}, { + "location": { + "latitude": 406589790, + "longitude": -743560121 + }, + "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" +}, { + "location": { + "latitude": 414653148, + "longitude": -740477477 + }, + "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" +}, { + "location": { + "latitude": 405957808, + "longitude": -743255336 + }, + "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" +}, { + "location": { + "latitude": 411733589, + "longitude": -741648093 + }, + "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" +}, { + "location": { + "latitude": 412676291, + "longitude": -742606606 + }, + "name": "1270 Lakes Road, Monroe, NY 10950, USA" +}, { + "location": { + "latitude": 409224445, + "longitude": -748286738 + }, + "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" +}, { + "location": { + "latitude": 406523420, + "longitude": -742135517 + }, + "name": "652 Garden Street, Elizabeth, NJ 07202, USA" +}, { + "location": { + "latitude": 401827388, + "longitude": -740294537 + }, + "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" +}, { + "location": { + "latitude": 410564152, + "longitude": -743685054 + }, + "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 408472324, + "longitude": -740726046 + }, + "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" +}, { + "location": { + "latitude": 412452168, + "longitude": -740214052 + }, + "name": "5 White Oak Lane, Stony Point, NY 10980, USA" +}, { + "location": { + "latitude": 409146138, + "longitude": -746188906 + }, + "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" +}, { + "location": { + "latitude": 404701380, + "longitude": -744781745 + }, + "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 409642566, + "longitude": -746017679 + }, + "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" +}, { + "location": { + "latitude": 408031728, + "longitude": -748645385 + }, + "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" +}, { + "location": { + "latitude": 413700272, + "longitude": -742135189 + }, + "name": "367 Prospect Road, Chester, NY 10918, USA" +}, { + "location": { + "latitude": 404310607, + "longitude": -740282632 + }, + "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" +}, { + "location": { + "latitude": 409319800, + "longitude": -746201391 + }, + "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" +}, { + "location": { + "latitude": 406685311, + "longitude": -742108603 + }, + "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" +}, { + "location": { + "latitude": 419018117, + "longitude": -749142781 + }, + "name": "43 Dreher Road, Roscoe, NY 12776, USA" +}, { + "location": { + "latitude": 412856162, + "longitude": -745148837 + }, + "name": "Swan Street, Pine Island, NY 10969, USA" +}, { + "location": { + "latitude": 416560744, + "longitude": -746721964 + }, + "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" +}, { + "location": { + "latitude": 405314270, + "longitude": -749836354 + }, + "name": "" +}, { + "location": { + "latitude": 414219548, + "longitude": -743327440 + }, + "name": "" +}, { + "location": { + "latitude": 415534177, + "longitude": -742900616 + }, + "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" +}, { + "location": { + "latitude": 406898530, + "longitude": -749127080 + }, + "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" +}, { + "location": { + "latitude": 407586880, + "longitude": -741670168 + }, + "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" +}, { + "location": { + "latitude": 400106455, + "longitude": -742870190 + }, + "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" +}, { + "location": { + "latitude": 400066188, + "longitude": -746793294 + }, + "name": "" +}, { + "location": { + "latitude": 418803880, + "longitude": -744102673 + }, + "name": "40 Mountain Road, Napanoch, NY 12458, USA" +}, { + "location": { + "latitude": 414204288, + "longitude": -747895140 + }, + "name": "" +}, { + "location": { + "latitude": 414777405, + "longitude": -740615601 + }, + "name": "" +}, { + "location": { + "latitude": 415464475, + "longitude": -747175374 + }, + "name": "48 North Road, Forestburgh, NY 12777, USA" +}, { + "location": { + "latitude": 404062378, + "longitude": -746376177 + }, + "name": "" +}, { + "location": { + "latitude": 405688272, + "longitude": -749285130 + }, + "name": "" +}, { + "location": { + "latitude": 400342070, + "longitude": -748788996 + }, + "name": "" +}, { + "location": { + "latitude": 401809022, + "longitude": -744157964 + }, + "name": "" +}, { + "location": { + "latitude": 404226644, + "longitude": -740517141 + }, + "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" +}, { + "location": { + "latitude": 410322033, + "longitude": -747871659 + }, + "name": "" +}, { + "location": { + "latitude": 407100674, + "longitude": -747742727 + }, + "name": "" +}, { + "location": { + "latitude": 418811433, + "longitude": -741718005 + }, + "name": "213 Bush Road, Stone Ridge, NY 12484, USA" +}, { + "location": { + "latitude": 415034302, + "longitude": -743850945 + }, + "name": "" +}, { + "location": { + "latitude": 411349992, + "longitude": -743694161 + }, + "name": "" +}, { + "location": { + "latitude": 404839914, + "longitude": -744759616 + }, + "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 414638017, + "longitude": -745957854 + }, + "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" +}, { + "location": { + "latitude": 412127800, + "longitude": -740173578 + }, + "name": "" +}, { + "location": { + "latitude": 401263460, + "longitude": -747964303 + }, + "name": "" +}, { + "location": { + "latitude": 412843391, + "longitude": -749086026 + }, + "name": "" +}, { + "location": { + "latitude": 418512773, + "longitude": -743067823 + }, + "name": "" +}, { + "location": { + "latitude": 404318328, + "longitude": -740835638 + }, + "name": "42-102 Main Street, Belford, NJ 07718, USA" +}, { + "location": { + "latitude": 419020746, + "longitude": -741172328 + }, + "name": "" +}, { + "location": { + "latitude": 404080723, + "longitude": -746119569 + }, + "name": "" +}, { + "location": { + "latitude": 401012643, + "longitude": -744035134 + }, + "name": "" +}, { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" +}, { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" +}, { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" +}, { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" +}, { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" +}, { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" +}, { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" +}, { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" +}, { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" +}, { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" +}] diff --git a/grpc-common/cpp/route_guide/route_guide_server.cc b/grpc-common/cpp/route_guide/route_guide_server.cc new file mode 100644 index 0000000000..b37539299a --- /dev/null +++ b/grpc-common/cpp/route_guide/route_guide_server.cc @@ -0,0 +1,202 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "helper.h" +#include "route_guide.grpc.pb.h" + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::ServerReader; +using grpc::ServerReaderWriter; +using grpc::ServerWriter; +using grpc::Status; +using examples::Point; +using examples::Feature; +using examples::Rectangle; +using examples::RouteSummary; +using examples::RouteNote; +using examples::RouteGuide; +using std::chrono::system_clock; + + +float ConvertToRadians(float num) { + return num * 3.1415926 /180; +} + +float GetDistance(const Point& start, const Point& end) { + const float kCoordFactor = 10000000.0; + float lat_1 = start.latitude() / kCoordFactor; + float lat_2 = end.latitude() / kCoordFactor; + float lon_1 = start.longitude() / kCoordFactor; + float lon_2 = end.longitude() / kCoordFactor; + float lat_rad_1 = ConvertToRadians(lat_1); + float lat_rad_2 = ConvertToRadians(lat_2); + float delta_lat_rad = ConvertToRadians(lat_2-lat_1); + float delta_lon_rad = ConvertToRadians(lon_2-lon_1); + + float a = pow(sin(delta_lat_rad/2), 2) + cos(lat_rad_1) * cos(lat_rad_2) * + pow(sin(delta_lon_rad/2), 2); + float c = 2 * atan2(sqrt(a), sqrt(1-a)); + int R = 6371000; // metres + + return R * c; +} + +std::string GetFeatureName(const Point& point, + const std::vector& feature_list) { + for (const Feature& f : feature_list) { + if (f.location().latitude() == point.latitude() && + f.location().longitude() == point.longitude()) { + return f.name(); + } + } + return ""; +} + +class RouteGuideImpl final : public RouteGuide::Service { + public: + explicit RouteGuideImpl(const std::string& db) { + examples::ParseDb(db, &feature_list_); + } + + Status GetFeature(ServerContext* context, const Point* point, + Feature* feature) override { + feature->set_name(GetFeatureName(*point, feature_list_)); + feature->mutable_location()->CopyFrom(*point); + return Status::OK; + } + + Status ListFeatures(ServerContext* context, + const examples::Rectangle* rectangle, + ServerWriter* writer) override { + auto lo = rectangle->lo(); + auto hi = rectangle->hi(); + long left = (std::min)(lo.longitude(), hi.longitude()); + long right = (std::max)(lo.longitude(), hi.longitude()); + long top = (std::max)(lo.latitude(), hi.latitude()); + long bottom = (std::min)(lo.latitude(), hi.latitude()); + for (const Feature& f : feature_list_) { + if (f.location().longitude() >= left && + f.location().longitude() <= right && + f.location().latitude() >= bottom && + f.location().latitude() <= top) { + writer->Write(f); + } + } + return Status::OK; + } + + Status RecordRoute(ServerContext* context, ServerReader* reader, + RouteSummary* summary) override { + Point point; + int point_count = 0; + int feature_count = 0; + float distance = 0.0; + Point previous; + + system_clock::time_point start_time = system_clock::now(); + while (reader->Read(&point)) { + point_count++; + if (!GetFeatureName(point, feature_list_).empty()) { + feature_count++; + } + if (point_count != 1) { + distance += GetDistance(previous, point); + } + previous = point; + } + system_clock::time_point end_time = system_clock::now(); + summary->set_point_count(point_count); + summary->set_feature_count(feature_count); + summary->set_distance(static_cast(distance)); + auto secs = std::chrono::duration_cast( + end_time - start_time); + summary->set_elapsed_time(secs.count()); + + return Status::OK; + } + + Status RouteChat(ServerContext* context, + ServerReaderWriter* stream) override { + std::vector received_notes; + RouteNote note; + while (stream->Read(¬e)) { + for (const RouteNote& n : received_notes) { + if (n.location().latitude() == note.location().latitude() && + n.location().longitude() == note.location().longitude()) { + stream->Write(n); + } + } + received_notes.push_back(note); + } + + return Status::OK; + } + + private: + + std::vector feature_list_; +}; + +void RunServer(const std::string& db_path) { + std::string server_address("0.0.0.0:50051"); + RouteGuideImpl service(db_path); + + ServerBuilder builder; + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + builder.RegisterService(&service); + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + server->Wait(); +} + +int main(int argc, char** argv) { + // Expect only arg: --db_path=path/to/route_guide_db.json. + std::string db = examples::GetDbFileContent(argc, argv); + RunServer(db); + + return 0; +} diff --git a/grpc-common/csharp/.gitignore b/grpc-common/csharp/.gitignore new file mode 100644 index 0000000000..585000ea2d --- /dev/null +++ b/grpc-common/csharp/.gitignore @@ -0,0 +1,5 @@ +bin/ +obj/ +packages/ +*.suo +*.userprefs diff --git a/grpc-common/csharp/.nuget/packages.config b/grpc-common/csharp/.nuget/packages.config new file mode 100644 index 0000000000..b14373069f --- /dev/null +++ b/grpc-common/csharp/.nuget/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/grpc-common/csharp/Greeter.sln b/grpc-common/csharp/Greeter.sln new file mode 100644 index 0000000000..9430e94de9 --- /dev/null +++ b/grpc-common/csharp/Greeter.sln @@ -0,0 +1,42 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Greeter", "Greeter\Greeter.csproj", "{724DFC8C-4B57-4C3F-811C-0463BE2A2829}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterServer", "GreeterServer\GreeterServer.csproj", "{A7706C84-92D2-4B7A-B779-76B64D2950EC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterClient", "GreeterClient\GreeterClient.csproj", "{ACCF4597-3748-4117-8633-1CB767F8CCC3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{FF1EBE95-F20D-4C27-8A61-D0125F3C8152}" + ProjectSection(SolutionItems) = preProject + .nuget\packages.config = .nuget\packages.config + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Debug|Any CPU.Build.0 = Debug|Any CPU + {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Release|Any CPU.ActiveCfg = Release|Any CPU + {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Release|Any CPU.Build.0 = Release|Any CPU + {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Release|Any CPU.Build.0 = Release|Any CPU + {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = Greeter\Greeter.csproj + EndGlobalSection +EndGlobal diff --git a/grpc-common/csharp/Greeter/.gitignore b/grpc-common/csharp/Greeter/.gitignore new file mode 100644 index 0000000000..1746e3269e --- /dev/null +++ b/grpc-common/csharp/Greeter/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/grpc-common/csharp/Greeter/Greeter.csproj b/grpc-common/csharp/Greeter/Greeter.csproj new file mode 100644 index 0000000000..b8f965dbd2 --- /dev/null +++ b/grpc-common/csharp/Greeter/Greeter.csproj @@ -0,0 +1,81 @@ + + + + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {724DFC8C-4B57-4C3F-811C-0463BE2A2829} + Library + Greeter + Greeter + v4.5 + 927432a0 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + full + true + bin\Release + prompt + 4 + false + + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll + + + False + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll + + + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + \ No newline at end of file diff --git a/grpc-common/csharp/Greeter/Helloworld.cs b/grpc-common/csharp/Greeter/Helloworld.cs new file mode 100644 index 0000000000..923a4271e9 --- /dev/null +++ b/grpc-common/csharp/Greeter/Helloworld.cs @@ -0,0 +1,617 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.ProtocolBuffers; +using pbc = global::Google.ProtocolBuffers.Collections; +using pbd = global::Google.ProtocolBuffers.Descriptors; +using scg = global::System.Collections.Generic; +namespace helloworld { + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public static partial class Helloworld { + + #region Extension registration + public static void RegisterAllExtensions(pb::ExtensionRegistry registry) { + } + #endregion + #region Static variables + internal static pbd::MessageDescriptor internal__static_helloworld_HelloRequest__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_helloworld_HelloRequest__FieldAccessorTable; + internal static pbd::MessageDescriptor internal__static_helloworld_HelloReply__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_helloworld_HelloReply__FieldAccessorTable; + #endregion + #region Descriptor + public static pbd::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbd::FileDescriptor descriptor; + + static Helloworld() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz", + "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo", + "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl", + "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEISChBpby5ncnBjLmV4", + "YW1wbGVz")); + pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) { + descriptor = root; + internal__static_helloworld_HelloRequest__Descriptor = Descriptor.MessageTypes[0]; + internal__static_helloworld_HelloRequest__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_helloworld_HelloRequest__Descriptor, + new string[] { "Name", }); + internal__static_helloworld_HelloReply__Descriptor = Descriptor.MessageTypes[1]; + internal__static_helloworld_HelloReply__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_helloworld_HelloReply__Descriptor, + new string[] { "Message", }); + pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance(); + RegisterAllExtensions(registry); + return registry; + }; + pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData, + new pbd::FileDescriptor[] { + }, assigner); + } + #endregion + + } + #region Messages + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class HelloRequest : pb::GeneratedMessage { + private HelloRequest() { } + private static readonly HelloRequest defaultInstance = new HelloRequest().MakeReadOnly(); + private static readonly string[] _helloRequestFieldNames = new string[] { "name" }; + private static readonly uint[] _helloRequestFieldTags = new uint[] { 10 }; + public static HelloRequest DefaultInstance { + get { return defaultInstance; } + } + + public override HelloRequest DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override HelloRequest ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::helloworld.Helloworld.internal__static_helloworld_HelloRequest__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::helloworld.Helloworld.internal__static_helloworld_HelloRequest__FieldAccessorTable; } + } + + public const int NameFieldNumber = 1; + private bool hasName; + private string name_ = ""; + public bool HasName { + get { return hasName; } + } + public string Name { + get { return name_; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _helloRequestFieldNames; + if (hasName) { + output.WriteString(1, field_names[0], Name); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasName) { + size += pb::CodedOutputStream.ComputeStringSize(1, Name); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static HelloRequest ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static HelloRequest ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static HelloRequest ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static HelloRequest ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static HelloRequest ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static HelloRequest ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static HelloRequest ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static HelloRequest ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static HelloRequest ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static HelloRequest ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private HelloRequest MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(HelloRequest prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(HelloRequest cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private HelloRequest result; + + private HelloRequest PrepareBuilder() { + if (resultIsReadOnly) { + HelloRequest original = result; + result = new HelloRequest(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override HelloRequest MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::helloworld.HelloRequest.Descriptor; } + } + + public override HelloRequest DefaultInstanceForType { + get { return global::helloworld.HelloRequest.DefaultInstance; } + } + + public override HelloRequest BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is HelloRequest) { + return MergeFrom((HelloRequest) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(HelloRequest other) { + if (other == global::helloworld.HelloRequest.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasName) { + Name = other.Name; + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_helloRequestFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _helloRequestFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 10: { + result.hasName = input.ReadString(ref result.name_); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasName { + get { return result.hasName; } + } + public string Name { + get { return result.Name; } + set { SetName(value); } + } + public Builder SetName(string value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasName = true; + result.name_ = value; + return this; + } + public Builder ClearName() { + PrepareBuilder(); + result.hasName = false; + result.name_ = ""; + return this; + } + } + static HelloRequest() { + object.ReferenceEquals(global::helloworld.Helloworld.Descriptor, null); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class HelloReply : pb::GeneratedMessage { + private HelloReply() { } + private static readonly HelloReply defaultInstance = new HelloReply().MakeReadOnly(); + private static readonly string[] _helloReplyFieldNames = new string[] { "message" }; + private static readonly uint[] _helloReplyFieldTags = new uint[] { 10 }; + public static HelloReply DefaultInstance { + get { return defaultInstance; } + } + + public override HelloReply DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override HelloReply ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::helloworld.Helloworld.internal__static_helloworld_HelloReply__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::helloworld.Helloworld.internal__static_helloworld_HelloReply__FieldAccessorTable; } + } + + public const int MessageFieldNumber = 1; + private bool hasMessage; + private string message_ = ""; + public bool HasMessage { + get { return hasMessage; } + } + public string Message { + get { return message_; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _helloReplyFieldNames; + if (hasMessage) { + output.WriteString(1, field_names[0], Message); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasMessage) { + size += pb::CodedOutputStream.ComputeStringSize(1, Message); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static HelloReply ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static HelloReply ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static HelloReply ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static HelloReply ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static HelloReply ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static HelloReply ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static HelloReply ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static HelloReply ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static HelloReply ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static HelloReply ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private HelloReply MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(HelloReply prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(HelloReply cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private HelloReply result; + + private HelloReply PrepareBuilder() { + if (resultIsReadOnly) { + HelloReply original = result; + result = new HelloReply(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override HelloReply MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::helloworld.HelloReply.Descriptor; } + } + + public override HelloReply DefaultInstanceForType { + get { return global::helloworld.HelloReply.DefaultInstance; } + } + + public override HelloReply BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is HelloReply) { + return MergeFrom((HelloReply) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(HelloReply other) { + if (other == global::helloworld.HelloReply.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasMessage) { + Message = other.Message; + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_helloReplyFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _helloReplyFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 10: { + result.hasMessage = input.ReadString(ref result.message_); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasMessage { + get { return result.hasMessage; } + } + public string Message { + get { return result.Message; } + set { SetMessage(value); } + } + public Builder SetMessage(string value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasMessage = true; + result.message_ = value; + return this; + } + public Builder ClearMessage() { + PrepareBuilder(); + result.hasMessage = false; + result.message_ = ""; + return this; + } + } + static HelloReply() { + object.ReferenceEquals(global::helloworld.Helloworld.Descriptor, null); + } + } + + #endregion + +} + +#endregion Designer generated code diff --git a/grpc-common/csharp/Greeter/HelloworldGrpc.cs b/grpc-common/csharp/Greeter/HelloworldGrpc.cs new file mode 100644 index 0000000000..1ca9d2899b --- /dev/null +++ b/grpc-common/csharp/Greeter/HelloworldGrpc.cs @@ -0,0 +1,78 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto +#region Designer generated code + +using System; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; + +namespace helloworld { + public static class Greeter + { + static readonly string __ServiceName = "helloworld.Greeter"; + + static readonly Marshaller __Marshaller_HelloRequest = Marshallers.Create((arg) => arg.ToByteArray(), global::helloworld.HelloRequest.ParseFrom); + static readonly Marshaller __Marshaller_HelloReply = Marshallers.Create((arg) => arg.ToByteArray(), global::helloworld.HelloReply.ParseFrom); + + static readonly Method __Method_SayHello = new Method( + MethodType.Unary, + "SayHello", + __Marshaller_HelloRequest, + __Marshaller_HelloReply); + + // client-side stub interface + public interface IGreeterClient + { + global::helloworld.HelloReply SayHello(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)); + Task SayHelloAsync(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)); + } + + // server-side interface + public interface IGreeter + { + Task SayHello(ServerCallContext context, global::helloworld.HelloRequest request); + } + + // client stub + public class GreeterClient : AbstractStub, IGreeterClient + { + public GreeterClient(Channel channel) : this(channel, StubConfiguration.Default) + { + } + public GreeterClient(Channel channel, StubConfiguration config) : base(channel, config) + { + } + public global::helloworld.HelloReply SayHello(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_SayHello); + return Calls.BlockingUnaryCall(call, request, token); + } + public Task SayHelloAsync(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_SayHello); + return Calls.AsyncUnaryCall(call, request, token); + } + } + + // creates service definition that can be registered with a server + public static ServerServiceDefinition BindService(IGreeter serviceImpl) + { + return ServerServiceDefinition.CreateBuilder(__ServiceName) + .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build(); + } + + // creates a new client stub + public static IGreeterClient NewStub(Channel channel) + { + return new GreeterClient(channel); + } + + // creates a new client stub + public static IGreeterClient NewStub(Channel channel, StubConfiguration config) + { + return new GreeterClient(channel, config); + } + } +} +#endregion diff --git a/grpc-common/csharp/Greeter/Properties/AssemblyInfo.cs b/grpc-common/csharp/Greeter/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..b9d0dc264d --- /dev/null +++ b/grpc-common/csharp/Greeter/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle("Greeter")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("jtattermusch")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/grpc-common/csharp/Greeter/packages.config b/grpc-common/csharp/Greeter/packages.config new file mode 100644 index 0000000000..5922553bc3 --- /dev/null +++ b/grpc-common/csharp/Greeter/packages.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/grpc-common/csharp/Greeter/protos/helloworld.proto b/grpc-common/csharp/Greeter/protos/helloworld.proto new file mode 100644 index 0000000000..e02ebd94e7 --- /dev/null +++ b/grpc-common/csharp/Greeter/protos/helloworld.proto @@ -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. + +// TODO(jtattermusch): as of now, C# protobufs don't officially support +// proto3. +syntax = "proto2"; + +option java_package = "io.grpc.examples"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + optional string name = 1; +} + +// The response message containing the greetings +message HelloReply { + optional string message = 1; +} diff --git a/grpc-common/csharp/GreeterClient/.gitignore b/grpc-common/csharp/GreeterClient/.gitignore new file mode 100644 index 0000000000..1746e3269e --- /dev/null +++ b/grpc-common/csharp/GreeterClient/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/grpc-common/csharp/GreeterClient/GreeterClient.csproj b/grpc-common/csharp/GreeterClient/GreeterClient.csproj new file mode 100644 index 0000000000..59b768af01 --- /dev/null +++ b/grpc-common/csharp/GreeterClient/GreeterClient.csproj @@ -0,0 +1,84 @@ + + + + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {ACCF4597-3748-4117-8633-1CB767F8CCC3} + Exe + GreeterClient + GreeterClient + v4.5 + 985ca8be + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + true + + + full + true + bin\Release + prompt + 4 + true + + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll + + + False + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll + + + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll + + + + + + + + + + {724DFC8C-4B57-4C3F-811C-0463BE2A2829} + Greeter + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + \ No newline at end of file diff --git a/grpc-common/csharp/GreeterClient/Program.cs b/grpc-common/csharp/GreeterClient/Program.cs new file mode 100644 index 0000000000..61c29762b1 --- /dev/null +++ b/grpc-common/csharp/GreeterClient/Program.cs @@ -0,0 +1,25 @@ +using System; +using Grpc.Core; +using helloworld; + +namespace GreeterClient +{ + class ClientMainClass + { + public static void Main(string[] args) + { + GrpcEnvironment.Initialize(); + + using (Channel channel = new Channel("127.0.0.1:50051")) + { + var client = Greeter.NewStub(channel); + String user = "you"; + + var reply = client.SayHello(new HelloRequest.Builder { Name = user }.Build()); + Console.WriteLine("Greeting: " + reply.Message); + } + + GrpcEnvironment.Shutdown(); + } + } +} diff --git a/grpc-common/csharp/GreeterClient/Properties/AssemblyInfo.cs b/grpc-common/csharp/GreeterClient/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..1422e952d8 --- /dev/null +++ b/grpc-common/csharp/GreeterClient/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle("GreeterClient")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("jtattermusch")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/grpc-common/csharp/GreeterClient/packages.config b/grpc-common/csharp/GreeterClient/packages.config new file mode 100644 index 0000000000..5922553bc3 --- /dev/null +++ b/grpc-common/csharp/GreeterClient/packages.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/grpc-common/csharp/GreeterServer/.gitignore b/grpc-common/csharp/GreeterServer/.gitignore new file mode 100644 index 0000000000..1746e3269e --- /dev/null +++ b/grpc-common/csharp/GreeterServer/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/grpc-common/csharp/GreeterServer/GreeterServer.csproj b/grpc-common/csharp/GreeterServer/GreeterServer.csproj new file mode 100644 index 0000000000..cd50d6cd52 --- /dev/null +++ b/grpc-common/csharp/GreeterServer/GreeterServer.csproj @@ -0,0 +1,84 @@ + + + + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {A7706C84-92D2-4B7A-B779-76B64D2950EC} + Exe + GreeterServer + GreeterServer + v4.5 + a1eeb1d8 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + true + + + full + true + bin\Release + prompt + 4 + true + + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll + + + False + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll + + + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll + + + + + + + + + + {724DFC8C-4B57-4C3F-811C-0463BE2A2829} + Greeter + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + \ No newline at end of file diff --git a/grpc-common/csharp/GreeterServer/Program.cs b/grpc-common/csharp/GreeterServer/Program.cs new file mode 100644 index 0000000000..9482797c3b --- /dev/null +++ b/grpc-common/csharp/GreeterServer/Program.cs @@ -0,0 +1,37 @@ +using System; +using System.Threading.Tasks; +using Grpc.Core; +using helloworld; + +namespace GreeterServer +{ + class GreeterImpl : Greeter.IGreeter + { + // Server side handler of the SayHello RPC + public Task SayHello(ServerCallContext context, HelloRequest request) + { + var reply = new HelloReply.Builder { Message = "Hello " + request.Name }.Build(); + return Task.FromResult(reply); + } + } + + class ServerMainClass + { + public static void Main(string[] args) + { + GrpcEnvironment.Initialize(); + + Server server = new Server(); + server.AddServiceDefinition(Greeter.BindService(new GreeterImpl())); + int port = server.AddListeningPort("localhost", 50051); + server.Start(); + + Console.WriteLine("Greeter server listening on port " + port); + Console.WriteLine("Press any key to stop the server..."); + Console.ReadKey(); + + server.ShutdownAsync().Wait(); + GrpcEnvironment.Shutdown(); + } + } +} diff --git a/grpc-common/csharp/GreeterServer/Properties/AssemblyInfo.cs b/grpc-common/csharp/GreeterServer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..f8a8d521d8 --- /dev/null +++ b/grpc-common/csharp/GreeterServer/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle("GreeterServer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("jtattermusch")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/grpc-common/csharp/GreeterServer/packages.config b/grpc-common/csharp/GreeterServer/packages.config new file mode 100644 index 0000000000..5922553bc3 --- /dev/null +++ b/grpc-common/csharp/GreeterServer/packages.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/grpc-common/csharp/README.md b/grpc-common/csharp/README.md new file mode 100644 index 0000000000..77d1aaf2e6 --- /dev/null +++ b/grpc-common/csharp/README.md @@ -0,0 +1,72 @@ +gRPC in 3 minutes (C#) +======================== + +BACKGROUND +------------- +For this sample, we've already generated the server and client stubs from `helloworld.proto`. +Example projects depend on NuGet packages `Grpc` and `Google.ProtocolBuffers` which have been already added to the project for you. + +PREREQUISITES +------------- +**Windows** +- .NET 4.5+ +- VS 2013 (with NuGet plugin installed) + +**Linux (Mono)** +- Mono +- Monodevelop 5.9 with NuGet Add-in installed (older versions might work) + +**MacOS (Mono)** +- Xamarin Studio (with NuGet plugin installed) + +BUILD +------- + +**Windows** +- Clone this repository. + +- Open solution `Greeter.sln` with Visual Studio + +- Build the solution (this will automatically download NuGet dependencies) + +**Linux (Mono)** +- Clone this repository. + +- Install gRPC C Core using instructions in https://github.com/grpc/homebrew-grpc + +- gRPC C# depends on native shared library `libgrpc_csharp_ext.so`. To make it visible + to Mono runtime, follow instructions in [Using gRPC C# on Linux](https://github.com/grpc/grpc/tree/master/src/csharp#usage-linux-mono) + +- Open solution `Greeter.sln` in MonoDevelop (you need to manually restore dependencies by using `mono nuget.exe restore` if you don't have NuGet add-in) + +- Build the solution. + +**MacOS (Mono)** +- See [Using gRPC C# on MacOS](https://github.com/grpc/grpc/tree/master/src/csharp#usage-macos-mono) for more info + on MacOS support. + +Try it! +------- + +- Run the server + + ``` + > cd GreeterServer/bin/Debug + > GreeterServer.exe + ``` + +- Run the client + + ``` + > cd GreeterClient/bin/Debug + > GreeterClient.exe + ``` + +You can also run the server and client directly from Visual Studio. + +On Linux or Mac, use `mono GreeterServer.exe` and `mono GreeterClient.exe` to run the server and client. + +Tutorial +-------- + +You can find a more detailed tutorial in [gRPC Basics: C#](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/README.md) diff --git a/grpc-common/csharp/route_guide/.gitignore b/grpc-common/csharp/route_guide/.gitignore new file mode 100644 index 0000000000..585000ea2d --- /dev/null +++ b/grpc-common/csharp/route_guide/.gitignore @@ -0,0 +1,5 @@ +bin/ +obj/ +packages/ +*.suo +*.userprefs diff --git a/grpc-common/csharp/route_guide/.nuget/packages.config b/grpc-common/csharp/route_guide/.nuget/packages.config new file mode 100644 index 0000000000..b14373069f --- /dev/null +++ b/grpc-common/csharp/route_guide/.nuget/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/README.md b/grpc-common/csharp/route_guide/README.md new file mode 100644 index 0000000000..35c6024bcf --- /dev/null +++ b/grpc-common/csharp/route_guide/README.md @@ -0,0 +1,409 @@ +#gRPC Basics: C# # + +This tutorial provides a basic C# programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate server and client code using the protocol buffer compiler. +- Use the C# gRPC API to write a simple client and server for your service. + +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial only uses the proto2 version of the protocol buffers language, as proto3 support for C# is not ready yet (see [protobuf C# README](https://github.com/google/protobuf/tree/master/csharp#proto2--proto3)). + +This isn't a comprehensive guide to using gRPC in C#: more reference documentation is coming soon. + +## Why use gRPC? + +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/csharp/route_guide](https://github.com/grpc/grpc-common/tree/master/csharp/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/google/grpc-common.git +``` + +All the files for this tutorial are in the directory `grpc-common/csharp/route_guide`. +Open the solution `grpc-common/csharp/route_guide/RouteGuide.sln` from Visual Studio (or Monodevelop on Linux). + +On Windows, you should not need to do anything besides opening the solution. All the needed dependencies will be restored +for you automatically by the `Grpc` NuGet package upon building the solution. + +On Linux (or MacOS), you will first need to install protobuf and gRPC C Core using Linuxbrew (or Homebrew) tool in order to be +able to generate the server and client interface code and run the examples. Follow the instructions for [Linux](https://github.com/grpc/grpc/tree/master/src/csharp#usage-linux-mono) or [MacOS](https://github.com/grpc/grpc/tree/master/src/csharp#usage-macos-mono). + +## Defining the service + +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/csharp/route_guide/RouteGuide/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/sharp/route_guide/RouteGuide/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +```protobuf +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +```protobuf + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. +```protobuf + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} +``` + +- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. +```protobuf + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +```protobuf + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +```protobuf +// 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; +} +``` + + +## Generating client and server code + +Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C# plugin. + +If you want to run this yourself, make sure you've installed protoc and gRPC C# plugin. The instructions vary based on your OS: +- For Windows, the `Grpc.Tools` NuGet package contains the binaries you will need to generate the code. +- For Linux, make sure you've [installed gRPC C Core using Linuxbrew](https://github.com/grpc/grpc/tree/master/src/csharp#usage-linux-mono) +- For MacOS, make sure you've [installed gRPC C Core using Homebrew](https://github.com/grpc/grpc/tree/master/src/csharp#usage-macos-mono) + +Once that's done, the following command can be used to generate the C# code. + +To generate the code on Windows, we use `protoc.exe` and `grpc_csharp_plugin.exe` binaries that are shipped with the `Grpc.Tools` NuGet package under the `tools` directory. +Normally you would need to add the `Grpc.Tools` package to the solution yourself, but in this tutorial it has been already done for you. Following command should be run from the `csharp/route_guide` directory: +``` +> packages\Grpc.Tools.0.5.1\tools\protoc -I RouteGuide/protos --csharp_out=RouteGuide --grpc_out=RouteGuide --plugin=protoc-gen-grpc=packages\Grpc.Tools.0.5.1\tools\grpc_csharp_plugin.exe RouteGuide/protos/route_guide.proto +``` + +On Linux/MacOS, we rely on `protoc` and `grpc_csharp_plugin` being installed by Linuxbrew/Homebrew. Run this command from the route_guide directory: +```shell +$ protoc -I RouteGuide/protos --csharp_out=RouteGuide --grpc_out=RouteGuide --plugin=protoc-gen-grpc=`which grpc_csharp_plugin` RouteGuide/protos/route_guide.proto +``` + +Running one of the previous commands regenerates the following files in the RouteGuide directory: +- `RouteGuide/RouteGuide.cs` defines a namespace `examples` + - This contains all the protocol buffer code to populate, serialize, and retrieve our request and response message types +- `RouteGuide/RouteGuideGrpc.cs`, provides stub and service classes + - an interface `RouteGuide.IRouteGuide` to inherit from when defining RouteGuide service implementations + - a class `RouteGuide.RouteGuideClient` that can be used to access remote RouteGuide instances + + + +## Creating the server + +First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). + +There are two parts to making our `RouteGuide` service do its job: +- Implementing the service interface generated from our service definition: doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and return the service responses. + +You can find our example `RouteGuide` server in [grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/RouteGuideServer/RouteGuideServerImpl.cs). Let's take a closer look at how it works. + +### Implementing RouteGuide + +As you can see, our server has a `RouteGuideImpl` class that implements the generated `RouteGuide.IRouteGuide`: + +```csharp +// RouteGuideImpl provides an implementation of the RouteGuide service. +public class RouteGuideImpl : RouteGuide.IRouteGuide +``` + +#### Simple RPC + +`RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. + +```csharp + public Task GetFeature(Grpc.Core.ServerCallContext context, Point request) + { + return Task.FromResult(CheckFeature(request)); + } +``` + +The method is passed a context for the RPC (which is empty in the alpha release), the client's `Point` protocol buffer request, and returns a `Feature` protocol buffer. In the method we create the `Feature` with the appropriate information, and then return it. To allow asynchronous +implementation, the method returns `Task` rather than just `Feature`. You are free to perform your computations synchronously and return +the result once you've finished, just as we do in the example. + +#### Server-side streaming RPC + +Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature` protocol buffers to our client. + +```csharp + // in RouteGuideImpl + public async Task ListFeatures(Grpc.Core.ServerCallContext context, Rectangle request, + Grpc.Core.IServerStreamWriter responseStream) + { + int left = Math.Min(request.Lo.Longitude, request.Hi.Longitude); + int right = Math.Max(request.Lo.Longitude, request.Hi.Longitude); + int top = Math.Max(request.Lo.Latitude, request.Hi.Latitude); + int bottom = Math.Min(request.Lo.Latitude, request.Hi.Latitude); + + foreach (var feature in features) + { + if (!RouteGuideUtil.Exists(feature)) + { + continue; + } + + int lat = feature.Location.Latitude; + int lon = feature.Location.Longitude; + if (lon >= left && lon <= right && lat >= bottom && lat <= top) + { + await responseStream.WriteAsync(feature); + } + } + } +``` + +As you can see, here the request object is a `Rectangle` in which our client wants to find `Feature`s, but instead of returning a simple response we need to write responses to an asynchronous stream `IServerStreamWriter` using async method `WriteAsync`. + +#### Client-side streaming RPC + +Similarly, the client-side streaming method `RecordRoute` uses an [IAsyncEnumerator](https://github.com/Reactive-Extensions/Rx.NET/blob/master/Ix.NET/Source/System.Interactive.Async/IAsyncEnumerator.cs), to read the stream of requests using the async method `MoveNext` and the `Current` property. + +```csharp + public async Task RecordRoute(Grpc.Core.ServerCallContext context, + Grpc.Core.IAsyncStreamReader requestStream) + { + int pointCount = 0; + int featureCount = 0; + int distance = 0; + Point previous = null; + var stopwatch = new Stopwatch(); + stopwatch.Start(); + + while (await requestStream.MoveNext()) + { + var point = requestStream.Current; + pointCount++; + if (RouteGuideUtil.Exists(CheckFeature(point))) + { + featureCount++; + } + if (previous != null) + { + distance += (int) CalcDistance(previous, point); + } + previous = point; + } + + stopwatch.Stop(); + return RouteSummary.CreateBuilder().SetPointCount(pointCount) + .SetFeatureCount(featureCount).SetDistance(distance) + .SetElapsedTime((int) (stopwatch.ElapsedMilliseconds / 1000)).Build(); + } +``` + +#### Bidirectional streaming RPC + +Finally, let's look at our bidirectional streaming RPC `RouteChat`. + +```csharp + public async Task RouteChat(Grpc.Core.ServerCallContext context, + Grpc.Core.IAsyncStreamReader requestStream, Grpc.Core.IServerStreamWriter responseStream) + { + while (await requestStream.MoveNext()) + { + var note = requestStream.Current; + List notes = GetOrCreateNotes(note.Location); + + List prevNotes; + lock (notes) + { + prevNotes = new List(notes); + } + + foreach (var prevNote in prevNotes) + { + await responseStream.WriteAsync(prevNote); + } + + lock (notes) + { + notes.Add(note); + } + } + } +``` + +Here the method receives both `requestStream` and `responseStream` arguments. Reading the requests is done the same way as in the client-side streaming method `RecordRoute`. Writing the responses is done the same way as in the server-side streaming method `ListFeatures`. + +### Starting the server + +Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: + +```csharp +var features = RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile); +GrpcEnvironment.Initialize(); + +Server server = new Server(); +server.AddServiceDefinition(RouteGuide.BindService(new RouteGuideImpl(features))); +int port = server.AddListeningPort("localhost", 50052); +server.Start(); + +Console.WriteLine("RouteGuide server listening on port " + port); +Console.WriteLine("Press any key to stop the server..."); +Console.ReadKey(); + +server.ShutdownAsync().Wait(); +GrpcEnvironment.Shutdown(); +``` +As you can see, we build and start our server using `Grpc.Core.Server` class. To do this, we: + +1. Create an instance of `Grpc.Core.Server`. +1. Create an instance of our service implementation class `RouteGuideImpl`. +3. Register our service implementation with the server using the `AddServiceDefinition` method and the generated method `RouteGuide.BindService`. +2. Specify the address and port we want to use to listen for client requests using the `AddListeningPort` method. +4. Call `Start` on the server instance to start an RPC server for our service. + + +## Creating the client + +In this section, we'll look at creating a C# client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/csharp/route_guide/RouteGuideClient/Program.cs](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/RouteGuideClient/Program.cs). + +### Creating a stub + +To call service methods, we first need to create a *stub*. + +First, we need to create a gRPC client channel that will connect to gRPC server. Then, we use the `RouteGuide.NewStub` method of the `RouteGuide` class generated from our .proto. + +```csharp +GrpcEnvironment.Initialize(); + +using (Channel channel = new Channel("127.0.0.1:50052")) +{ + var client = RouteGuide.NewStub(channel); + + // YOUR CODE GOES HERE +} + +GrpcEnvironment.Shutdown(); +``` + +### Calling service methods + +Now let's look at how we call our service methods. gRPC C# provides asynchronous versions of each of the supported method types. For convenience, +gRPC C# also provides a synchronous method stub, but only for simple (single request/single response) RPCs. + +#### Simple RPC + +Calling the simple RPC `GetFeature` in a synchronous way is nearly as straightforward as calling a local method. + +```csharp +Point request = Point.CreateBuilder().SetLatitude(409146138).SetLongitude(-746188906).Build(); +Feature feature = client.GetFeature(request); +``` + +As you can see, we create and populate a request protocol buffer object (in our case `Point`), and call the desired method on the client object, passing it the request. If the RPC finishes with success, the response protocol buffer (in our case `Feature`) will be returned. Otherwise, an exception of type `RpcException` will be thrown, indicating the status code of the problem. + +Alternatively, if you are in async context, you can call an asynchronous version of the method (and use `await` keyword to await the result): +```csharp +Point request = Point.CreateBuilder().SetLatitude(409146138).SetLongitude(-746188906).Build(); +Feature feature = await client.GetFeatureAsync(request); +``` + +#### Streaming RPCs + +Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. The difference with respect to simple call is that the client methods return an instance of a call object, that provides access to request/response streams and/or asynchronous result (depending on the streaming type you are using). + +Here's where we call the server-side streaming method `ListFeatures`, which has property `ReponseStream` of type `IAsyncEnumerator` + +```csharp +using (var call = client.ListFeatures(request)) +{ + while (await call.ResponseStream.MoveNext()) + { + Feature feature = call.ResponseStream.Current; + Console.WriteLine("Received " + feature.ToString()); + } +} +``` + +The client-side streaming method `RecordRoute` is similar, except we use the property `RequestStream` to write the requests one by one using `WriteAsync` and eventually signal that no more request will be send using `CompleteAsync`. The method result can be obtained through the property +`Result`. +```csharp +using (var call = client.RecordRoute()) +{ + foreach (var point in points) + { + await call.RequestStream.WriteAsync(point); + } + await call.RequestStream.CompleteAsync(); + + RouteSummary summary = await call.Result; +} +``` + +Finally, let's look at our bidirectional streaming RPC `RouteChat`. In this case, we write the request to `RequestStream` and receive the responses from `ResponseStream`. As you can see from the example, the streams are independent of each other. + +```csharp + using (var call = client.RouteChat()) + { + var responseReaderTask = Task.Run(async () => + { + while (await call.ResponseStream.MoveNext()) + { + var note = call.ResponseStream.Current; + Console.WriteLine("Received " + note); + } + }); + + foreach (RouteNote request in requests) + { + await call.RequestStream.WriteAsync(request); + } + await call.RequestStream.CompleteAsync(); + await responseReaderTask; +} +``` + +## Try it out! + +Build client and server: + +Open the solution `grpc-common/csharp/route_guide/RouteGuide.sln` from Visual Studio (or Monodevelop on Linux) and hit "Build". + +Run the server, which will listen on port 50052: +``` +> cd RouteGuideServer/bin/Debug +> RouteGuideServer.exe +``` + +Run the client (in a different terminal): +``` +> cd RouteGuideClient/bin/Debug +> RouteGuideClient.exe +``` + +You can also run the server and client directly from Visual Studio. + +On Linux or Mac, use `mono RouteGuideServer.exe` and `mono RouteGuideClient.exe` to run the server and client. diff --git a/grpc-common/csharp/route_guide/RouteGuide.sln b/grpc-common/csharp/route_guide/RouteGuide.sln new file mode 100644 index 0000000000..0b79fdc5ca --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuide.sln @@ -0,0 +1,39 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuide", "RouteGuide\RouteGuide.csproj", "{49954D9C-5F17-4662-96B2-73BE833DD81A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideClient", "RouteGuideClient\RouteGuideClient.csproj", "{D47BE663-4DE3-4206-B7A8-EA3FA066DADC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideServer", "RouteGuideServer\RouteGuideServer.csproj", "{4B7C7794-BE24-4477-ACE7-18259EB73D27}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2F6B184B-A576-4F21-AF2E-27E73D1FC96E}" + ProjectSection(SolutionItems) = preProject + .nuget\packages.config = .nuget\packages.config + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {49954D9C-5F17-4662-96B2-73BE833DD81A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {49954D9C-5F17-4662-96B2-73BE833DD81A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {49954D9C-5F17-4662-96B2-73BE833DD81A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {49954D9C-5F17-4662-96B2-73BE833DD81A}.Release|Any CPU.Build.0 = Release|Any CPU + {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Release|Any CPU.Build.0 = Release|Any CPU + {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/grpc-common/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs b/grpc-common/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..9c3441e42f --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RouteGuide")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RouteGuide")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ef6b85bc-ac27-46de-8714-a658236cc6fb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/grpc-common/csharp/route_guide/RouteGuide/RouteGuide.cs b/grpc-common/csharp/route_guide/RouteGuide/RouteGuide.cs new file mode 100644 index 0000000000..80508bcd3f --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuide/RouteGuide.cs @@ -0,0 +1,1873 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: route_guide.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.ProtocolBuffers; +using pbc = global::Google.ProtocolBuffers.Collections; +using pbd = global::Google.ProtocolBuffers.Descriptors; +using scg = global::System.Collections.Generic; +namespace examples { + + namespace Proto { + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public static partial class RouteGuide { + + #region Extension registration + public static void RegisterAllExtensions(pb::ExtensionRegistry registry) { + } + #endregion + #region Static variables + internal static pbd::MessageDescriptor internal__static_examples_Point__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_Point__FieldAccessorTable; + internal static pbd::MessageDescriptor internal__static_examples_Rectangle__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_Rectangle__FieldAccessorTable; + internal static pbd::MessageDescriptor internal__static_examples_Feature__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_Feature__FieldAccessorTable; + internal static pbd::MessageDescriptor internal__static_examples_RouteNote__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_RouteNote__FieldAccessorTable; + internal static pbd::MessageDescriptor internal__static_examples_RouteSummary__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_RouteSummary__FieldAccessorTable; + #endregion + #region Descriptor + public static pbd::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbd::FileDescriptor descriptor; + + static RouteGuide() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChFyb3V0ZV9ndWlkZS5wcm90bxIIZXhhbXBsZXMiLAoFUG9pbnQSEAoIbGF0", + "aXR1ZGUYASABKAUSEQoJbG9uZ2l0dWRlGAIgASgFIkUKCVJlY3RhbmdsZRIb", + "CgJsbxgBIAEoCzIPLmV4YW1wbGVzLlBvaW50EhsKAmhpGAIgASgLMg8uZXhh", + "bXBsZXMuUG9pbnQiOgoHRmVhdHVyZRIMCgRuYW1lGAEgASgJEiEKCGxvY2F0", + "aW9uGAIgASgLMg8uZXhhbXBsZXMuUG9pbnQiPwoJUm91dGVOb3RlEiEKCGxv", + "Y2F0aW9uGAEgASgLMg8uZXhhbXBsZXMuUG9pbnQSDwoHbWVzc2FnZRgCIAEo", + "CSJiCgxSb3V0ZVN1bW1hcnkSEwoLcG9pbnRfY291bnQYASABKAUSFQoNZmVh", + "dHVyZV9jb3VudBgCIAEoBRIQCghkaXN0YW5jZRgDIAEoBRIUCgxlbGFwc2Vk", + "X3RpbWUYBCABKAUy9QEKClJvdXRlR3VpZGUSMgoKR2V0RmVhdHVyZRIPLmV4", + "YW1wbGVzLlBvaW50GhEuZXhhbXBsZXMuRmVhdHVyZSIAEjoKDExpc3RGZWF0", + "dXJlcxITLmV4YW1wbGVzLlJlY3RhbmdsZRoRLmV4YW1wbGVzLkZlYXR1cmUi", + "ADABEjoKC1JlY29yZFJvdXRlEg8uZXhhbXBsZXMuUG9pbnQaFi5leGFtcGxl", + "cy5Sb3V0ZVN1bW1hcnkiACgBEjsKCVJvdXRlQ2hhdBITLmV4YW1wbGVzLlJv", + "dXRlTm90ZRoTLmV4YW1wbGVzLlJvdXRlTm90ZSIAKAEwAQ==")); + pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) { + descriptor = root; + internal__static_examples_Point__Descriptor = Descriptor.MessageTypes[0]; + internal__static_examples_Point__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_examples_Point__Descriptor, + new string[] { "Latitude", "Longitude", }); + internal__static_examples_Rectangle__Descriptor = Descriptor.MessageTypes[1]; + internal__static_examples_Rectangle__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_examples_Rectangle__Descriptor, + new string[] { "Lo", "Hi", }); + internal__static_examples_Feature__Descriptor = Descriptor.MessageTypes[2]; + internal__static_examples_Feature__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_examples_Feature__Descriptor, + new string[] { "Name", "Location", }); + internal__static_examples_RouteNote__Descriptor = Descriptor.MessageTypes[3]; + internal__static_examples_RouteNote__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_examples_RouteNote__Descriptor, + new string[] { "Location", "Message", }); + internal__static_examples_RouteSummary__Descriptor = Descriptor.MessageTypes[4]; + internal__static_examples_RouteSummary__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_examples_RouteSummary__Descriptor, + new string[] { "PointCount", "FeatureCount", "Distance", "ElapsedTime", }); + pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance(); + RegisterAllExtensions(registry); + return registry; + }; + pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData, + new pbd::FileDescriptor[] { + }, assigner); + } + #endregion + + } + } + #region Messages + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Point : pb::GeneratedMessage { + private Point() { } + private static readonly Point defaultInstance = new Point().MakeReadOnly(); + private static readonly string[] _pointFieldNames = new string[] { "latitude", "longitude" }; + private static readonly uint[] _pointFieldTags = new uint[] { 8, 16 }; + public static Point DefaultInstance { + get { return defaultInstance; } + } + + public override Point DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override Point ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::examples.Proto.RouteGuide.internal__static_examples_Point__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::examples.Proto.RouteGuide.internal__static_examples_Point__FieldAccessorTable; } + } + + public const int LatitudeFieldNumber = 1; + private bool hasLatitude; + private int latitude_; + public bool HasLatitude { + get { return hasLatitude; } + } + public int Latitude { + get { return latitude_; } + } + + public const int LongitudeFieldNumber = 2; + private bool hasLongitude; + private int longitude_; + public bool HasLongitude { + get { return hasLongitude; } + } + public int Longitude { + get { return longitude_; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _pointFieldNames; + if (hasLatitude) { + output.WriteInt32(1, field_names[0], Latitude); + } + if (hasLongitude) { + output.WriteInt32(2, field_names[1], Longitude); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasLatitude) { + size += pb::CodedOutputStream.ComputeInt32Size(1, Latitude); + } + if (hasLongitude) { + size += pb::CodedOutputStream.ComputeInt32Size(2, Longitude); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static Point ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static Point ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static Point ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static Point ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static Point ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static Point ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static Point ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static Point ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static Point ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static Point ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private Point MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(Point prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(Point cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private Point result; + + private Point PrepareBuilder() { + if (resultIsReadOnly) { + Point original = result; + result = new Point(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override Point MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::examples.Point.Descriptor; } + } + + public override Point DefaultInstanceForType { + get { return global::examples.Point.DefaultInstance; } + } + + public override Point BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is Point) { + return MergeFrom((Point) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(Point other) { + if (other == global::examples.Point.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasLatitude) { + Latitude = other.Latitude; + } + if (other.HasLongitude) { + Longitude = other.Longitude; + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_pointFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _pointFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 8: { + result.hasLatitude = input.ReadInt32(ref result.latitude_); + break; + } + case 16: { + result.hasLongitude = input.ReadInt32(ref result.longitude_); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasLatitude { + get { return result.hasLatitude; } + } + public int Latitude { + get { return result.Latitude; } + set { SetLatitude(value); } + } + public Builder SetLatitude(int value) { + PrepareBuilder(); + result.hasLatitude = true; + result.latitude_ = value; + return this; + } + public Builder ClearLatitude() { + PrepareBuilder(); + result.hasLatitude = false; + result.latitude_ = 0; + return this; + } + + public bool HasLongitude { + get { return result.hasLongitude; } + } + public int Longitude { + get { return result.Longitude; } + set { SetLongitude(value); } + } + public Builder SetLongitude(int value) { + PrepareBuilder(); + result.hasLongitude = true; + result.longitude_ = value; + return this; + } + public Builder ClearLongitude() { + PrepareBuilder(); + result.hasLongitude = false; + result.longitude_ = 0; + return this; + } + } + static Point() { + object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Rectangle : pb::GeneratedMessage { + private Rectangle() { } + private static readonly Rectangle defaultInstance = new Rectangle().MakeReadOnly(); + private static readonly string[] _rectangleFieldNames = new string[] { "hi", "lo" }; + private static readonly uint[] _rectangleFieldTags = new uint[] { 18, 10 }; + public static Rectangle DefaultInstance { + get { return defaultInstance; } + } + + public override Rectangle DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override Rectangle ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::examples.Proto.RouteGuide.internal__static_examples_Rectangle__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::examples.Proto.RouteGuide.internal__static_examples_Rectangle__FieldAccessorTable; } + } + + public const int LoFieldNumber = 1; + private bool hasLo; + private global::examples.Point lo_; + public bool HasLo { + get { return hasLo; } + } + public global::examples.Point Lo { + get { return lo_ ?? global::examples.Point.DefaultInstance; } + } + + public const int HiFieldNumber = 2; + private bool hasHi; + private global::examples.Point hi_; + public bool HasHi { + get { return hasHi; } + } + public global::examples.Point Hi { + get { return hi_ ?? global::examples.Point.DefaultInstance; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _rectangleFieldNames; + if (hasLo) { + output.WriteMessage(1, field_names[1], Lo); + } + if (hasHi) { + output.WriteMessage(2, field_names[0], Hi); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasLo) { + size += pb::CodedOutputStream.ComputeMessageSize(1, Lo); + } + if (hasHi) { + size += pb::CodedOutputStream.ComputeMessageSize(2, Hi); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static Rectangle ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static Rectangle ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static Rectangle ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static Rectangle ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static Rectangle ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static Rectangle ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static Rectangle ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static Rectangle ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static Rectangle ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static Rectangle ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private Rectangle MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(Rectangle prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(Rectangle cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private Rectangle result; + + private Rectangle PrepareBuilder() { + if (resultIsReadOnly) { + Rectangle original = result; + result = new Rectangle(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override Rectangle MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::examples.Rectangle.Descriptor; } + } + + public override Rectangle DefaultInstanceForType { + get { return global::examples.Rectangle.DefaultInstance; } + } + + public override Rectangle BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is Rectangle) { + return MergeFrom((Rectangle) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(Rectangle other) { + if (other == global::examples.Rectangle.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasLo) { + MergeLo(other.Lo); + } + if (other.HasHi) { + MergeHi(other.Hi); + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_rectangleFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _rectangleFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 10: { + global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); + if (result.hasLo) { + subBuilder.MergeFrom(Lo); + } + input.ReadMessage(subBuilder, extensionRegistry); + Lo = subBuilder.BuildPartial(); + break; + } + case 18: { + global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); + if (result.hasHi) { + subBuilder.MergeFrom(Hi); + } + input.ReadMessage(subBuilder, extensionRegistry); + Hi = subBuilder.BuildPartial(); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasLo { + get { return result.hasLo; } + } + public global::examples.Point Lo { + get { return result.Lo; } + set { SetLo(value); } + } + public Builder SetLo(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasLo = true; + result.lo_ = value; + return this; + } + public Builder SetLo(global::examples.Point.Builder builderForValue) { + pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); + PrepareBuilder(); + result.hasLo = true; + result.lo_ = builderForValue.Build(); + return this; + } + public Builder MergeLo(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + if (result.hasLo && + result.lo_ != global::examples.Point.DefaultInstance) { + result.lo_ = global::examples.Point.CreateBuilder(result.lo_).MergeFrom(value).BuildPartial(); + } else { + result.lo_ = value; + } + result.hasLo = true; + return this; + } + public Builder ClearLo() { + PrepareBuilder(); + result.hasLo = false; + result.lo_ = null; + return this; + } + + public bool HasHi { + get { return result.hasHi; } + } + public global::examples.Point Hi { + get { return result.Hi; } + set { SetHi(value); } + } + public Builder SetHi(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasHi = true; + result.hi_ = value; + return this; + } + public Builder SetHi(global::examples.Point.Builder builderForValue) { + pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); + PrepareBuilder(); + result.hasHi = true; + result.hi_ = builderForValue.Build(); + return this; + } + public Builder MergeHi(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + if (result.hasHi && + result.hi_ != global::examples.Point.DefaultInstance) { + result.hi_ = global::examples.Point.CreateBuilder(result.hi_).MergeFrom(value).BuildPartial(); + } else { + result.hi_ = value; + } + result.hasHi = true; + return this; + } + public Builder ClearHi() { + PrepareBuilder(); + result.hasHi = false; + result.hi_ = null; + return this; + } + } + static Rectangle() { + object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Feature : pb::GeneratedMessage { + private Feature() { } + private static readonly Feature defaultInstance = new Feature().MakeReadOnly(); + private static readonly string[] _featureFieldNames = new string[] { "location", "name" }; + private static readonly uint[] _featureFieldTags = new uint[] { 18, 10 }; + public static Feature DefaultInstance { + get { return defaultInstance; } + } + + public override Feature DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override Feature ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::examples.Proto.RouteGuide.internal__static_examples_Feature__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::examples.Proto.RouteGuide.internal__static_examples_Feature__FieldAccessorTable; } + } + + public const int NameFieldNumber = 1; + private bool hasName; + private string name_ = ""; + public bool HasName { + get { return hasName; } + } + public string Name { + get { return name_; } + } + + public const int LocationFieldNumber = 2; + private bool hasLocation; + private global::examples.Point location_; + public bool HasLocation { + get { return hasLocation; } + } + public global::examples.Point Location { + get { return location_ ?? global::examples.Point.DefaultInstance; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _featureFieldNames; + if (hasName) { + output.WriteString(1, field_names[1], Name); + } + if (hasLocation) { + output.WriteMessage(2, field_names[0], Location); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasName) { + size += pb::CodedOutputStream.ComputeStringSize(1, Name); + } + if (hasLocation) { + size += pb::CodedOutputStream.ComputeMessageSize(2, Location); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static Feature ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static Feature ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static Feature ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static Feature ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static Feature ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static Feature ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static Feature ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static Feature ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static Feature ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static Feature ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private Feature MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(Feature prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(Feature cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private Feature result; + + private Feature PrepareBuilder() { + if (resultIsReadOnly) { + Feature original = result; + result = new Feature(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override Feature MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::examples.Feature.Descriptor; } + } + + public override Feature DefaultInstanceForType { + get { return global::examples.Feature.DefaultInstance; } + } + + public override Feature BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is Feature) { + return MergeFrom((Feature) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(Feature other) { + if (other == global::examples.Feature.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasName) { + Name = other.Name; + } + if (other.HasLocation) { + MergeLocation(other.Location); + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_featureFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _featureFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 10: { + result.hasName = input.ReadString(ref result.name_); + break; + } + case 18: { + global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); + if (result.hasLocation) { + subBuilder.MergeFrom(Location); + } + input.ReadMessage(subBuilder, extensionRegistry); + Location = subBuilder.BuildPartial(); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasName { + get { return result.hasName; } + } + public string Name { + get { return result.Name; } + set { SetName(value); } + } + public Builder SetName(string value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasName = true; + result.name_ = value; + return this; + } + public Builder ClearName() { + PrepareBuilder(); + result.hasName = false; + result.name_ = ""; + return this; + } + + public bool HasLocation { + get { return result.hasLocation; } + } + public global::examples.Point Location { + get { return result.Location; } + set { SetLocation(value); } + } + public Builder SetLocation(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasLocation = true; + result.location_ = value; + return this; + } + public Builder SetLocation(global::examples.Point.Builder builderForValue) { + pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); + PrepareBuilder(); + result.hasLocation = true; + result.location_ = builderForValue.Build(); + return this; + } + public Builder MergeLocation(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + if (result.hasLocation && + result.location_ != global::examples.Point.DefaultInstance) { + result.location_ = global::examples.Point.CreateBuilder(result.location_).MergeFrom(value).BuildPartial(); + } else { + result.location_ = value; + } + result.hasLocation = true; + return this; + } + public Builder ClearLocation() { + PrepareBuilder(); + result.hasLocation = false; + result.location_ = null; + return this; + } + } + static Feature() { + object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class RouteNote : pb::GeneratedMessage { + private RouteNote() { } + private static readonly RouteNote defaultInstance = new RouteNote().MakeReadOnly(); + private static readonly string[] _routeNoteFieldNames = new string[] { "location", "message" }; + private static readonly uint[] _routeNoteFieldTags = new uint[] { 10, 18 }; + public static RouteNote DefaultInstance { + get { return defaultInstance; } + } + + public override RouteNote DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override RouteNote ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteNote__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteNote__FieldAccessorTable; } + } + + public const int LocationFieldNumber = 1; + private bool hasLocation; + private global::examples.Point location_; + public bool HasLocation { + get { return hasLocation; } + } + public global::examples.Point Location { + get { return location_ ?? global::examples.Point.DefaultInstance; } + } + + public const int MessageFieldNumber = 2; + private bool hasMessage; + private string message_ = ""; + public bool HasMessage { + get { return hasMessage; } + } + public string Message { + get { return message_; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _routeNoteFieldNames; + if (hasLocation) { + output.WriteMessage(1, field_names[0], Location); + } + if (hasMessage) { + output.WriteString(2, field_names[1], Message); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasLocation) { + size += pb::CodedOutputStream.ComputeMessageSize(1, Location); + } + if (hasMessage) { + size += pb::CodedOutputStream.ComputeStringSize(2, Message); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static RouteNote ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static RouteNote ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static RouteNote ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static RouteNote ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static RouteNote ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static RouteNote ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static RouteNote ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static RouteNote ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static RouteNote ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static RouteNote ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private RouteNote MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(RouteNote prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(RouteNote cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private RouteNote result; + + private RouteNote PrepareBuilder() { + if (resultIsReadOnly) { + RouteNote original = result; + result = new RouteNote(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override RouteNote MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::examples.RouteNote.Descriptor; } + } + + public override RouteNote DefaultInstanceForType { + get { return global::examples.RouteNote.DefaultInstance; } + } + + public override RouteNote BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is RouteNote) { + return MergeFrom((RouteNote) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(RouteNote other) { + if (other == global::examples.RouteNote.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasLocation) { + MergeLocation(other.Location); + } + if (other.HasMessage) { + Message = other.Message; + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_routeNoteFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _routeNoteFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 10: { + global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); + if (result.hasLocation) { + subBuilder.MergeFrom(Location); + } + input.ReadMessage(subBuilder, extensionRegistry); + Location = subBuilder.BuildPartial(); + break; + } + case 18: { + result.hasMessage = input.ReadString(ref result.message_); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasLocation { + get { return result.hasLocation; } + } + public global::examples.Point Location { + get { return result.Location; } + set { SetLocation(value); } + } + public Builder SetLocation(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasLocation = true; + result.location_ = value; + return this; + } + public Builder SetLocation(global::examples.Point.Builder builderForValue) { + pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); + PrepareBuilder(); + result.hasLocation = true; + result.location_ = builderForValue.Build(); + return this; + } + public Builder MergeLocation(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + if (result.hasLocation && + result.location_ != global::examples.Point.DefaultInstance) { + result.location_ = global::examples.Point.CreateBuilder(result.location_).MergeFrom(value).BuildPartial(); + } else { + result.location_ = value; + } + result.hasLocation = true; + return this; + } + public Builder ClearLocation() { + PrepareBuilder(); + result.hasLocation = false; + result.location_ = null; + return this; + } + + public bool HasMessage { + get { return result.hasMessage; } + } + public string Message { + get { return result.Message; } + set { SetMessage(value); } + } + public Builder SetMessage(string value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasMessage = true; + result.message_ = value; + return this; + } + public Builder ClearMessage() { + PrepareBuilder(); + result.hasMessage = false; + result.message_ = ""; + return this; + } + } + static RouteNote() { + object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class RouteSummary : pb::GeneratedMessage { + private RouteSummary() { } + private static readonly RouteSummary defaultInstance = new RouteSummary().MakeReadOnly(); + private static readonly string[] _routeSummaryFieldNames = new string[] { "distance", "elapsed_time", "feature_count", "point_count" }; + private static readonly uint[] _routeSummaryFieldTags = new uint[] { 24, 32, 16, 8 }; + public static RouteSummary DefaultInstance { + get { return defaultInstance; } + } + + public override RouteSummary DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override RouteSummary ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteSummary__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteSummary__FieldAccessorTable; } + } + + public const int PointCountFieldNumber = 1; + private bool hasPointCount; + private int pointCount_; + public bool HasPointCount { + get { return hasPointCount; } + } + public int PointCount { + get { return pointCount_; } + } + + public const int FeatureCountFieldNumber = 2; + private bool hasFeatureCount; + private int featureCount_; + public bool HasFeatureCount { + get { return hasFeatureCount; } + } + public int FeatureCount { + get { return featureCount_; } + } + + public const int DistanceFieldNumber = 3; + private bool hasDistance; + private int distance_; + public bool HasDistance { + get { return hasDistance; } + } + public int Distance { + get { return distance_; } + } + + public const int ElapsedTimeFieldNumber = 4; + private bool hasElapsedTime; + private int elapsedTime_; + public bool HasElapsedTime { + get { return hasElapsedTime; } + } + public int ElapsedTime { + get { return elapsedTime_; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _routeSummaryFieldNames; + if (hasPointCount) { + output.WriteInt32(1, field_names[3], PointCount); + } + if (hasFeatureCount) { + output.WriteInt32(2, field_names[2], FeatureCount); + } + if (hasDistance) { + output.WriteInt32(3, field_names[0], Distance); + } + if (hasElapsedTime) { + output.WriteInt32(4, field_names[1], ElapsedTime); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasPointCount) { + size += pb::CodedOutputStream.ComputeInt32Size(1, PointCount); + } + if (hasFeatureCount) { + size += pb::CodedOutputStream.ComputeInt32Size(2, FeatureCount); + } + if (hasDistance) { + size += pb::CodedOutputStream.ComputeInt32Size(3, Distance); + } + if (hasElapsedTime) { + size += pb::CodedOutputStream.ComputeInt32Size(4, ElapsedTime); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static RouteSummary ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static RouteSummary ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static RouteSummary ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static RouteSummary ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static RouteSummary ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static RouteSummary ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static RouteSummary ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static RouteSummary ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static RouteSummary ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static RouteSummary ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private RouteSummary MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(RouteSummary prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(RouteSummary cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private RouteSummary result; + + private RouteSummary PrepareBuilder() { + if (resultIsReadOnly) { + RouteSummary original = result; + result = new RouteSummary(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override RouteSummary MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::examples.RouteSummary.Descriptor; } + } + + public override RouteSummary DefaultInstanceForType { + get { return global::examples.RouteSummary.DefaultInstance; } + } + + public override RouteSummary BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is RouteSummary) { + return MergeFrom((RouteSummary) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(RouteSummary other) { + if (other == global::examples.RouteSummary.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasPointCount) { + PointCount = other.PointCount; + } + if (other.HasFeatureCount) { + FeatureCount = other.FeatureCount; + } + if (other.HasDistance) { + Distance = other.Distance; + } + if (other.HasElapsedTime) { + ElapsedTime = other.ElapsedTime; + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_routeSummaryFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _routeSummaryFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 8: { + result.hasPointCount = input.ReadInt32(ref result.pointCount_); + break; + } + case 16: { + result.hasFeatureCount = input.ReadInt32(ref result.featureCount_); + break; + } + case 24: { + result.hasDistance = input.ReadInt32(ref result.distance_); + break; + } + case 32: { + result.hasElapsedTime = input.ReadInt32(ref result.elapsedTime_); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasPointCount { + get { return result.hasPointCount; } + } + public int PointCount { + get { return result.PointCount; } + set { SetPointCount(value); } + } + public Builder SetPointCount(int value) { + PrepareBuilder(); + result.hasPointCount = true; + result.pointCount_ = value; + return this; + } + public Builder ClearPointCount() { + PrepareBuilder(); + result.hasPointCount = false; + result.pointCount_ = 0; + return this; + } + + public bool HasFeatureCount { + get { return result.hasFeatureCount; } + } + public int FeatureCount { + get { return result.FeatureCount; } + set { SetFeatureCount(value); } + } + public Builder SetFeatureCount(int value) { + PrepareBuilder(); + result.hasFeatureCount = true; + result.featureCount_ = value; + return this; + } + public Builder ClearFeatureCount() { + PrepareBuilder(); + result.hasFeatureCount = false; + result.featureCount_ = 0; + return this; + } + + public bool HasDistance { + get { return result.hasDistance; } + } + public int Distance { + get { return result.Distance; } + set { SetDistance(value); } + } + public Builder SetDistance(int value) { + PrepareBuilder(); + result.hasDistance = true; + result.distance_ = value; + return this; + } + public Builder ClearDistance() { + PrepareBuilder(); + result.hasDistance = false; + result.distance_ = 0; + return this; + } + + public bool HasElapsedTime { + get { return result.hasElapsedTime; } + } + public int ElapsedTime { + get { return result.ElapsedTime; } + set { SetElapsedTime(value); } + } + public Builder SetElapsedTime(int value) { + PrepareBuilder(); + result.hasElapsedTime = true; + result.elapsedTime_ = value; + return this; + } + public Builder ClearElapsedTime() { + PrepareBuilder(); + result.hasElapsedTime = false; + result.elapsedTime_ = 0; + return this; + } + } + static RouteSummary() { + object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); + } + } + + #endregion + +} + +#endregion Designer generated code diff --git a/grpc-common/csharp/route_guide/RouteGuide/RouteGuide.csproj b/grpc-common/csharp/route_guide/RouteGuide/RouteGuide.csproj new file mode 100644 index 0000000000..8358974aac --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuide/RouteGuide.csproj @@ -0,0 +1,101 @@ + + + + + + + + Debug + AnyCPU + {49954D9C-5F17-4662-96B2-73BE833DD81A} + Library + Properties + RouteGuide + RouteGuide + v4.5 + 512 + 214cccda + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll + + + False + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll + + + False + ..\packages\Newtonsoft.Json.7.0.1-beta2\lib\net45\Newtonsoft.Json.dll + + + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + + ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll + + + + + + + + + + + + + + + + + + PreserveNewest + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + + \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs b/grpc-common/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs new file mode 100644 index 0000000000..c4b3900dca --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs @@ -0,0 +1,123 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: route_guide.proto +#region Designer generated code + +using System; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; + +namespace examples { + public static class RouteGuide + { + static readonly string __ServiceName = "examples.RouteGuide"; + + static readonly Marshaller __Marshaller_Point = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.Point.ParseFrom); + static readonly Marshaller __Marshaller_Feature = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.Feature.ParseFrom); + static readonly Marshaller __Marshaller_Rectangle = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.Rectangle.ParseFrom); + static readonly Marshaller __Marshaller_RouteSummary = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.RouteSummary.ParseFrom); + static readonly Marshaller __Marshaller_RouteNote = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.RouteNote.ParseFrom); + + static readonly Method __Method_GetFeature = new Method( + MethodType.Unary, + "GetFeature", + __Marshaller_Point, + __Marshaller_Feature); + + static readonly Method __Method_ListFeatures = new Method( + MethodType.ServerStreaming, + "ListFeatures", + __Marshaller_Rectangle, + __Marshaller_Feature); + + static readonly Method __Method_RecordRoute = new Method( + MethodType.ClientStreaming, + "RecordRoute", + __Marshaller_Point, + __Marshaller_RouteSummary); + + static readonly Method __Method_RouteChat = new Method( + MethodType.DuplexStreaming, + "RouteChat", + __Marshaller_RouteNote, + __Marshaller_RouteNote); + + // client-side stub interface + public interface IRouteGuideClient + { + global::examples.Feature GetFeature(global::examples.Point request, CancellationToken token = default(CancellationToken)); + Task GetFeatureAsync(global::examples.Point request, CancellationToken token = default(CancellationToken)); + AsyncServerStreamingCall ListFeatures(global::examples.Rectangle request, CancellationToken token = default(CancellationToken)); + AsyncClientStreamingCall RecordRoute(CancellationToken token = default(CancellationToken)); + AsyncDuplexStreamingCall RouteChat(CancellationToken token = default(CancellationToken)); + } + + // server-side interface + public interface IRouteGuide + { + Task GetFeature(ServerCallContext context, global::examples.Point request); + Task ListFeatures(ServerCallContext context, global::examples.Rectangle request, IServerStreamWriter responseStream); + Task RecordRoute(ServerCallContext context, IAsyncStreamReader requestStream); + Task RouteChat(ServerCallContext context, IAsyncStreamReader requestStream, IServerStreamWriter responseStream); + } + + // client stub + public class RouteGuideClient : AbstractStub, IRouteGuideClient + { + public RouteGuideClient(Channel channel) : this(channel, StubConfiguration.Default) + { + } + public RouteGuideClient(Channel channel, StubConfiguration config) : base(channel, config) + { + } + public global::examples.Feature GetFeature(global::examples.Point request, CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_GetFeature); + return Calls.BlockingUnaryCall(call, request, token); + } + public Task GetFeatureAsync(global::examples.Point request, CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_GetFeature); + return Calls.AsyncUnaryCall(call, request, token); + } + public AsyncServerStreamingCall ListFeatures(global::examples.Rectangle request, CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_ListFeatures); + return Calls.AsyncServerStreamingCall(call, request, token); + } + public AsyncClientStreamingCall RecordRoute(CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_RecordRoute); + return Calls.AsyncClientStreamingCall(call, token); + } + public AsyncDuplexStreamingCall RouteChat(CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_RouteChat); + return Calls.AsyncDuplexStreamingCall(call, token); + } + } + + // creates service definition that can be registered with a server + public static ServerServiceDefinition BindService(IRouteGuide serviceImpl) + { + return ServerServiceDefinition.CreateBuilder(__ServiceName) + .AddMethod(__Method_GetFeature, serviceImpl.GetFeature) + .AddMethod(__Method_ListFeatures, serviceImpl.ListFeatures) + .AddMethod(__Method_RecordRoute, serviceImpl.RecordRoute) + .AddMethod(__Method_RouteChat, serviceImpl.RouteChat).Build(); + } + + // creates a new client stub + public static IRouteGuideClient NewStub(Channel channel) + { + return new RouteGuideClient(channel); + } + + // creates a new client stub + public static IRouteGuideClient NewStub(Channel channel, StubConfiguration config) + { + return new RouteGuideClient(channel, config); + } + } +} +#endregion diff --git a/grpc-common/csharp/route_guide/RouteGuide/RouteGuideUtil.cs b/grpc-common/csharp/route_guide/RouteGuide/RouteGuideUtil.cs new file mode 100644 index 0000000000..6fb8b1e28a --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuide/RouteGuideUtil.cs @@ -0,0 +1,67 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace examples +{ + public static class RouteGuideUtil + { + public const string DefaultFeaturesFile = "route_guide_db.json"; + + private const double CoordFactor = 1e7; + + /// + /// Indicates whether the given feature exists (i.e. has a valid name). + /// + public static bool Exists(Feature feature) + { + return feature != null && (feature.Name.Length != 0); + } + + public static double GetLatitude(Point point) + { + return point.Latitude / CoordFactor; + } + + public static double GetLongitude(Point point) + { + return point.Longitude / CoordFactor; + } + + /// + /// Parses features from a JSON file. + /// + public static List ParseFeatures(string filename) + { + var features = new List(); + var jsonFeatures = JsonConvert.DeserializeObject>(File.ReadAllText(filename)); + + + foreach(var jsonFeature in jsonFeatures) + { + features.Add(Feature.CreateBuilder().SetName(jsonFeature.name).SetLocation( + Point.CreateBuilder() + .SetLongitude(jsonFeature.location.longitude) + .SetLatitude(jsonFeature.location.latitude).Build()).Build()); + } + return features; + } + + private class JsonFeature + { + public string name; + public JsonLocation location; + } + + private class JsonLocation + { + public int longitude; + public int latitude; + } + } +} diff --git a/grpc-common/csharp/route_guide/RouteGuide/packages.config b/grpc-common/csharp/route_guide/RouteGuide/packages.config new file mode 100644 index 0000000000..79abe0aa65 --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuide/packages.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuide/protos/route_guide.proto b/grpc-common/csharp/route_guide/RouteGuide/protos/route_guide.proto new file mode 100644 index 0000000000..f4110b5515 --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuide/protos/route_guide.proto @@ -0,0 +1,123 @@ +// 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. + +// TODO(jtattermusch): as of now, C# protobufs don't officially support +// proto3. +syntax = "proto2"; + +package examples; + +// Interface exported by the server. +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + // + // A feature with an empty name is returned if there's no feature at the given + // position. + rpc GetFeature(Point) returns (Feature) {} + + // A server-to-client streaming RPC. + // + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} + + // A client-to-server streaming RPC. + // + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} + + // A Bidirectional streaming RPC. + // + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +} + +// Points are represented as latitude-longitude pairs in the E7 representation +// (degrees multiplied by 10**7 and rounded to the nearest integer). +// Latitudes should be in the range +/- 90 degrees and longitude should be in +// the range +/- 180 degrees (inclusive). +message Point { + optional int32 latitude = 1; + optional int32 longitude = 2; +} + +// A latitude-longitude rectangle, represented as two diagonally opposite +// points "lo" and "hi". +message Rectangle { + // One corner of the rectangle. + optional Point lo = 1; + + // The other corner of the rectangle. + optional Point hi = 2; +} + +// A feature names something at a given point. +// +// If a feature could not be named, the name is empty. +message Feature { + // The name of the feature. + optional string name = 1; + + // The point where the feature is detected. + optional Point location = 2; +} + +// A RouteNote is a message sent while at a given point. +message RouteNote { + // The location from which the message is sent. + optional Point location = 1; + + // The message to be sent. + optional string message = 2; +} + +// A RouteSummary is received in response to a RecordRoute rpc. +// +// It contains the number of individual points received, the number of +// detected features, and the total distance covered as the cumulative sum of +// the distance between each point. +message RouteSummary { + // The number of points received. + optional int32 point_count = 1; + + // The number of known features passed while traversing the route. + optional int32 feature_count = 2; + + // The distance covered in metres. + optional int32 distance = 3; + + // The duration of the traversal in seconds. + optional int32 elapsed_time = 4; +} diff --git a/grpc-common/csharp/route_guide/RouteGuide/route_guide_db.json b/grpc-common/csharp/route_guide/RouteGuide/route_guide_db.json new file mode 100644 index 0000000000..209f016259 --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuide/route_guide_db.json @@ -0,0 +1,601 @@ +[{ + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" +}, { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" +}, { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" +}, { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" +}, { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" +}, { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" +}, { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" +}, { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" +}, { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" +}, { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" +}, { + "location": { + "latitude": 415736605, + "longitude": -742847522 + }, + "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" +}, { + "location": { + "latitude": 413843930, + "longitude": -740501726 + }, + "name": "162 Merrill Road, Highland Mills, NY 10930, USA" +}, { + "location": { + "latitude": 410873075, + "longitude": -744459023 + }, + "name": "Clinton Road, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 412346009, + "longitude": -744026814 + }, + "name": "16 Old Brook Lane, Warwick, NY 10990, USA" +}, { + "location": { + "latitude": 402948455, + "longitude": -747903913 + }, + "name": "3 Drake Lane, Pennington, NJ 08534, USA" +}, { + "location": { + "latitude": 406337092, + "longitude": -740122226 + }, + "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" +}, { + "location": { + "latitude": 406421967, + "longitude": -747727624 + }, + "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" +}, { + "location": { + "latitude": 416318082, + "longitude": -749677716 + }, + "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" +}, { + "location": { + "latitude": 415301720, + "longitude": -748416257 + }, + "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" +}, { + "location": { + "latitude": 402647019, + "longitude": -747071791 + }, + "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" +}, { + "location": { + "latitude": 412567807, + "longitude": -741058078 + }, + "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" +}, { + "location": { + "latitude": 416855156, + "longitude": -744420597 + }, + "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" +}, { + "location": { + "latitude": 404663628, + "longitude": -744820157 + }, + "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" +}, { + "location": { + "latitude": 407113723, + "longitude": -749746483 + }, + "name": "" +}, { + "location": { + "latitude": 402133926, + "longitude": -743613249 + }, + "name": "" +}, { + "location": { + "latitude": 400273442, + "longitude": -741220915 + }, + "name": "" +}, { + "location": { + "latitude": 411236786, + "longitude": -744070769 + }, + "name": "" +}, { + "location": { + "latitude": 411633782, + "longitude": -746784970 + }, + "name": "211-225 Plains Road, Augusta, NJ 07822, USA" +}, { + "location": { + "latitude": 415830701, + "longitude": -742952812 + }, + "name": "" +}, { + "location": { + "latitude": 413447164, + "longitude": -748712898 + }, + "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" +}, { + "location": { + "latitude": 405047245, + "longitude": -749800722 + }, + "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" +}, { + "location": { + "latitude": 418858923, + "longitude": -746156790 + }, + "name": "" +}, { + "location": { + "latitude": 417951888, + "longitude": -748484944 + }, + "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" +}, { + "location": { + "latitude": 407033786, + "longitude": -743977337 + }, + "name": "26 East 3rd Street, New Providence, NJ 07974, USA" +}, { + "location": { + "latitude": 417548014, + "longitude": -740075041 + }, + "name": "" +}, { + "location": { + "latitude": 410395868, + "longitude": -744972325 + }, + "name": "" +}, { + "location": { + "latitude": 404615353, + "longitude": -745129803 + }, + "name": "" +}, { + "location": { + "latitude": 406589790, + "longitude": -743560121 + }, + "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" +}, { + "location": { + "latitude": 414653148, + "longitude": -740477477 + }, + "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" +}, { + "location": { + "latitude": 405957808, + "longitude": -743255336 + }, + "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" +}, { + "location": { + "latitude": 411733589, + "longitude": -741648093 + }, + "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" +}, { + "location": { + "latitude": 412676291, + "longitude": -742606606 + }, + "name": "1270 Lakes Road, Monroe, NY 10950, USA" +}, { + "location": { + "latitude": 409224445, + "longitude": -748286738 + }, + "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" +}, { + "location": { + "latitude": 406523420, + "longitude": -742135517 + }, + "name": "652 Garden Street, Elizabeth, NJ 07202, USA" +}, { + "location": { + "latitude": 401827388, + "longitude": -740294537 + }, + "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" +}, { + "location": { + "latitude": 410564152, + "longitude": -743685054 + }, + "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 408472324, + "longitude": -740726046 + }, + "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" +}, { + "location": { + "latitude": 412452168, + "longitude": -740214052 + }, + "name": "5 White Oak Lane, Stony Point, NY 10980, USA" +}, { + "location": { + "latitude": 409146138, + "longitude": -746188906 + }, + "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" +}, { + "location": { + "latitude": 404701380, + "longitude": -744781745 + }, + "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 409642566, + "longitude": -746017679 + }, + "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" +}, { + "location": { + "latitude": 408031728, + "longitude": -748645385 + }, + "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" +}, { + "location": { + "latitude": 413700272, + "longitude": -742135189 + }, + "name": "367 Prospect Road, Chester, NY 10918, USA" +}, { + "location": { + "latitude": 404310607, + "longitude": -740282632 + }, + "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" +}, { + "location": { + "latitude": 409319800, + "longitude": -746201391 + }, + "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" +}, { + "location": { + "latitude": 406685311, + "longitude": -742108603 + }, + "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" +}, { + "location": { + "latitude": 419018117, + "longitude": -749142781 + }, + "name": "43 Dreher Road, Roscoe, NY 12776, USA" +}, { + "location": { + "latitude": 412856162, + "longitude": -745148837 + }, + "name": "Swan Street, Pine Island, NY 10969, USA" +}, { + "location": { + "latitude": 416560744, + "longitude": -746721964 + }, + "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" +}, { + "location": { + "latitude": 405314270, + "longitude": -749836354 + }, + "name": "" +}, { + "location": { + "latitude": 414219548, + "longitude": -743327440 + }, + "name": "" +}, { + "location": { + "latitude": 415534177, + "longitude": -742900616 + }, + "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" +}, { + "location": { + "latitude": 406898530, + "longitude": -749127080 + }, + "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" +}, { + "location": { + "latitude": 407586880, + "longitude": -741670168 + }, + "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" +}, { + "location": { + "latitude": 400106455, + "longitude": -742870190 + }, + "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" +}, { + "location": { + "latitude": 400066188, + "longitude": -746793294 + }, + "name": "" +}, { + "location": { + "latitude": 418803880, + "longitude": -744102673 + }, + "name": "40 Mountain Road, Napanoch, NY 12458, USA" +}, { + "location": { + "latitude": 414204288, + "longitude": -747895140 + }, + "name": "" +}, { + "location": { + "latitude": 414777405, + "longitude": -740615601 + }, + "name": "" +}, { + "location": { + "latitude": 415464475, + "longitude": -747175374 + }, + "name": "48 North Road, Forestburgh, NY 12777, USA" +}, { + "location": { + "latitude": 404062378, + "longitude": -746376177 + }, + "name": "" +}, { + "location": { + "latitude": 405688272, + "longitude": -749285130 + }, + "name": "" +}, { + "location": { + "latitude": 400342070, + "longitude": -748788996 + }, + "name": "" +}, { + "location": { + "latitude": 401809022, + "longitude": -744157964 + }, + "name": "" +}, { + "location": { + "latitude": 404226644, + "longitude": -740517141 + }, + "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" +}, { + "location": { + "latitude": 410322033, + "longitude": -747871659 + }, + "name": "" +}, { + "location": { + "latitude": 407100674, + "longitude": -747742727 + }, + "name": "" +}, { + "location": { + "latitude": 418811433, + "longitude": -741718005 + }, + "name": "213 Bush Road, Stone Ridge, NY 12484, USA" +}, { + "location": { + "latitude": 415034302, + "longitude": -743850945 + }, + "name": "" +}, { + "location": { + "latitude": 411349992, + "longitude": -743694161 + }, + "name": "" +}, { + "location": { + "latitude": 404839914, + "longitude": -744759616 + }, + "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 414638017, + "longitude": -745957854 + }, + "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" +}, { + "location": { + "latitude": 412127800, + "longitude": -740173578 + }, + "name": "" +}, { + "location": { + "latitude": 401263460, + "longitude": -747964303 + }, + "name": "" +}, { + "location": { + "latitude": 412843391, + "longitude": -749086026 + }, + "name": "" +}, { + "location": { + "latitude": 418512773, + "longitude": -743067823 + }, + "name": "" +}, { + "location": { + "latitude": 404318328, + "longitude": -740835638 + }, + "name": "42-102 Main Street, Belford, NJ 07718, USA" +}, { + "location": { + "latitude": 419020746, + "longitude": -741172328 + }, + "name": "" +}, { + "location": { + "latitude": 404080723, + "longitude": -746119569 + }, + "name": "" +}, { + "location": { + "latitude": 401012643, + "longitude": -744035134 + }, + "name": "" +}, { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" +}, { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" +}, { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" +}, { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" +}, { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" +}, { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" +}, { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" +}, { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" +}, { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" +}, { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" +}] \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuideClient/App.config b/grpc-common/csharp/route_guide/RouteGuideClient/App.config new file mode 100644 index 0000000000..8e15646352 --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuideClient/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuideClient/Program.cs b/grpc-common/csharp/route_guide/RouteGuideClient/Program.cs new file mode 100644 index 0000000000..0352c78020 --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuideClient/Program.cs @@ -0,0 +1,223 @@ +using Grpc.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace examples +{ + class Program + { + /// + /// Sample client code that makes gRPC calls to the server. + /// + public class RouteGuideClient + { + readonly RouteGuide.IRouteGuideClient client; + + public RouteGuideClient(RouteGuide.IRouteGuideClient client) + { + this.client = client; + } + + /// + /// Blocking unary call example. Calls GetFeature and prints the response. + /// + public void GetFeature(int lat, int lon) + { + try + { + Log("*** GetFeature: lat={0} lon={1}", lat, lon); + + Point request = Point.CreateBuilder().SetLatitude(lat).SetLongitude(lon).Build(); + + Feature feature = client.GetFeature(request); + if (RouteGuideUtil.Exists(feature)) + { + Log("Found feature called \"{0}\" at {1}, {2}", + feature.Name, + RouteGuideUtil.GetLatitude(feature.Location), + RouteGuideUtil.GetLongitude(feature.Location)); + } + else + { + Log("Found no feature at {0}, {1}", + RouteGuideUtil.GetLatitude(feature.Location), + RouteGuideUtil.GetLongitude(feature.Location)); + } + } + catch (RpcException e) + { + Log("RPC failed " + e); + throw e; + } + } + + + /// + /// Server-streaming example. Calls listFeatures with a rectangle of interest. Prints each response feature as it arrives. + /// + public async Task ListFeatures(int lowLat, int lowLon, int hiLat, int hiLon) + { + try + { + Log("*** ListFeatures: lowLat={0} lowLon={1} hiLat={2} hiLon={3}", lowLat, lowLon, hiLat, + hiLon); + + Rectangle request = + Rectangle.CreateBuilder() + .SetLo(Point.CreateBuilder().SetLatitude(lowLat).SetLongitude(lowLon).Build()) + .SetHi(Point.CreateBuilder().SetLatitude(hiLat).SetLongitude(hiLon).Build()).Build(); + + using (var call = client.ListFeatures(request)) + { + StringBuilder responseLog = new StringBuilder("Result: "); + + while (await call.ResponseStream.MoveNext()) + { + Feature feature = call.ResponseStream.Current; + responseLog.Append(feature.ToString()); + } + Log(responseLog.ToString()); + } + } + catch (RpcException e) + { + Log("RPC failed " + e); + throw e; + } + } + + /// + /// Client-streaming example. Sends numPoints randomly chosen points from features + /// with a variable delay in between. Prints the statistics when they are sent from the server. + /// + public async Task RecordRoute(List features, int numPoints) + { + try + { + Log("*** RecordRoute"); + using (var call = client.RecordRoute()) + { + // Send numPoints points randomly selected from the features list. + StringBuilder numMsg = new StringBuilder(); + Random rand = new Random(); + for (int i = 0; i < numPoints; ++i) + { + int index = rand.Next(features.Count); + Point point = features[index].Location; + Log("Visiting point {0}, {1}", RouteGuideUtil.GetLatitude(point), + RouteGuideUtil.GetLongitude(point)); + + await call.RequestStream.WriteAsync(point); + + // A bit of delay before sending the next one. + await Task.Delay(rand.Next(1000) + 500); + } + await call.RequestStream.CompleteAsync(); + + RouteSummary summary = await call.Result; + Log("Finished trip with {0} points. Passed {1} features. " + + "Travelled {2} meters. It took {3} seconds.", summary.PointCount, + summary.FeatureCount, summary.Distance, summary.ElapsedTime); + + Log("Finished RecordRoute"); + } + } + catch (RpcException e) + { + Log("RPC failed", e); + throw e; + } + } + + /// + /// Bi-directional streaming example. Send some chat messages, and print any + /// chat messages that are sent from the server. + /// + public async Task RouteChat() + { + try + { + Log("*** RouteChat"); + var requests = + new List { NewNote("First message", 0, 0), NewNote("Second message", 0, 1), NewNote("Third message", 1, 0), NewNote("Fourth message", 1, 1) }; + + using (var call = client.RouteChat()) + { + var responseReaderTask = Task.Run(async () => + { + while (await call.ResponseStream.MoveNext()) + { + var note = call.ResponseStream.Current; + Log("Got message \"{0}\" at {1}, {2}", note.Message, + note.Location.Latitude, note.Location.Longitude); + } + }); + + foreach (RouteNote request in requests) + { + Log("Sending message \"{0}\" at {1}, {2}", request.Message, + request.Location.Latitude, request.Location.Longitude); + + await call.RequestStream.WriteAsync(request); + } + await call.RequestStream.CompleteAsync(); + await responseReaderTask; + + Log("Finished RouteChat"); + } + } + catch (RpcException e) + { + Log("RPC failed", e); + throw e; + } + } + + private void Log(string s, params object[] args) + { + Console.WriteLine(string.Format(s, args)); + } + + private void Log(string s) + { + Console.WriteLine(s); + } + + private RouteNote NewNote(string message, int lat, int lon) + { + return RouteNote.CreateBuilder().SetMessage(message).SetLocation( + Point.CreateBuilder().SetLatitude(lat).SetLongitude(lat).Build()).Build(); + } + } + + static void Main(string[] args) + { + GrpcEnvironment.Initialize(); + + using (Channel channel = new Channel("127.0.0.1:50052")) + { + var client = new RouteGuideClient(RouteGuide.NewStub(channel)); + + // Looking for a valid feature + client.GetFeature(409146138, -746188906); + + // Feature missing. + client.GetFeature(0, 0); + + // Looking for features between 40, -75 and 42, -73. + client.ListFeatures(400000000, -750000000, 420000000, -730000000).Wait(); + + // Record a few randomly selected points from the features file. + client.RecordRoute(RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile), 10).Wait(); + + // Send and receive some notes. + client.RouteChat().Wait(); + } + + GrpcEnvironment.Shutdown(); + } + } +} diff --git a/grpc-common/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs b/grpc-common/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..a17e164a78 --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RouteGuideClient")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RouteGuideClient")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("914644eb-47cd-4a37-9fba-5e62dd432333")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/grpc-common/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj b/grpc-common/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj new file mode 100644 index 0000000000..78034a9145 --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj @@ -0,0 +1,100 @@ + + + + + + + + Debug + AnyCPU + {D47BE663-4DE3-4206-B7A8-EA3FA066DADC} + Exe + Properties + RouteGuideClient + RouteGuideClient + v4.5 + 512 + 794416d0 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll + + + False + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll + + + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + + ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll + + + + + + + + + + + + + + + + + + {49954d9c-5f17-4662-96b2-73be833dd81a} + RouteGuide + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + + \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuideClient/packages.config b/grpc-common/csharp/route_guide/RouteGuideClient/packages.config new file mode 100644 index 0000000000..5922553bc3 --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuideClient/packages.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuideServer/App.config b/grpc-common/csharp/route_guide/RouteGuideServer/App.config new file mode 100644 index 0000000000..8e15646352 --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuideServer/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuideServer/Program.cs b/grpc-common/csharp/route_guide/RouteGuideServer/Program.cs new file mode 100644 index 0000000000..e00b4d6723 --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuideServer/Program.cs @@ -0,0 +1,30 @@ +using Grpc.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace examples +{ + class Program + { + static void Main(string[] args) + { + var features = RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile); + GrpcEnvironment.Initialize(); + + Server server = new Server(); + server.AddServiceDefinition(RouteGuide.BindService(new RouteGuideImpl(features))); + int port = server.AddListeningPort("localhost", 50052); + server.Start(); + + Console.WriteLine("RouteGuide server listening on port " + port); + Console.WriteLine("Press any key to stop the server..."); + Console.ReadKey(); + + server.ShutdownAsync().Wait(); + GrpcEnvironment.Shutdown(); + } + } +} diff --git a/grpc-common/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs b/grpc-common/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..a161b1d602 --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RouteGuideServer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RouteGuideServer")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("908bdeef-05cc-42bf-9498-c4c573df8925")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs b/grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs new file mode 100644 index 0000000000..0bdf386fc3 --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs @@ -0,0 +1,184 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace examples +{ + /// + /// Example implementation of RouteGuide server. + /// + public class RouteGuideImpl : RouteGuide.IRouteGuide + { + readonly List features; + private readonly ConcurrentDictionary> routeNotes = + new ConcurrentDictionary>(); + + public RouteGuideImpl(List features) + { + this.features = features; + } + + /// + /// Gets the feature at the requested point. If no feature at that location + /// exists, an unnammed feature is returned at the provided location. + /// + public Task GetFeature(Grpc.Core.ServerCallContext context, Point request) + { + return Task.FromResult(CheckFeature(request)); + } + + /// + /// Gets all features contained within the given bounding rectangle. + /// + public async Task ListFeatures(Grpc.Core.ServerCallContext context, Rectangle request, Grpc.Core.IServerStreamWriter responseStream) + { + int left = Math.Min(request.Lo.Longitude, request.Hi.Longitude); + int right = Math.Max(request.Lo.Longitude, request.Hi.Longitude); + int top = Math.Max(request.Lo.Latitude, request.Hi.Latitude); + int bottom = Math.Min(request.Lo.Latitude, request.Hi.Latitude); + + foreach (var feature in features) + { + if (!RouteGuideUtil.Exists(feature)) + { + continue; + } + + int lat = feature.Location.Latitude; + int lon = feature.Location.Longitude; + if (lon >= left && lon <= right && lat >= bottom && lat <= top) + { + await responseStream.WriteAsync(feature); + } + } + } + + /// + /// Gets a stream of points, and responds with statistics about the "trip": number of points, + /// number of known features visited, total distance traveled, and total time spent. + /// + public async Task RecordRoute(Grpc.Core.ServerCallContext context, Grpc.Core.IAsyncStreamReader requestStream) + { + int pointCount = 0; + int featureCount = 0; + int distance = 0; + Point previous = null; + var stopwatch = new Stopwatch(); + stopwatch.Start(); + + while (await requestStream.MoveNext()) + { + var point = requestStream.Current; + pointCount++; + if (RouteGuideUtil.Exists(CheckFeature(point))) + { + featureCount++; + } + if (previous != null) + { + distance += (int) CalcDistance(previous, point); + } + previous = point; + } + + stopwatch.Stop(); + return RouteSummary.CreateBuilder().SetPointCount(pointCount) + .SetFeatureCount(featureCount).SetDistance(distance) + .SetElapsedTime((int) (stopwatch.ElapsedMilliseconds / 1000)).Build(); + } + + /// + /// Receives a stream of message/location pairs, and responds with a stream of all previous + /// messages at each of those locations. + /// + public async Task RouteChat(Grpc.Core.ServerCallContext context, Grpc.Core.IAsyncStreamReader requestStream, Grpc.Core.IServerStreamWriter responseStream) + { + while (await requestStream.MoveNext()) + { + var note = requestStream.Current; + List notes = GetOrCreateNotes(note.Location); + + List prevNotes; + lock (notes) + { + prevNotes = new List(notes); + } + + foreach (var prevNote in prevNotes) + { + await responseStream.WriteAsync(prevNote); + } + + lock (notes) + { + notes.Add(note); + } + } + } + + + /// + /// Get the notes list for the given location. If missing, create it. + /// + private List GetOrCreateNotes(Point location) + { + List notes = new List(); + routeNotes.TryAdd(location, notes); + return routeNotes[location]; + } + + /// + /// Gets the feature at the given point. + /// + /// the location to check + /// The feature object at the point Note that an empty name indicates no feature. + private Feature CheckFeature(Point location) + { + foreach (var feature in features) + { + if (feature.Location.Latitude == location.Latitude + && feature.Location.Longitude == location.Longitude) + { + return feature; + } + } + + // No feature was found, return an unnamed feature. + return Feature.CreateBuilder().SetName("").SetLocation(location).Build(); + } + + /// + /// Calculate the distance between two points using the "haversine" formula. + /// This code was taken from http://www.movable-type.co.uk/scripts/latlong.html. + /// + /// the starting point + /// the end point + /// the distance between the points in meters + private static double CalcDistance(Point start, Point end) + { + double lat1 = RouteGuideUtil.GetLatitude(start); + double lat2 = RouteGuideUtil.GetLatitude(end); + double lon1 = RouteGuideUtil.GetLongitude(start); + double lon2 = RouteGuideUtil.GetLongitude(end); + int r = 6371000; // metres + double φ1 = ToRadians(lat1); + double φ2 = ToRadians(lat2); + double Δφ = ToRadians(lat2 - lat1); + double Δλ = ToRadians(lon2 - lon1); + + double a = Math.Sin(Δφ / 2) * Math.Sin(Δφ / 2) + Math.Cos(φ1) * Math.Cos(φ2) * Math.Sin(Δλ / 2) * Math.Sin(Δλ / 2); + double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); + + return r * c; + } + + private static double ToRadians(double val) + { + return (Math.PI / 180) * val; + } + } +} diff --git a/grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj b/grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj new file mode 100644 index 0000000000..9ac1cfbf4d --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj @@ -0,0 +1,101 @@ + + + + + + + + Debug + AnyCPU + {4B7C7794-BE24-4477-ACE7-18259EB73D27} + Exe + Properties + RouteGuideServer + RouteGuideServer + v4.5 + 512 + 74781d8b + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll + + + False + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll + + + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + + ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll + + + + + + + + + + + + + + + + + + + {49954d9c-5f17-4662-96b2-73be833dd81a} + RouteGuide + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + + \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuideServer/packages.config b/grpc-common/csharp/route_guide/RouteGuideServer/packages.config new file mode 100644 index 0000000000..5922553bc3 --- /dev/null +++ b/grpc-common/csharp/route_guide/RouteGuideServer/packages.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/grpc-common/go/README.md b/grpc-common/go/README.md new file mode 100644 index 0000000000..79db479ec5 --- /dev/null +++ b/grpc-common/go/README.md @@ -0,0 +1,53 @@ +gRPC in 3 minutes (Go) +====================== + +BACKGROUND +------------- +For this sample, we've already generated the server and client stubs from [helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). + +PREREQUISITES +------------- + +- This requires Go 1.4 +- Requires that [GOPATH is set](https://golang.org/doc/code.html#GOPATH) +```sh +$ go help gopath +$ # ensure the PATH contains $GOPATH/bin +$ export PATH=$PATH:$GOPATH/bin +``` + +INSTALL +------- + +```sh +$ go get -u github.com/grpc/grpc-common/go/greeter_client +$ go get -u github.com/grpc/grpc-common/go/greeter_server +``` + +TRY IT! +------- + +- Run the server +```sh +$ greeter_server & +``` + +- Run the client +```sh +$ greeter_client +``` + +OPTIONAL - Rebuilding the generated code +---------------------------------------- + +1 First [install protoc](https://github.com/google/protobuf/blob/master/INSTALL.txt) + - For now, this needs to be installed from source + - This is will change once proto3 is officially released + +2 Install the protoc Go plugin. +```sh +$ go get -a github.com/golang/protobuf/protoc-gen-go +$ +$ # from this dir; invoke protoc +$ protoc -I ../protos ../protos/helloworld.proto --go_out=plugins=grpc:helloworld +``` diff --git a/grpc-common/go/gotutorial.md b/grpc-common/go/gotutorial.md new file mode 100644 index 0000000000..63f0ad9058 --- /dev/null +++ b/grpc-common/go/gotutorial.md @@ -0,0 +1,431 @@ +#gRPC Basics: Go + +This tutorial provides a basic Go programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate server and client code using the protocol buffer compiler. +- Use the Go gRPC API to write a simple client and server for your service. + +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. + +This isn't a comprehensive guide to using gRPC in Go: more reference documentation is coming soon. + +## Why use gRPC? + +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-go/examples/route_guide](https://github.com/grpc/grpc-go/tree/master/examples/route_guide). To download the example, clone the `grpc-go` repository by running the following command: +```shell +$ go get google.golang.org/grpc +``` + +Then change your current directory to `grpc-go/examples/route_guide`: +```shell +$ cd $GOPATH/src/google.golang.org/grpc/examples/route_guide +``` + +You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Go quick start guide](https://github.com/grpc/grpc-common/tree/master/go). + + +## Defining the service + +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +```proto +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +```proto + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. +```proto + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} +``` + +- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a client-side streaming method by placing the `stream` keyword before the *request* type. +```proto + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +```proto + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +```proto +// 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; +} +``` + + +## Generating client and server code + +Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC Go plugin. + +For simplicity, we've provided a [bash script](https://github.com/grpc/grpc-go/blob/master/codegen.sh) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this by yourself, make sure you've installed protoc and followed the gRPC-Go [installation instructions](https://github.com/grpc/grpc-go/blob/master/README.md) first): + +```shell +$ codegen.sh route_guide.proto +``` + +which actually runs: + +```shell +$ protoc --go_out=plugins=grpc:. route_guide.proto +``` + +Running this command generates the following file in your current directory: +- `route_guide.pb.go` + +This contains: +- All the protocol buffer code to populate, serialize, and retrieve our request and response message types +- An interface type (or *stub*) for clients to call with the methods defined in the `RouteGuide` service. +- An interface type for servers to implement, also with the methods defined in the `RouteGuide` service. + + + +## Creating the server + +First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). + +There are two parts to making our `RouteGuide` service do its job: +- Implementing the service interface generated from our service definition: doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and dispatch them to the right service implementation. + +You can find our example `RouteGuide` server in [grpc-go/examples/route_guide/server/server.go](https://github.com/grpc/grpc-go/tree/master/examples/route_guide/server/server.go). Let's take a closer look at how it works. + +### Implementing RouteGuide + +As you can see, our server has a `routeGuideServer` struct type that implements the generated `RouteGuideServer` interface: + +```go +type routeGuideServer struct { + ... +} +... + +func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) { + ... +} +... + +func (s *routeGuideServer) ListFeatures(rect *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer) error { + ... +} +... + +func (s *routeGuideServer) RecordRoute(stream pb.RouteGuide_RecordRouteServer) error { + ... +} +... + +func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error { + ... +} +... +``` + +#### Simple RPC +`routeGuideServer` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. + +```go +func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) { + for _, feature := range s.savedFeatures { + if proto.Equal(feature.Location, point) { + return feature, nil + } + } + // No feature was found, return an unnamed feature + return &pb.Feature{"", point}, nil +} +``` + +The method is passed a context object for the RPC and the client's `Point` protocol buffer request. It returns a `Feature` protocol buffer object with the response information and an `error`. In the method we populate the `Feature` with the appropriate information, and then `return` it along with an `nil` error to tell gRPC that we've finished dealing with the RPC and that the `Feature` can be returned to the client. + +#### Server-side streaming RPC +Now let's look at one of our streaming RPCs. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. + +```go +func (s *routeGuideServer) ListFeatures(rect *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer) error { + for _, feature := range s.savedFeatures { + if inRange(feature.Location, rect) { + if err := stream.Send(feature); err != nil { + return err + } + } + } + return nil +} +``` + +As you can see, instead of getting simple request and response objects in our method parameters, this time we get a request object (the `Rectangle` in which our client wants to find `Feature`s) and a special `RouteGuide_ListFeaturesServer` object to write our responses. + +In the method, we populate as many `Feature` objects as we need to return, writing them to the `RouteGuide_ListFeaturesServer` using its `Send()` method. Finally, as in our simple RPC, we return a `nil` error to tell gRPC that we've finished writing responses. Should any error happen in this call, we return a non-`nil` error; the gRPC layer will translate it into an appropriate RPC status to be sent on the wire. + +#### Client-side streaming RPC +Now let's look at something a little more complicated: the client-side streaming method `RecordRoute`, where we get a stream of `Point`s from the client and return a single `RouteSummary` with information about their trip. As you can see, this time the method doesn't have a request parameter at all. Instead, it gets a `RouteGuide_RecordRouteServer` stream, which the server can use to both read *and* write messages - it can receive client messages using its `Recv()` method and return its single response using its `SendAndClose()` method. + +```go +func (s *routeGuideServer) RecordRoute(stream pb.RouteGuide_RecordRouteServer) error { + var pointCount, featureCount, distance int32 + var lastPoint *pb.Point + startTime := time.Now() + for { + point, err := stream.Recv() + if err == io.EOF { + endTime := time.Now() + return stream.SendAndClose(&pb.RouteSummary{ + PointCount: pointCount, + FeatureCount: featureCount, + Distance: distance, + ElapsedTime: int32(endTime.Sub(startTime).Seconds()), + }) + } + if err != nil { + return err + } + pointCount++ + for _, feature := range s.savedFeatures { + if proto.Equal(feature.Location, point) { + featureCount++ + } + } + if lastPoint != nil { + distance += calcDistance(lastPoint, point) + } + lastPoint = point + } +} +``` + +In the method body we use the `RouteGuide_RecordRouteServer`s `Recv()` method to repeatedly read in our client's requests to a request object (in this case a `Point`) until there are no more messages: the server needs to check the the error returned from `Read()` after each call. If this is `nil`, the stream is still good and it can continue reading; if it's `io.EOF` the message stream has ended and the server can return its `RouteSummary`. If it has any other value, we return the error "as is" so that it'll be translated to an RPC status by the gRPC layer. + +#### Bidirectional streaming RPC +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. + +```go +func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error { + for { + in, err := stream.Recv() + if err == io.EOF { + return nil + } + if err != nil { + return err + } + key := serialize(in.Location) + ... // look for notes to be sent to client + for _, note := range s.routeNotes[key] { + if err := stream.Send(note); err != nil { + return err + } + } + } +} +``` + +This time we get a `RouteGuide_RouteChatServer` stream that, as in our client-side streaming example, can be used to read and write messages. However, this time we return values via our method's stream while the client is still writing messages to *their* message stream. + +The syntax for reading and writing here is very similar to our client-streaming method, except the server uses the stream's `Send()` method rather than `SendAndClose()` because it's writing multiple responses. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + +### Starting the server + +Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: + +```go +flag.Parse() +lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port)) +if err != nil { + log.Fatalf("failed to listen: %v", err) +} +grpcServer := grpc.NewServer() +pb.RegisterRouteGuideServer(grpcServer, &routeGuideServer{}) +... // determine whether to use TLS +grpcServer.Serve(lis) +``` +To build and start a server, we: + +1. Specify the port we want to use to listen for client requests using `lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))`. +2. Create an instance of the gRPC server using `grpc.NewServer()`. +3. Register our service implementation with the gRPC server. +4. Call `Serve()` on the server with our port details to do a blocking wait until the process is killed or `Stop()` is called. + + +## Creating the client + +In this section, we'll look at creating a Go client for our `RouteGuide` service. You can see our complete example client code in [grpc-go/examples/route_guide/client/client.go](https://github.com/grpc/grpc-go/tree/master/examples/route_guide/client/client.go). + +### Creating a stub + +To call service methods, we first need to create a gRPC *channel* to communicate with the server. We create this by passing the server address and port number to `grpc.Dial()` as follows: + +```go +conn, err := grpc.Dial(*serverAddr) +if err != nil { + ... +} +defer conn.Close() +``` + +You can use `DialOptions` to set the auth credentials (e.g., TLS, GCE credentials, JWT credentials) in `grpc.Dial` if the service you request requires that - however, we don't need to do this for our `RouteGuide` service. + +Once the gRPC *channel* is setup, we need a client *stub* to perform RPCs. We get this using the `NewRouteGuideClient` method provided in the `pb` package we generated from our .proto. + +```go +client := pb.NewRouteGuideClient(conn) +``` + +### Calling service methods + +Now let's look at how we call our service methods. Note that in gRPC-Go, RPCs operate in a blocking/synchronous mode, which means that the RPC call waits for the server to respond, and will either return a response or an error. + +#### Simple RPC + +Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. + +```go +feature, err := client.GetFeature(context.Background(), &pb.Point{409146138, -746188906}) +if err != nil { + ... +} +``` + +As you can see, we call the method on the stub we got earlier. In our method parameters we create and populate a request protocol buffer object (in our case `Point`). We also pass a `context.Context` object which lets us change our RPC's behaviour if necessary, such as time-out/cancel an RPC in flight. If the call doesn't return an error, then we can read the response information from the server from the first return value. + +```go +log.Println(feature) +``` + +#### Server-side streaming RPC + +Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. + +```go +rect := &pb.Rectangle{ ... } // initialize a pb.Rectangle +stream, err := client.ListFeatures(context.Background(), rect) +if err != nil { + ... +} +for { + feature, err := stream.Recv() + if err == io.EOF { + break + } + if err != nil { + log.Fatalf("%v.ListFeatures(_) = _, %v", client, err) + } + log.Println(feature) +} +``` + +As in the simple RPC, we pass the method a context and a request. However, instead of getting a response object back, we get back an instance of `RouteGuide_ListFeaturesClient`. The client can use the `RouteGuide_ListFeaturesClient` stream to read the server's responses. + +We use the `RouteGuide_ListFeaturesClient`'s `Recv()` method to repeatedly read in the server's responses to a response protocol buffer object (in this case a `Feature`) until there are no more messages: the client needs to check the error `err` returned from `Recv()` after each call. If `nil`, the stream is still good and it can continue reading; if it's `io.EOF` then the message stream has ended; otherwise there must be an RPC error, which is passed over through `err`. + +#### Client-side streaming RPC + +The client-side streaming method `RecordRoute` is similar to the server-side method, except that we only pass the method a context and get a `RouteGuide_RecordRouteClient` stream back, which we can use to both write *and* read messages. + +```go +// Create a random number of random points +r := rand.New(rand.NewSource(time.Now().UnixNano())) +pointCount := int(r.Int31n(100)) + 2 // Traverse at least two points +var points []*pb.Point +for i := 0; i < pointCount; i++ { + points = append(points, randomPoint(r)) +} +log.Printf("Traversing %d points.", len(points)) +stream, err := client.RecordRoute(context.Background()) +if err != nil { + log.Fatalf("%v.RecordRoute(_) = _, %v", client, err) +} +for _, point := range points { + if err := stream.Send(point); err != nil { + log.Fatalf("%v.Send(%v) = %v", stream, point, err) + } +} +reply, err := stream.CloseAndRecv() +if err != nil { + log.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, nil) +} +log.Printf("Route summary: %v", reply) +``` + +The `RouteGuide_RecordRouteClient` has a `Send()` method that we can use to send requests to the server. Once we've finished writing our client's requests to the stream using `Send()`, we need to call `CloseAndRecv()` on the stream to let gRPC know that we've finished writing and are expecting to receive a response. We get our RPC status from the `err` returned from `CloseAndRecv()`. If the status is `nil`, then the first return value from `CloseAndRecv()` will be a valid server response. + +#### Bidirectional streaming RPC + +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. As in the case of `RecordRoute`, we only pass the method a context object and get back a stream that we can use to both write and read messages. However, this time we return values via our method's stream while the server is still writing messages to *their* message stream. + +```go +stream, err := client.RouteChat(context.Background()) +waitc := make(chan struct{}) +go func() { + for { + in, err := stream.Recv() + if err == io.EOF { + // read done. + close(waitc) + return + } + if err != nil { + log.Fatalf("Failed to receive a note : %v", err) + } + log.Printf("Got message %s at point(%d, %d)", in.Message, in.Location.Latitude, in.Location.Longitude) + } +}() +for _, note := range notes { + if err := stream.Send(note); err != nil { + log.Fatalf("Failed to send a note: %v", err) + } +} +stream.CloseSend() +<-waitc +``` + +The syntax for reading and writing here is very similar to our client-side streaming method, except we use the stream's `CloseSend()` method once we've finished our call. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + +## Try it out! + +To compile and run the server, assuming you are in the folder +`$GOPATH/src/google.golang.org/grpc/examples/route_guide`, simply: + +```sh +$ go run server/server.go +``` + +Likewise, to run the client: + +```sh +$ go run client/client.go +``` + diff --git a/grpc-common/go/greeter_client/main.go b/grpc-common/go/greeter_client/main.go new file mode 100644 index 0000000000..065ae852bc --- /dev/null +++ b/grpc-common/go/greeter_client/main.go @@ -0,0 +1,69 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +package main + +import ( + "log" + "os" + + pb "github.com/grpc/grpc-common/go/helloworld" + "golang.org/x/net/context" + "google.golang.org/grpc" +) + +const ( + address = "localhost:50051" + defaultName = "world" +) + +func main() { + // Set up a connection to the server. + conn, err := grpc.Dial(address) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + defer conn.Close() + c := pb.NewGreeterClient(conn) + + // Contact the server and print out its response. + name := defaultName + if len(os.Args) > 1 { + name = os.Args[1] + } + r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name}) + if err != nil { + log.Fatalf("could not greet: %v", err) + } + log.Printf("Greeting: %s", r.Message) +} diff --git a/grpc-common/go/greeter_server/main.go b/grpc-common/go/greeter_server/main.go new file mode 100644 index 0000000000..c7fa06ad18 --- /dev/null +++ b/grpc-common/go/greeter_server/main.go @@ -0,0 +1,65 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +package main + +import ( + "log" + "net" + + pb "github.com/grpc/grpc-common/go/helloworld" + "golang.org/x/net/context" + "google.golang.org/grpc" +) + +const ( + port = ":50051" +) + +// server is used to implement hellowrld.GreeterServer. +type server struct{} + +// SayHello implements helloworld.GreeterServer +func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { + return &pb.HelloReply{Message: "Hello " + in.Name}, nil +} + +func main() { + lis, err := net.Listen("tcp", port) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + s := grpc.NewServer() + pb.RegisterGreeterServer(s, &server{}) + s.Serve(lis) +} diff --git a/grpc-common/go/helloworld/helloworld.pb.go b/grpc-common/go/helloworld/helloworld.pb.go new file mode 100644 index 0000000000..1ff931a384 --- /dev/null +++ b/grpc-common/go/helloworld/helloworld.pb.go @@ -0,0 +1,109 @@ +// Code generated by protoc-gen-go. +// source: helloworld.proto +// DO NOT EDIT! + +/* +Package helloworld is a generated protocol buffer package. + +It is generated from these files: + helloworld.proto + +It has these top-level messages: + HelloRequest + HelloReply +*/ +package helloworld + +import proto "github.com/golang/protobuf/proto" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal + +// The request message containing the user's name. +type HelloRequest struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` +} + +func (m *HelloRequest) Reset() { *m = HelloRequest{} } +func (m *HelloRequest) String() string { return proto.CompactTextString(m) } +func (*HelloRequest) ProtoMessage() {} + +// The response message containing the greetings +type HelloReply struct { + Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` +} + +func (m *HelloReply) Reset() { *m = HelloReply{} } +func (m *HelloReply) String() string { return proto.CompactTextString(m) } +func (*HelloReply) ProtoMessage() {} + +func init() { +} + +// Client API for Greeter service + +type GreeterClient interface { + // Sends a greeting + SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) +} + +type greeterClient struct { + cc *grpc.ClientConn +} + +func NewGreeterClient(cc *grpc.ClientConn) GreeterClient { + return &greeterClient{cc} +} + +func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) { + out := new(HelloReply) + err := grpc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for Greeter service + +type GreeterServer interface { + // Sends a greeting + SayHello(context.Context, *HelloRequest) (*HelloReply, error) +} + +func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) { + s.RegisterService(&_Greeter_serviceDesc, srv) +} + +func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { + in := new(HelloRequest) + if err := codec.Unmarshal(buf, in); err != nil { + return nil, err + } + out, err := srv.(GreeterServer).SayHello(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + +var _Greeter_serviceDesc = grpc.ServiceDesc{ + ServiceName: "helloworld.Greeter", + HandlerType: (*GreeterServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SayHello", + Handler: _Greeter_SayHello_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, +} diff --git a/grpc-common/grpc-auth-support.md b/grpc-common/grpc-auth-support.md new file mode 100644 index 0000000000..b9ef299332 --- /dev/null +++ b/grpc-common/grpc-auth-support.md @@ -0,0 +1,289 @@ +#gRPC Authentication support + +gRPC is designed to plug-in a number of authentication mechanisms. This document +provides a quick overview of the various auth mechanisms supported, discusses +the API with some examples, and concludes with a discussion of extensibility. +More documentation and examples are coming soon! + +## Supported auth mechanisms + +###SSL/TLS +gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the +server, and encrypt all the data exchanged between the client and the server. +Optional mechanisms are available for clients to provide certificates to +accomplish mutual authentication. + +###OAuth 2.0 +gRPC provides a generic mechanism (described below) to attach metadata to +requests and responses. This mechanism can be used to attach OAuth 2.0 Access +Tokens to RPCs being made at a client. Additional support for acquiring Access +Tokens while accessing Google APIs through gRPC is provided for certain auth +flows, demonstrated through code examples below. + +## API +To reduce complexity and minimize API clutter, gRPC works with a unified concept +of a Credentials object. Users construct gRPC credentials using corresponding +bootstrap credentials (e.g., SSL client certs or Service Account Keys), and use +the credentials while creating a gRPC channel to any server. Depending on the +type of credential supplied, the channel uses the credentials during the initial +SSL/TLS handshake with the server, or uses the credential to generate and +attach Access Tokens to each request being made on the channel. + +###SSL/TLS for server authentication and encryption +This is the simplest authentication scenario, where a client just wants to +authenticate the server and encrypt all data. + +```cpp +SslCredentialsOptions ssl_opts; // Options to override SSL params, empty by default +// Create the credentials object by providing service account key in constructor +std::unique_ptr creds = CredentialsFactory::SslCredentials(ssl_opts); +// Create a channel using the credentials created in the previous step +std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); +// Create a stub on the channel +std::unique_ptr stub(Greeter::NewStub(channel)); +// Make actual RPC calls on the stub. +grpc::Status s = stub->sayHello(&context, *request, response); +``` + +For advanced use cases such as modifying the root CA or using client certs, +the corresponding options can be set in the SslCredentialsOptions parameter +passed to the factory method. + + +###Authenticating with Google + +gRPC applications can use a simple API to create a credential that works in various deployment scenarios. + +```cpp +std::unique_ptr creds = CredentialsFactory::GoogleDefaultCredentials(); +// Create a channel, stub and make RPC calls (same as in the previous example) +std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); +std::unique_ptr stub(Greeter::NewStub(channel)); +grpc::Status s = stub->sayHello(&context, *request, response); +``` + +This credential works for applications using Service Accounts as well as for +applications running in [Google Compute Engine (GCE)](https://cloud.google.com/compute/). In the former case, the +service account’s private keys are loaded from the file named in the environment +variable `GOOGLE_APPLICATION_CREDENTIALS`. The +keys are used to generate bearer tokens that are attached to each outgoing RPC +on the corresponding channel. + +For applications running in GCE, a default service account and corresponding +OAuth scopes can be configured during VM setup. At run-time, this credential +handles communication with the authentication systems to obtain OAuth2 access +tokens and attaches them to each outgoing RPC on the corresponding channel. +Extending gRPC to support other authentication mechanisms +The gRPC protocol is designed with a general mechanism for sending metadata +associated with RPC. Clients can send metadata at the beginning of an RPC and +servers can send back metadata at the beginning and end of the RPC. This +provides a natural mechanism to support OAuth2 and other authentication +mechanisms that need attach bearer tokens to individual request. + +In the simplest case, there is a single line of code required on the client +to add a specific token as metadata to an RPC and a corresponding access on +the server to retrieve this piece of metadata. The generation of the token +on the client side and its verification at the server can be done separately. + +A deeper integration can be achieved by plugging in a gRPC credentials implementation for any custom authentication mechanism that needs to attach per-request tokens. gRPC internals also allow switching out SSL/TLS with other encryption mechanisms. + +## Examples + +These authentication mechanisms will be available in all gRPC's supported languages. +The following sections demonstrate how authentication and authorization features described above appear in each language: more languages are coming soon. + +###SSL/TLS for server authentication and encryption (Ruby) +```ruby +# Base case - No encryption +stub = Helloworld::Greeter::Stub.new('localhost:50051') +... + +# With server authentication SSL/TLS +creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file +stub = Helloworld::Greeter::Stub.new('localhost:50051', creds: creds) +``` + +###SSL/TLS for server authentication and encryption (C#) +```csharp +// Base case - No encryption +var channel = new Channel("localhost:50051"); +var client = new Greeter.GreeterClient(channel); +... + +// With server authentication SSL/TLS +var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file +var channel = new Channel("localhost:50051", credentials); +var client = new Greeter.GreeterClient(channel); +``` + +###SSL/TLS for server authentication and encryption (Objective-C) + +The default for Objective-C is to use SSL/TLS, as that's the most common use case when accessing +remote APIs. + +```objective-c +// Base case - With server authentication SSL/TLS +HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"localhost:50051"]; +// Same as using @"https://localhost:50051". +... + +// No encryption +HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"http://localhost:50051"]; +// Specifying the HTTP scheme explicitly forces no encryption. +``` + +###SSL/TLS for server authentication and encryption (Python) +```python +# Base case - No encryption +stub = early_adopter_create_GreeterService_stub('localhost', 50051) +... + +# With server authentication SSL/TLS +stub = early_adopter_create_GreeterService_stub( + 'localhost', 50051, secure=True, root_certificates=open('ca.pem').read()) +... +``` +n.b.: the beta API will look different + +###Authenticating with Google (Ruby) +```ruby +# Base case - No encryption/authorization +stub = Helloworld::Greeter::Stub.new('localhost:50051') +... + +# Authenticating with Google +require 'googleauth' # from http://www.rubydoc.info/gems/googleauth/0.1.0 +... +creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file +scope = 'https://www.googleapis.com/auth/grpc-testing' +authorization = Google::Auth.get_application_default(scope) +stub = Helloworld::Greeter::Stub.new('localhost:50051', + creds: creds, + update_metadata: authorization.updater_proc) +``` + +###Authenticating with Google (Node.js) + +```node +// Base case - No encryption/authorization +var stub = new helloworld.Greeter('localhost:50051'); +... +// Authenticating with Google +var GoogleAuth = require('google-auth-library'); // from https://www.npmjs.com/package/google-auth-library +... +var creds = grpc.Credentials.createSsl(load_certs); // load_certs typically loads a CA roots file +var scope = 'https://www.googleapis.com/auth/grpc-testing'; +(new GoogleAuth()).getApplicationDefault(function(err, auth) { + if (auth.createScopeRequired()) { + auth = auth.createScoped(scope); + } + var stub = new helloworld.Greeter('localhost:50051', + {credentials: creds}, + grpc.getGoogleAuthDelegate(auth)); +}); +``` + +###Authenticating with Google (C#) +```csharp +// Base case - No encryption/authorization +var channel = new Channel("localhost:50051"); +var client = new Greeter.GreeterClient(channel); +... + +// Authenticating with Google +using Grpc.Auth; // from Grpc.Auth NuGet package +... +var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file +var channel = new Channel("localhost:50051", credentials); + +string scope = "https://www.googleapis.com/auth/grpc-testing"; +var authorization = GoogleCredential.GetApplicationDefault(); +if (authorization.IsCreateScopedRequired) +{ + authorization = credential.CreateScoped(new[] { scope }); +} +var client = new Greeter.GreeterClient(channel, + new StubConfiguration(OAuth2InterceptorFactory.Create(credential))); +``` + +###Authenticating with Google (PHP) +```php +// Base case - No encryption/authorization +$client = new helloworld\GreeterClient( + new Grpc\BaseStub('localhost:50051', [])); +... + +// Authenticating with Google +// the environment variable "GOOGLE_APPLICATION_CREDENTIALS" needs to be set +$scope = "https://www.googleapis.com/auth/grpc-testing"; +$auth = Google\Auth\ApplicationDefaultCredentials::getCredentials($scope); +$opts = [ + 'credentials' => Grpc\Credentials::createSsl(file_get_contents('ca.pem')); + 'update_metadata' => $auth->getUpdateMetadataFunc(), +]; + +$client = new helloworld\GreeterClient( + new Grpc\BaseStub('localhost:50051', $opts)); + +``` + +###Authenticating with Google (Objective-C) + +This example uses the [Google iOS Sign-In library](https://developers.google.com/identity/sign-in/ios/), +but it's easily extrapolated to any other OAuth2 library. + +```objective-c +// Base case - No authentication +[client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { + ... +}]; + +... + +// Authenticating with Google + +// When signing the user in, ask her for the relevant scopes. +GIDSignIn.sharedInstance.scopes = @[@"https://www.googleapis.com/auth/grpc-testing"]; + +... + +#import + +// Create a not-yet-started RPC. We want to set the request headers on this object before starting +// it. +ProtoRPC *call = + [client RPCToSayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { + ... + }]; + +// Set the access token to be used. +NSString *accessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken; +call.requestMetadata[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken]}]; + +// Start the RPC. +[call start]; +``` + +You can see a working example app, with a more detailed explanation, [here](https://github.com/grpc/grpc-common/tree/master/objective-c/auth_sample). + +### Authenticating with Google (Python) +```python +# Base case - No encryption +stub = early_adopter_create_GreeterService_stub('localhost', 50051) +... + +# With server authentication SSL/TLS +import oauth2client.client +credentials = oauth2client.GoogleCredentials.get_application_default() +scope = 'https://www.googleapis.com/auth/grpc-testing' +scoped_credentials = credentials.create_scoped([scope]) +access_token = scoped_credentials.get_access_token().access_token +metadata_transformer = ( + lambda x: [('Authorization', 'Bearer {}'.format(access_token))]) + +stub = early_adopter_create_GreeterService_stub( + 'localhost', 50051, secure=True, root_certificates=open('ca.pem').read(), + metadata_transformer=metadata_transformer) +... +``` +n.b.: the beta API will look different diff --git a/grpc-common/java/android/.gitignore b/grpc-common/java/android/.gitignore new file mode 100644 index 0000000000..6345b76a48 --- /dev/null +++ b/grpc-common/java/android/.gitignore @@ -0,0 +1,21 @@ +.gradle +/local.properties +/gradle.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +.idea/ + +*.iml +*.apk +*.ap_ +*.dex +*.class +bin/ +gen/ +.gradle/ +/*/build/ +local.properties +proguard/ +*.log diff --git a/grpc-common/java/android/README.md b/grpc-common/java/android/README.md new file mode 100644 index 0000000000..9de65a0267 --- /dev/null +++ b/grpc-common/java/android/README.md @@ -0,0 +1,41 @@ +gRPC Hello World Tutorial (Android Java) +======================== + +BACKGROUND +------------- +For this sample, we've already generated the server and client stubs from [helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). + +PREREQUISITES +------------- +- [Java gRPC](https://github.com/grpc/grpc-java) + +- [Android Tutorial](https://developer.android.com/training/basics/firstapp/index.html) if you're new to Android development + +- We only have Android gRPC client in this example. Please follow examples in other languages to build and run a gRPC server. + +INSTALL +------- +**1 Clone the gRPC Java git repo** +```sh +$ git clone https://github.com/grpc/grpc-java +``` + +**2 Install gRPC Java, as described in [How to Build](https://github.com/grpc/grpc-java#how-to-build)** +```sh +$ # from this dir +$ cd grpc-java +$ # follow the instructions in 'How to Build' +``` + +**3 Prepare the app** +- Clone this git repo +```sh +$ git clone https://github.com/grpc/grpc-common + +``` + +**4 Install the app** +```sh +$ cd grpc-common/java/android +$ ./gradlew installDebug +``` diff --git a/grpc-common/java/android/app/.gitignore b/grpc-common/java/android/app/.gitignore new file mode 100644 index 0000000000..796b96d1c4 --- /dev/null +++ b/grpc-common/java/android/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/grpc-common/java/android/app/build.gradle b/grpc-common/java/android/app/build.gradle new file mode 100644 index 0000000000..aedf4fe92a --- /dev/null +++ b/grpc-common/java/android/app/build.gradle @@ -0,0 +1,34 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 21 + buildToolsVersion "21.1.2" + + defaultConfig { + applicationId "io.grpc.helloworldexample" + minSdkVersion 7 + targetSdkVersion 21 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile 'com.android.support:appcompat-v7:21.0.3' + compile 'com.google.code.findbugs:jsr305:3.0.0' + compile 'com.squareup.okhttp:okhttp:2.2.0' + compile 'com.google.guava:guava:18.0' + + // You need to build the https://github.com/grpc/grpc-java + // to obtain these libraries below. + compile 'io.grpc:grpc-core:0.1.0-SNAPSHOT' + compile 'io.grpc:grpc-protobuf-nano:0.1.0-SNAPSHOT' + compile 'io.grpc:grpc-okhttp:0.1.0-SNAPSHOT' + compile 'io.grpc:grpc-stub:0.1.0-SNAPSHOT' +} diff --git a/grpc-common/java/android/app/proguard-rules.pro b/grpc-common/java/android/app/proguard-rules.pro new file mode 100644 index 0000000000..3e659b91f3 --- /dev/null +++ b/grpc-common/java/android/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/thagikura/android-sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/grpc-common/java/android/app/src/main/AndroidManifest.xml b/grpc-common/java/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..8c40f11684 --- /dev/null +++ b/grpc-common/java/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + diff --git a/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/GreeterGrpc.java b/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/GreeterGrpc.java new file mode 100644 index 0000000000..817c9fde8f --- /dev/null +++ b/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/GreeterGrpc.java @@ -0,0 +1,179 @@ +package io.grpc.helloworldexample; + +import java.io.IOException; + +import static io.grpc.stub.Calls.asyncUnaryCall; +import static io.grpc.stub.Calls.blockingUnaryCall; +import static io.grpc.stub.Calls.createMethodDescriptor; +import static io.grpc.stub.Calls.unaryFutureCall; +import static io.grpc.stub.ServerCalls.asyncUnaryRequestCall; +import static io.grpc.stub.ServerCalls.createMethodDefinition; + +public class GreeterGrpc { + + private static final io.grpc.stub.Method METHOD_SAY_HELLO = + io.grpc.stub.Method.create( + io.grpc.MethodType.UNARY, "SayHello", + io.grpc.protobuf.nano.NanoUtils.marshaller( + new io.grpc.protobuf.nano.Parser() { + @Override + public Helloworld.HelloRequest parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return Helloworld.HelloRequest.parseFrom(input); + } + }), + io.grpc.protobuf.nano.NanoUtils.marshaller( + new io.grpc.protobuf.nano.Parser() { + @Override + public Helloworld.HelloReply parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return Helloworld.HelloReply.parseFrom(input); + } + })); + + public static GreeterStub newStub(io.grpc.Channel channel) { + return new GreeterStub(channel, CONFIG); + } + + public static GreeterBlockingStub newBlockingStub( + io.grpc.Channel channel) { + return new GreeterBlockingStub(channel, CONFIG); + } + + public static GreeterFutureStub newFutureStub( + io.grpc.Channel channel) { + return new GreeterFutureStub(channel, CONFIG); + } + + public static final GreeterServiceDescriptor CONFIG = + new GreeterServiceDescriptor(); + + public static class GreeterServiceDescriptor extends + io.grpc.stub.AbstractServiceDescriptor { + public final io.grpc.MethodDescriptor sayHello; + + private GreeterServiceDescriptor() { + sayHello = createMethodDescriptor( + "helloworld.Greeter", METHOD_SAY_HELLO); + } + + private GreeterServiceDescriptor( + java.util.Map> methodMap) { + sayHello = (io.grpc.MethodDescriptor) methodMap.get( + CONFIG.sayHello.getName()); + } + + @java.lang.Override + protected GreeterServiceDescriptor build( + java.util.Map> methodMap) { + return new GreeterServiceDescriptor(methodMap); + } + + @java.lang.Override + public com.google.common.collect.ImmutableList> methods() { + return com.google.common.collect.ImmutableList.>of( + sayHello); + } + } + + public static interface Greeter { + + public void sayHello(Helloworld.HelloRequest request, + io.grpc.stub.StreamObserver responseObserver); + } + + public static interface GreeterBlockingClient { + + public Helloworld.HelloReply sayHello(Helloworld.HelloRequest request); + } + + public static interface GreeterFutureClient { + + public com.google.common.util.concurrent.ListenableFuture sayHello( + Helloworld.HelloRequest request); + } + + public static class GreeterStub extends + io.grpc.stub.AbstractStub + implements Greeter { + private GreeterStub(io.grpc.Channel channel, + GreeterServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected GreeterStub build(io.grpc.Channel channel, + GreeterServiceDescriptor config) { + return new GreeterStub(channel, config); + } + + @java.lang.Override + public void sayHello(Helloworld.HelloRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + channel.newCall(config.sayHello), request, responseObserver); + } + } + + public static class GreeterBlockingStub extends + io.grpc.stub.AbstractStub + implements GreeterBlockingClient { + private GreeterBlockingStub(io.grpc.Channel channel, + GreeterServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected GreeterBlockingStub build(io.grpc.Channel channel, + GreeterServiceDescriptor config) { + return new GreeterBlockingStub(channel, config); + } + + @java.lang.Override + public Helloworld.HelloReply sayHello(Helloworld.HelloRequest request) { + return blockingUnaryCall( + channel.newCall(config.sayHello), request); + } + } + + public static class GreeterFutureStub extends + io.grpc.stub.AbstractStub + implements GreeterFutureClient { + private GreeterFutureStub(io.grpc.Channel channel, + GreeterServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected GreeterFutureStub build(io.grpc.Channel channel, + GreeterServiceDescriptor config) { + return new GreeterFutureStub(channel, config); + } + + @java.lang.Override + public com.google.common.util.concurrent.ListenableFuture sayHello( + Helloworld.HelloRequest request) { + return unaryFutureCall( + channel.newCall(config.sayHello), request); + } + } + + public static io.grpc.ServerServiceDefinition bindService( + final Greeter serviceImpl) { + return io.grpc.ServerServiceDefinition.builder("helloworld.Greeter") + .addMethod(createMethodDefinition( + METHOD_SAY_HELLO, + asyncUnaryRequestCall( + new io.grpc.stub.ServerCalls.UnaryRequestMethod< + Helloworld.HelloRequest, + Helloworld.HelloReply>() { + @java.lang.Override + public void invoke( + Helloworld.HelloRequest request, + io.grpc.stub.StreamObserver responseObserver) { + serviceImpl.sayHello(request, responseObserver); + } + }))).build(); + } +} diff --git a/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/Helloworld.java b/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/Helloworld.java new file mode 100644 index 0000000000..28da5a91d3 --- /dev/null +++ b/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/Helloworld.java @@ -0,0 +1,175 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +package io.grpc.helloworldexample; + +@SuppressWarnings("hiding") +public interface Helloworld { + + public static final class HelloRequest extends + com.google.protobuf.nano.MessageNano { + + private static volatile HelloRequest[] _emptyArray; + public static HelloRequest[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized ( + com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new HelloRequest[0]; + } + } + } + return _emptyArray; + } + + // optional string name = 1; + public java.lang.String name; + + public HelloRequest() { + clear(); + } + + public HelloRequest clear() { + name = ""; + cachedSize = -1; + return this; + } + + @Override + public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) + throws java.io.IOException { + if (!this.name.equals("")) { + output.writeString(1, this.name); + } + super.writeTo(output); + } + + @Override + protected int computeSerializedSize() { + int size = super.computeSerializedSize(); + if (!this.name.equals("")) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeStringSize(1, this.name); + } + return size; + } + + @Override + public HelloRequest mergeFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: { + if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { + return this; + } + break; + } + case 10: { + this.name = input.readString(); + break; + } + } + } + } + + public static HelloRequest parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new HelloRequest(), data); + } + + public static HelloRequest parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + return new HelloRequest().mergeFrom(input); + } + } + + public static final class HelloReply extends + com.google.protobuf.nano.MessageNano { + + private static volatile HelloReply[] _emptyArray; + public static HelloReply[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized ( + com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new HelloReply[0]; + } + } + } + return _emptyArray; + } + + // optional string message = 1; + public java.lang.String message; + + public HelloReply() { + clear(); + } + + public HelloReply clear() { + message = ""; + cachedSize = -1; + return this; + } + + @Override + public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) + throws java.io.IOException { + if (!this.message.equals("")) { + output.writeString(1, this.message); + } + super.writeTo(output); + } + + @Override + protected int computeSerializedSize() { + int size = super.computeSerializedSize(); + if (!this.message.equals("")) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeStringSize(1, this.message); + } + return size; + } + + @Override + public HelloReply mergeFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: { + if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { + return this; + } + break; + } + case 10: { + this.message = input.readString(); + break; + } + } + } + } + + public static HelloReply parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new HelloReply(), data); + } + + public static HelloReply parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + return new HelloReply().mergeFrom(input); + } + } +} \ No newline at end of file diff --git a/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java b/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java new file mode 100644 index 0000000000..b6d734f9a9 --- /dev/null +++ b/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java @@ -0,0 +1,90 @@ +package io.grpc.helloworldexample; + +import android.content.Context; +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.v7.app.ActionBarActivity; +import android.text.TextUtils; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; + +import java.util.concurrent.TimeUnit; + +import io.grpc.ChannelImpl; +import io.grpc.helloworldexample.Helloworld.HelloReply; +import io.grpc.helloworldexample.Helloworld.HelloRequest; +import io.grpc.transport.okhttp.OkHttpChannelBuilder; + +public class HelloworldActivity extends ActionBarActivity { + private Button mSendButton; + private EditText mHostEdit; + private EditText mPortEdit; + private EditText mMessageEdit; + private TextView mResultText; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_helloworld); + mSendButton = (Button) findViewById(R.id.send_button); + mHostEdit = (EditText) findViewById(R.id.host_edit_text); + mPortEdit = (EditText) findViewById(R.id.port_edit_text); + mMessageEdit = (EditText) findViewById(R.id.message_edit_text); + mResultText = (TextView) findViewById(R.id.grpc_response_text); + } + + public void sendMessage(View view) { + ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)) + .hideSoftInputFromWindow(mHostEdit.getWindowToken(), 0); + mSendButton.setEnabled(false); + new GrpcTask().execute(); + } + + private class GrpcTask extends AsyncTask { + private String mHost; + private String mMessage; + private int mPort; + private ChannelImpl mChannel; + + @Override + protected void onPreExecute() { + mHost = mHostEdit.getText().toString(); + mMessage = mMessageEdit.getText().toString(); + String portStr = mPortEdit.getText().toString(); + mPort = TextUtils.isEmpty(portStr) ? 0 : Integer.valueOf(portStr); + mResultText.setText(""); + } + + private String sayHello(ChannelImpl channel) { + GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel); + HelloRequest message = new HelloRequest(); + message.name = mMessage; + HelloReply reply = stub.sayHello(message); + return reply.message; + } + + @Override + protected String doInBackground(Void... nothing) { + try { + mChannel = OkHttpChannelBuilder.forAddress(mHost, mPort).build(); + return sayHello(mChannel); + } catch (Exception e) { + return "Failed... : " + e.getMessage(); + } + } + + @Override + protected void onPostExecute(String result) { + try { + mChannel.shutdown().awaitTerminated(1, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + mResultText.setText(result); + mSendButton.setEnabled(true); + } + } +} \ No newline at end of file diff --git a/grpc-common/java/android/app/src/main/res/layout/activity_helloworld.xml b/grpc-common/java/android/app/src/main/res/layout/activity_helloworld.xml new file mode 100644 index 0000000000..00ca04ce65 --- /dev/null +++ b/grpc-common/java/android/app/src/main/res/layout/activity_helloworld.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/grpc-common/objective-c/auth_sample/Misc/GoogleService-Info.plist b/grpc-common/objective-c/auth_sample/Misc/GoogleService-Info.plist new file mode 100644 index 0000000000..86909d84a3 --- /dev/null +++ b/grpc-common/objective-c/auth_sample/Misc/GoogleService-Info.plist @@ -0,0 +1,10 @@ + + + + + CLIENT_ID + 15087385131-lh9bpkiai9nls53uadju0if6k7un3uih.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.15087385131-lh9bpkiai9nls53uadju0if6k7un3uih + + \ No newline at end of file diff --git a/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json b/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..36d2c80d88 --- /dev/null +++ b/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json b/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json new file mode 100644 index 0000000000..33a745102c --- /dev/null +++ b/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "first.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf b/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf new file mode 100644 index 0000000000..47d911dea6 Binary files /dev/null and b/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf differ diff --git a/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json b/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json new file mode 100644 index 0000000000..03bd9c927f --- /dev/null +++ b/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "second.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf b/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf new file mode 100644 index 0000000000..401614e288 Binary files /dev/null and b/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf differ diff --git a/grpc-common/objective-c/auth_sample/Misc/Info.plist b/grpc-common/objective-c/auth_sample/Misc/Info.plist new file mode 100644 index 0000000000..fc292507c7 --- /dev/null +++ b/grpc-common/objective-c/auth_sample/Misc/Info.plist @@ -0,0 +1,80 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + io.grpc.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + REVERSED_CLIENT_ID + CFBundleURLSchemes + + com.googleusercontent.apps.15087385131-lh9bpkiai9nls53uadju0if6k7un3uih + + + + CFBundleTypeRole + Editor + CFBundleURLName + BUNDLE_ID + CFBundleURLSchemes + + io.grpc.AuthSample + + + + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + Main + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarTintParameters + + UINavigationBar + + Style + UIBarStyleDefault + Translucent + + + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/grpc-common/objective-c/auth_sample/Misc/main.m b/grpc-common/objective-c/auth_sample/Misc/main.m new file mode 100644 index 0000000000..81e9d44e54 --- /dev/null +++ b/grpc-common/objective-c/auth_sample/Misc/main.m @@ -0,0 +1,41 @@ +/* + * + * 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. + * + */ + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/grpc-common/objective-c/auth_sample/Podfile b/grpc-common/objective-c/auth_sample/Podfile new file mode 100644 index 0000000000..dd4fd558c0 --- /dev/null +++ b/grpc-common/objective-c/auth_sample/Podfile @@ -0,0 +1,10 @@ +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '8.0' + +target 'AuthSample' do + # Depend on the generated AuthTestService library. + pod 'AuthTestService', :path => '.' + + # Depend on Google's OAuth2 library + pod 'Google/SignIn' +end diff --git a/grpc-common/objective-c/auth_sample/README.md b/grpc-common/objective-c/auth_sample/README.md new file mode 100644 index 0000000000..4ca4982f53 --- /dev/null +++ b/grpc-common/objective-c/auth_sample/README.md @@ -0,0 +1,189 @@ +#OAuth2 on gRPC: Objective-C + +This example application demostrates how to use OAuth2 on gRPC to make authenticated API calls on +behalf of a user. By walking through it you'll learn how to use the Objective-C gRPC API to: + +- Initialize and configure a remote call object before the RPC is started. +- Set request metadata elements on a call, which are semantically equivalent to HTTP request +headers. +- Read response metadata from a call, which is equivalent to HTTP response headers and trailers. + +It assumes you know the basics on how to make gRPC API calls using the Objective-C client library, +as shown in the [Hello World](https://github.com/grpc/grpc-common/tree/master/objective-c/helloworld) +or [Route Guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide) tutorials, +and are familiar with OAuth2 concepts like _access token_. + +- [Example code and setup](#setup) +- [Try it out!](#try) +- [Create an RPC object and start it later](#rpc-object) +- [Set request metadata of a call: Authorization header with an access token](#request-metadata) +- [Get response metadata of a call: Auth challenge header](#response-metadata) + + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/objective-c/auth_sample](https://github.com/grpc/grpc-common/tree/master/objective-c/auth_sample). +To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/objective-c/auth_sample`: +```shell +$ cd grpc-common/objective-c/auth_sample +``` + +Our example is a simple application with two views. The first one lets a user sign in and out using +the OAuth2 flow of Google's [iOS SignIn library](https://developers.google.com/identity/sign-in/ios/). +(Google's library is used in this example because the test gRPC service we are going to call expects +Google account credentials, but neither gRPC nor the Objective-C client library is tied to any +specific OAuth2 provider). The second view makes a gRPC request to the test server, using the +access token obtained by the first view. + +Note: OAuth2 libraries need the application to register and obtain an ID from the identity provider +(in the case of this example app, Google). The app's XCode project is configured using that ID, so +you shouldn't copy this project "as is" for your own app: it would result in your app being +identified in the consent screen as "gRPC-AuthSample", and not having access to real Google +services. Instead, configure your own XCode project following the [instructions here](https://developers.google.com/identity/sign-in/ios/). + +As with the other examples, you also should have [Cocoapods](https://cocoapods.org/#install) +installed, as well as the relevant tools to generate the client library code. You can obtain the +latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). + + + +## Try it out! + +To try the sample app, first have Cocoapods generate and install the client library for our .proto +files: + +```shell +$ pod install +``` + +(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet +on your computer's cache). + +Finally, open the XCode workspace created by Cocoapods, and run the app. + +The first view, `SelectUserViewController.h/m`, asks you to sign in with your Google account, and to +give the "gRPC-AuthSample" app the following permissions: + +- View your email address. +- View your basic profile info. +- "Test scope for access to the Zoo service". + +This last permission, corresponding to the scope `https://www.googleapis.com/auth/xapi.zoo` doesn't +grant any real capability: it's only used for testing. You can log out at any time. + +The second view, `MakeRPCViewController.h/m`, makes a gRPC request to a test server at +https://grpc-test.sandbox.google.com, sending the access token along with the request. The test +service simply validates the token and writes in its response which user it belongs to, and which +scopes it gives access to. (The client application already knows those two values; it's a way to +verify that everything went as expected). + +The next sections guide you step-by-step through how the gRPC call in `MakeRPCViewController` is +performed. + + +## Create an RPC object and start it later + +The other basic tutorials show how to invoke an RPC by calling an asynchronous method in a generated +client object. This shows how to initialize an object that represents the RPC, and configure it +before starting the network request. + +Assume you have a proto service definition like this: + +```protobuf +option objc_class_prefix = "AUTH"; + +service TestService { + rpc UnaryCall(Request) returns (Response); +} +``` + +A `unaryCallWithRequest:handler:` method, with which you're already familiar, is generated for the +`AUTHTestService` class: + +```objective-c +[client unaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { + ... +}]; +``` + +In addition, an `RPCToUnaryCallWithRequest:handler:` method is generated, which returns a +not-yet-started RPC object: + +```objective-c +#import + +ProtoRPC *call = + [client RPCToUnaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { + ... + }]; +``` + +The RPC represented by this object can be started at any later time like this: + +```objective-c +[call start]; +``` + + +## Set request metadata of a call: Authorization header with an access token + +The `ProtoRPC` class has a `requestMetadata` property (inherited from `GRPCCall`) defined like this: + +```objective-c +- (NSMutableDictionary *)requestMetadata; // nonatomic +- (void)setRequestMetadata:(NSDictionary *)requestMetadata; // nonatomic, copy +``` + +Setting it to a dictionary of metadata keys and values will have them sent on the wire when the call +is started. gRPC metadata are pieces of information about the call sent by the client to the server +(and vice versa). They take the form of key-value pairs and are essentially opaque to gRPC itself. + +```objective-c +call.requestMetadata = @{@"My-Header": @"Value for this header", + @"Another-Header": @"Its value"}; +``` + +For convenience, the property is initialized with an empty `NSMutableDictionary`, so that request +metadata elements can be set like this: + +```objective-c +call.requestMetadata[@"My-Header"] = @"Value for this header"; +``` + +If you have an access token, OAuth2 specifies it is to be sent in this format: + +```objective-c +call.requestMetadata[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken]; +``` + + +## Get response metadata of a call: Auth challenge header + +The `ProtoRPC` class also inherits a `responseMetadata` property, analogous to the request metadata +we just looked at. It's defined like this: + +```objective-c +@property(atomic, readonly) NSDictionary *responseMetadata; +``` + +To access OAuth2's authentication challenge header you write: + +```objective-c +call.responseMetadata[@"www-authenticate"] +``` + +Note that, as gRPC metadata elements are mapped to HTTP/2 headers (or trailers), the keys of the +response metadata are always ASCII strings in lowercase. + +Many uses cases of response metadata are getting more details about an RPC error. For convenience, +when a `NSError` instance is passed to an RPC handler block, the response metadata dictionary can +also be accessed this way: + +```objective-c +error.userInfo[kGRPCStatusMetadataKey] +``` diff --git a/grpc-common/objective-c/auth_sample/SelectUserViewController.h b/grpc-common/objective-c/auth_sample/SelectUserViewController.h new file mode 100644 index 0000000000..eb3c2cf5f0 --- /dev/null +++ b/grpc-common/objective-c/auth_sample/SelectUserViewController.h @@ -0,0 +1,42 @@ +/* + * + * 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. + * + */ + +#import +#import + +@interface SelectUserViewController : UIViewController +@property(weak, nonatomic) IBOutlet GIDSignInButton *signInButton; +@property(weak, nonatomic) IBOutlet UIButton *signOutButton; +@property(weak, nonatomic) IBOutlet UILabel *mainLabel; +@property(weak, nonatomic) IBOutlet UILabel *subLabel; +@end diff --git a/grpc-common/objective-c/auth_sample/SelectUserViewController.m b/grpc-common/objective-c/auth_sample/SelectUserViewController.m new file mode 100644 index 0000000000..954c531f3f --- /dev/null +++ b/grpc-common/objective-c/auth_sample/SelectUserViewController.m @@ -0,0 +1,86 @@ +/* + * + * 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. + * + */ + +#import "SelectUserViewController.h" + +#import "MakeRPCViewController.h" + +@implementation SelectUserViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.signOutButton.layer.cornerRadius = 5; + self.signOutButton.hidden = YES; + + // As instructed in https://developers.google.com/identity/sign-in/ios/sign-in + GIDSignIn *signIn = GIDSignIn.sharedInstance; + signIn.delegate = self; + signIn.uiDelegate = self; + + // As instructed in https://developers.google.com/identity/sign-in/ios/additional-scopes + if (![signIn.scopes containsObject:kTestScope]) { + signIn.scopes = [signIn.scopes arrayByAddingObject:kTestScope]; + } + + [signIn signInSilently]; +} + +- (void)signIn:(GIDSignIn *)signIn +didSignInForUser:(GIDGoogleUser *)user + withError:(NSError *)error { + if (error) { + // The user probably cancelled the sign-in flow. + return; + } + + self.mainLabel.text = [NSString stringWithFormat:@"User: %@", user.profile.email]; + NSString *scopes = [user.accessibleScopes componentsJoinedByString:@", "]; + scopes = scopes.length ? scopes : @"(none)"; + self.subLabel.text = [NSString stringWithFormat:@"Scopes: %@", scopes]; + + self.signInButton.hidden = YES; + self.signOutButton.hidden = NO; +} + +- (IBAction)didTapSignOut { + [GIDSignIn.sharedInstance signOut]; + + self.mainLabel.text = @"Please sign in."; + self.subLabel.text = @""; + + self.signInButton.hidden = NO; + self.signOutButton.hidden = YES; +} + +@end diff --git a/grpc-common/objective-c/helloworld/HelloWorld.podspec b/grpc-common/objective-c/helloworld/HelloWorld.podspec new file mode 100644 index 0000000000..ae009a688c --- /dev/null +++ b/grpc-common/objective-c/helloworld/HelloWorld.podspec @@ -0,0 +1,35 @@ +Pod::Spec.new do |s| + s.name = "HelloWorld" + s.version = "0.0.1" + s.license = "New BSD" + + s.ios.deployment_target = "6.0" + s.osx.deployment_target = "10.8" + + # Base directory where the .proto files are. + src = "../../protos" + + # Directory where the generated files will be place. + dir = "Pods/" + s.name + + # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. + s.prepare_command = <<-CMD + mkdir -p #{dir} + protoc -I #{src} --objc_out=#{dir} --objcgrpc_out=#{dir} #{src}/helloworld.proto + CMD + + s.subspec "Messages" do |ms| + ms.source_files = "#{dir}/*.pbobjc.{h,m}", "#{dir}/**/*.pbobjc.{h,m}" + ms.header_mappings_dir = dir + ms.requires_arc = false + ms.dependency "Protobuf", "~> 3.0.0-alpha-3" + end + + s.subspec "Services" do |ss| + ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}" + ss.header_mappings_dir = dir + ss.requires_arc = true + ss.dependency "gRPC", "~> 0.6" + ss.dependency "#{s.name}/Messages" + end +end diff --git a/grpc-common/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj b/grpc-common/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..702ad3ff8b --- /dev/null +++ b/grpc-common/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj @@ -0,0 +1,349 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 5E3690661B2A23800040F884 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3690651B2A23800040F884 /* main.m */; }; + 5E3690691B2A23800040F884 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3690681B2A23800040F884 /* AppDelegate.m */; }; + 5E36906C1B2A23800040F884 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E36906B1B2A23800040F884 /* ViewController.m */; }; + 5E36906F1B2A23800040F884 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E36906D1B2A23800040F884 /* Main.storyboard */; }; + 5E3690711B2A23800040F884 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5E3690701B2A23800040F884 /* Images.xcassets */; }; + EF61CF6AE2536A31D47F0E63 /* libPods-HelloWorld.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B4E1F55F8A2EC95A0E7EE88 /* libPods-HelloWorld.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.release.xcconfig"; path = "Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld.release.xcconfig"; sourceTree = ""; }; + 5E3690601B2A23800040F884 /* HelloWorld.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorld.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E3690641B2A23800040F884 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5E3690651B2A23800040F884 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 5E3690671B2A23800040F884 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 5E3690681B2A23800040F884 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5E36906B1B2A23800040F884 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 5E36906E1B2A23800040F884 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5E3690701B2A23800040F884 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6B4E1F55F8A2EC95A0E7EE88 /* libPods-HelloWorld.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HelloWorld.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.debug.xcconfig"; path = "Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5E36905D1B2A23800040F884 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EF61CF6AE2536A31D47F0E63 /* libPods-HelloWorld.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 5E3690571B2A23800040F884 = { + isa = PBXGroup; + children = ( + 5E3690651B2A23800040F884 /* main.m */, + 5E3690621B2A23800040F884 /* HelloWorld */, + 5E3690611B2A23800040F884 /* Products */, + BD9CE6458E7C4FF49A1DF69F /* Pods */, + 66CEC7120220DDD2221DD075 /* Frameworks */, + ); + sourceTree = ""; + }; + 5E3690611B2A23800040F884 /* Products */ = { + isa = PBXGroup; + children = ( + 5E3690601B2A23800040F884 /* HelloWorld.app */, + ); + name = Products; + sourceTree = ""; + }; + 5E3690621B2A23800040F884 /* HelloWorld */ = { + isa = PBXGroup; + children = ( + 5E3690631B2A23800040F884 /* Supporting Files */, + ); + path = HelloWorld; + sourceTree = ""; + }; + 5E3690631B2A23800040F884 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 5E3690701B2A23800040F884 /* Images.xcassets */, + 5E36906D1B2A23800040F884 /* Main.storyboard */, + 5E36906B1B2A23800040F884 /* ViewController.m */, + 5E3690681B2A23800040F884 /* AppDelegate.m */, + 5E3690671B2A23800040F884 /* AppDelegate.h */, + 5E3690641B2A23800040F884 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 66CEC7120220DDD2221DD075 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 6B4E1F55F8A2EC95A0E7EE88 /* libPods-HelloWorld.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + BD9CE6458E7C4FF49A1DF69F /* Pods */ = { + isa = PBXGroup; + children = ( + DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */, + 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5E36905F1B2A23800040F884 /* HelloWorld */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5E3690831B2A23810040F884 /* Build configuration list for PBXNativeTarget "HelloWorld" */; + buildPhases = ( + ACF9162361FB8F24C70657DE /* Check Pods Manifest.lock */, + 5E36905C1B2A23800040F884 /* Sources */, + 5E36905D1B2A23800040F884 /* Frameworks */, + 5E36905E1B2A23800040F884 /* Resources */, + 4C7D815378D98AB3BFC1A7D5 /* Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = HelloWorld; + productName = HelloWorld; + productReference = 5E3690601B2A23800040F884 /* HelloWorld.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5E3690581B2A23800040F884 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0620; + ORGANIZATIONNAME = Google; + TargetAttributes = { + 5E36905F1B2A23800040F884 = { + CreatedOnToolsVersion = 6.2; + }; + }; + }; + buildConfigurationList = 5E36905B1B2A23800040F884 /* Build configuration list for PBXProject "HelloWorld" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5E3690571B2A23800040F884; + productRefGroup = 5E3690611B2A23800040F884 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5E36905F1B2A23800040F884 /* HelloWorld */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5E36905E1B2A23800040F884 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E36906F1B2A23800040F884 /* Main.storyboard in Resources */, + 5E3690711B2A23800040F884 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 4C7D815378D98AB3BFC1A7D5 /* Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + ACF9162361FB8F24C70657DE /* Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5E36905C1B2A23800040F884 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E36906C1B2A23800040F884 /* ViewController.m in Sources */, + 5E3690691B2A23800040F884 /* AppDelegate.m in Sources */, + 5E3690661B2A23800040F884 /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 5E36906D1B2A23800040F884 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5E36906E1B2A23800040F884 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 5E3690811B2A23810040F884 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.2; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5E3690821B2A23810040F884 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.2; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5E3690841B2A23810040F884 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = HelloWorld/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 5E3690851B2A23810040F884 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = HelloWorld/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5E36905B1B2A23800040F884 /* Build configuration list for PBXProject "HelloWorld" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E3690811B2A23810040F884 /* Debug */, + 5E3690821B2A23810040F884 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5E3690831B2A23810040F884 /* Build configuration list for PBXNativeTarget "HelloWorld" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E3690841B2A23810040F884 /* Debug */, + 5E3690851B2A23810040F884 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5E3690581B2A23800040F884 /* Project object */; +} diff --git a/grpc-common/objective-c/helloworld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/grpc-common/objective-c/helloworld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..174a04ecb8 --- /dev/null +++ b/grpc-common/objective-c/helloworld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/grpc-common/objective-c/helloworld/HelloWorld/AppDelegate.h b/grpc-common/objective-c/helloworld/HelloWorld/AppDelegate.h new file mode 100644 index 0000000000..102e7f3ade --- /dev/null +++ b/grpc-common/objective-c/helloworld/HelloWorld/AppDelegate.h @@ -0,0 +1,38 @@ +/* + * + * 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. + * + */ + +#import + +@interface AppDelegate : UIResponder +@property (strong, nonatomic) UIWindow *window; +@end diff --git a/grpc-common/objective-c/helloworld/HelloWorld/AppDelegate.m b/grpc-common/objective-c/helloworld/HelloWorld/AppDelegate.m new file mode 100644 index 0000000000..a38e36651e --- /dev/null +++ b/grpc-common/objective-c/helloworld/HelloWorld/AppDelegate.m @@ -0,0 +1,37 @@ +/* + * + * 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. + * + */ + +#import "AppDelegate.h" + +@implementation AppDelegate +@end diff --git a/grpc-common/objective-c/helloworld/HelloWorld/Base.lproj/Main.storyboard b/grpc-common/objective-c/helloworld/HelloWorld/Base.lproj/Main.storyboard new file mode 100644 index 0000000000..f56d2f3bb5 --- /dev/null +++ b/grpc-common/objective-c/helloworld/HelloWorld/Base.lproj/Main.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/grpc-common/objective-c/helloworld/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json b/grpc-common/objective-c/helloworld/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..36d2c80d88 --- /dev/null +++ b/grpc-common/objective-c/helloworld/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/grpc-common/objective-c/helloworld/HelloWorld/Info.plist b/grpc-common/objective-c/helloworld/HelloWorld/Info.plist new file mode 100644 index 0000000000..1078fff723 --- /dev/null +++ b/grpc-common/objective-c/helloworld/HelloWorld/Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + Google.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + Main + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/grpc-common/objective-c/helloworld/HelloWorld/ViewController.m b/grpc-common/objective-c/helloworld/HelloWorld/ViewController.m new file mode 100644 index 0000000000..090fd93689 --- /dev/null +++ b/grpc-common/objective-c/helloworld/HelloWorld/ViewController.m @@ -0,0 +1,40 @@ +/* + * + * 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. + * + */ + +#import + +@interface ViewController : UIViewController +@end + +@implementation ViewController +@end diff --git a/grpc-common/objective-c/helloworld/Podfile b/grpc-common/objective-c/helloworld/Podfile new file mode 100644 index 0000000000..2934ebc2c8 --- /dev/null +++ b/grpc-common/objective-c/helloworld/Podfile @@ -0,0 +1,7 @@ +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '8.0' + +target 'HelloWorld' do + # Depend on the generated HelloWorld library. + pod 'HelloWorld', :path => '.' +end diff --git a/grpc-common/objective-c/helloworld/README.md b/grpc-common/objective-c/helloworld/README.md new file mode 100644 index 0000000000..685339e84a --- /dev/null +++ b/grpc-common/objective-c/helloworld/README.md @@ -0,0 +1,56 @@ +#gRPC in 3 minutes (Objective-C) + +## Installation + +To run this example you should have [Cocoapods](https://cocoapods.org/#install) installed, as well +as the relevant tools to generate the client library code (and a server in another language, for +testing). You can obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). + +## Hello Objective-C gRPC! + +Here's how to build and run the Objective-C implementation of the [Hello World](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto) +example used in [Getting started](https://github.com/grpc/grpc-common). + +The example code for this and our other examples lives in the `grpc-common` GitHub repository. Clone +this repository to your local machine by running the following command: + + +```sh +$ git clone https://github.com/grpc/grpc-common.git +``` + +Change your current directory to `grpc-common/objective-c/helloworld` + +```sh +$ cd grpc-common/objective-c/helloworld +``` + +### Try it! +To try the sample app, we need a gRPC server running locally. Let's compile and run, for example, +the C++ server in this repository: + +```shell +$ pushd ../../cpp/helloworld +$ make +$ ./greeter_server & +$ popd +``` + +Now have Cocoapods generate and install the client library for our .proto files: + +```shell +$ pod install +``` + +(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet +on your computer's cache.) + +Finally, open the XCode workspace created by Cocoapods, and run the app. You can check the calling +code in `main.m` and see the results in XCode's log console. + +The code sends a `HLWHelloRequest` containing the string "Objective-C" to a local server. The server +responds with a `HLWHelloResponse`, which contains a string that is then output to the log. + +## Tutorial + +You can find a more detailed tutorial in [gRPC Basics: Objective-C](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/README.md). diff --git a/grpc-common/objective-c/helloworld/main.m b/grpc-common/objective-c/helloworld/main.m new file mode 100644 index 0000000000..458580be30 --- /dev/null +++ b/grpc-common/objective-c/helloworld/main.m @@ -0,0 +1,51 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import +#import "AppDelegate.h" + +#import + +static NSString * const kHostAddress = @"http://localhost:50051"; + +int main(int argc, char * argv[]) { + @autoreleasepool { + HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress]; + HLWHelloRequest *request = [HLWHelloRequest message]; + request.name = @"Objective-C"; + [client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { + NSLog(@"%@", response.message); + }]; + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/grpc-common/objective-c/route_guide/Misc/AppDelegate.h b/grpc-common/objective-c/route_guide/Misc/AppDelegate.h new file mode 100644 index 0000000000..102e7f3ade --- /dev/null +++ b/grpc-common/objective-c/route_guide/Misc/AppDelegate.h @@ -0,0 +1,38 @@ +/* + * + * 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. + * + */ + +#import + +@interface AppDelegate : UIResponder +@property (strong, nonatomic) UIWindow *window; +@end diff --git a/grpc-common/objective-c/route_guide/Misc/AppDelegate.m b/grpc-common/objective-c/route_guide/Misc/AppDelegate.m new file mode 100644 index 0000000000..a38e36651e --- /dev/null +++ b/grpc-common/objective-c/route_guide/Misc/AppDelegate.m @@ -0,0 +1,37 @@ +/* + * + * 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. + * + */ + +#import "AppDelegate.h" + +@implementation AppDelegate +@end diff --git a/grpc-common/objective-c/route_guide/Misc/Base.lproj/Main.storyboard b/grpc-common/objective-c/route_guide/Misc/Base.lproj/Main.storyboard new file mode 100644 index 0000000000..9bf9498d62 --- /dev/null +++ b/grpc-common/objective-c/route_guide/Misc/Base.lproj/Main.storyboard @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/grpc-common/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json b/grpc-common/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..36d2c80d88 --- /dev/null +++ b/grpc-common/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/grpc-common/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json b/grpc-common/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json new file mode 100644 index 0000000000..33a745102c --- /dev/null +++ b/grpc-common/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "first.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/grpc-common/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf b/grpc-common/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf new file mode 100644 index 0000000000..47d911dea6 Binary files /dev/null and b/grpc-common/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf differ diff --git a/grpc-common/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json b/grpc-common/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json new file mode 100644 index 0000000000..03bd9c927f --- /dev/null +++ b/grpc-common/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "second.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/grpc-common/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf b/grpc-common/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf new file mode 100644 index 0000000000..401614e288 Binary files /dev/null and b/grpc-common/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf differ diff --git a/grpc-common/objective-c/route_guide/Misc/Info.plist b/grpc-common/objective-c/route_guide/Misc/Info.plist new file mode 100644 index 0000000000..33ad4800f6 --- /dev/null +++ b/grpc-common/objective-c/route_guide/Misc/Info.plist @@ -0,0 +1,57 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + gRPC.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + Main + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarTintParameters + + UINavigationBar + + Style + UIBarStyleDefault + Translucent + + + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/grpc-common/objective-c/route_guide/Misc/main.m b/grpc-common/objective-c/route_guide/Misc/main.m new file mode 100644 index 0000000000..fb701005d1 --- /dev/null +++ b/grpc-common/objective-c/route_guide/Misc/main.m @@ -0,0 +1,41 @@ +/* + * + * 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. + * + */ + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/grpc-common/objective-c/route_guide/Podfile b/grpc-common/objective-c/route_guide/Podfile new file mode 100644 index 0000000000..a97f414685 --- /dev/null +++ b/grpc-common/objective-c/route_guide/Podfile @@ -0,0 +1,7 @@ +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '8.0' + +target 'RouteGuideClient' do + # Depend on the generated RouteGuide library. + pod 'RouteGuide', :path => '.' +end diff --git a/grpc-common/objective-c/route_guide/README.md b/grpc-common/objective-c/route_guide/README.md new file mode 100644 index 0000000000..bbbd9e020d --- /dev/null +++ b/grpc-common/objective-c/route_guide/README.md @@ -0,0 +1,360 @@ +#gRPC Basics: Objective-C + +This tutorial provides a basic Objective-C programmer's introduction to working with gRPC. By +walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate client code using the protocol buffer compiler. +- Use the Objective-C gRPC API to write a simple client for your service. + +It assumes a passing familiarity with [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). +Note that the example in this tutorial uses the proto3 version of the protocol buffers language, +which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) +and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the +protocol buffers Github repository. + +This isn't a comprehensive guide to using gRPC in Objective-C: more reference documentation is +coming soon. + +- [Why use gRPC?](#why-grpc) +- [Example code and setup](#setup) +- [Try it out!](#try) +- [Defining the service](#proto) +- [Generating client code](#protoc) +- [Creating the client](#client) + + +## Why use gRPC? + +With gRPC you can define your service once in a .proto file and implement clients and servers in any +of gRPC's supported languages, which in turn can be run in environments ranging from servers inside +Google to your own tablet - all the complexity of communication between different languages and +environments is handled for you by gRPC. You also get all the advantages of working with protocol +buffers, including efficient serialization, a simple IDL, and easy interface updating. + +gRPC and proto3 are specially suited for mobile clients: gRPC is implemented on top of HTTP/2, which +results in network bandwidth savings over using HTTP/1.1. Serialization and parsing of the proto +binary format is more efficient than the equivalent JSON, resulting in CPU and battery savings. And +proto3 uses a runtime that has been optimized over the years at Google to keep code size to a +minimum. The latter is important in Objective-C, because the ability of the compiler to strip unused +code is limited by the dynamic nature of the language. + + + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/objective-c/route_guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide). +To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/objective-c/route_guide`: +```shell +$ cd grpc-common/objective-c/route_guide +``` + +Our example is a simple route mapping application that lets clients get information about features +on their route, create a summary of their route, and exchange route information such as traffic +updates with the server and other clients. + +You also should have [Cocoapods](https://cocoapods.org/#install) installed, as well as the relevant +tools to generate the client library code (and a server in another language, for testing). You can +obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). + + + +## Try it out! + +To try the sample app, we need a gRPC server running locally. Let's compile and run, for example, +the C++ server in this repository: + +```shell +$ pushd ../../cpp/route_guide +$ make +$ ./route_guide_server & +$ popd +``` + +Now have Cocoapods generate and install the client library for our .proto files: + +```shell +$ pod install +``` + +(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet +on your computer's cache). + +Finally, open the XCode workspace created by Cocoapods, and run the app. You can check the calling +code in `ViewControllers.m` and see the results in XCode's log console. + +The next sections guide you step-by-step through how this proto service is defined, how to generate +a client library from it, and how to create an app that uses that library. + + + +## Defining the service + +First let's look at how the service we're using is defined. A gRPC *service* and its method +*request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). +You can see the complete .proto file for our example in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +```protobuf +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response +types. Protocol buffers let you define four kinds of service method, all of which are used in the +`RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server and receives a response later, just +like a normal remote procedure call. +```protobuf + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *response-streaming RPC* where the client sends a request to the server and gets back a stream +of response messages. You specify a response-streaming method by placing the `stream` keyword before +the *response* type. +```protobuf + // 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 *request-streaming RPC* where the client sends a sequence of messages to the server. Once the +client has finished writing the messages, it waits for the server to read them all and return its +response. You specify a request-streaming method by placing the `stream` keyword before the +*request* type. +```protobuf + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages to the other. The two +streams operate independently, so clients and servers can read and write in whatever order they +like: for example, the server could wait to receive all the client messages before writing its +responses, or it could alternately read a message then write a message, or some other combination of +reads and writes. The order of messages in each stream is preserved. You specify this type of method +by placing the `stream` keyword before both the request and the response. +```protobuf + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and +response types used in our service methods - for example, here's the `Point` message type: +```protobuf +// 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; +} +``` + +You can specify a prefix to be used for your generated classes by adding the `objc_class_prefix` +option at the top of the file. For example: +```protobuf +option objc_class_prefix = "RTG"; +``` + + + +## Generating client code + +Next we need to generate the gRPC client interfaces from our .proto service definition. We do this +using the protocol buffer compiler (`protoc`) with a special gRPC Objective-C plugin. + +For simplicity, we've provided a [Podspec file](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/RouteGuide.podspec) +that runs `protoc` for you with the appropriate plugin, input, and output, and describes how to +compile the generated files. You just need to run in this directory (`grpc-common/objective-c/route_guide`): + +```shell +$ pod install +``` + +which, before installing the generated library in the XCode project of this sample, runs: + +```shell +$ protoc -I ../../protos --objc_out=Pods/RouteGuide --objcgrpc_out=Pods/RouteGuide ../../protos/route_guide.proto +``` + +Running this command generates the following files under `Pods/RouteGuide/`: +- `RouteGuide.pbobjc.h`, the header which declares your generated message classes. +- `RouteGuide.pbobjc.m`, which contains the implementation of your message classes. +- `RouteGuide.pbrpc.h`, the header which declares your generated service classes. +- `RouteGuide.pbrpc.m`, which contains the implementation of your service classes. + +These contain: +- All the protocol buffer code to populate, serialize, and retrieve our request and response message +types. +- A class called `RTGRouteGuide` that lets clients call the methods defined in the `RouteGuide` +service. + +You can also use the provided Podspec file to generate client code from any other proto service +definition; just replace the name (matching the file name), version, and other metadata. + + + +## Creating the client + +In this section, we'll look at creating an Objective-C client for our `RouteGuide` service. You can +see our complete example client code in [grpc-common/objective-c/route_guide/ViewControllers.m](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/ViewControllers.m). +(Note: In your apps, for maintainability and readability reasons, you shouldn't put all of your view +controllers in a single file; it's done here only to simplify the learning process). + +### Constructing a client object + +To call service methods, we first need to create a client object, an instance of the generated +`RTGRouteGuide` class. The designated initializer of the class expects a `NSString *` with the +server address and port we want to connect to: + +```objective-c +#import + +static NSString * const kHostAddress = @"http://localhost:50051"; + +... + +RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; +``` + +Notice that we've specified the HTTP scheme in the host address. This is because the server we will +be using to test our client doesn't use [TLS](http://en.wikipedia.org/wiki/Transport_Layer_Security). +This is fine because it will be running locally on our development machine. The most common case, +though, is connecting with a gRPC server on the internet, running gRPC over TLS. For that case, the +HTTPS scheme can be specified (or no scheme at all, as HTTPS is the default value). The default +value of the port is that of the scheme selected: 443 for HTTPS and 80 for HTTP. + + +### Calling service methods + +Now let's look at how we call our service methods. As you will see, all these methods are +asynchronous, so you can call them from the main thread of your app without worrying about freezing +your UI or the OS killing your app. + +#### Simple RPC + +Calling the simple RPC `GetFeature` is nearly as straightforward as calling any other asynchronous +method on Cocoa. + +```objective-c +RTGPoint *point = [RTGPoint message]; +point.latitude = 40E7; +point.longitude = -74E7; + +[client getFeatureWithRequest:point handler:^(RTGFeature *response, NSError *error) { + if (response) { + // Successful response received + } else { + // RPC error + } +}]; +``` + +As you can see, we create and populate a request protocol buffer object (in our case `RTGPoint`). +Then, we call the method on the client object, passing it the request, and a block to handle the +response (or any RPC error). If the RPC finishes successfully, the handler block is called with a +`nil` error argument, and we can read the response information from the server from the response +argument. If, instead, some RPC error happens, the handler block is called with a `nil` response +argument, and we can read the details of the problem from the error argument. + +```objective-c +NSLog(@"Found feature called %@ at %@.", response.name, response.location); +``` + +#### Streaming RPCs + +Now let's look at our streaming methods. Here's where we call the response-streaming method +`ListFeatures`, which results in our client receiving a stream of geographical `RTGFeature`s: + +```objective-c +[client listFeaturesWithRequest:rectangle + eventHandler:^(BOOL done, RTGFeature *response, NSError *error) { + if (response) { + // Element of the stream of responses received + } else if (error) { + // RPC error; the stream is over. + } + if (done) { + // The stream is over (all the responses were received, or an error occured). Do any cleanup. + } +}]; +``` + +Notice how the signature of the `eventHandler` block now includes a `BOOL done` parameter. The +`eventHandler` block can be called any number of times; only on the last call is the `done` argument +value set to `YES`. If an error occurs, the RPC finishes and the block is called with the arguments +`(YES, nil, error)`. + +The request-streaming method `RecordRoute` expects a stream of `RTGPoint`s from the cient. This +stream is passed to the method as an object of class `GRXWriter`. The simplest way to create one is +to initialize one from a `NSArray` object: + + +```objective-c +#import + +... + +RTGPoint *point1 = [RTGPoint message]; +point.latitude = 40E7; +point.longitude = -74E7; + +RTGPoint *point2 = [RTGPoint message]; +point.latitude = 40E7; +point.longitude = -74E7; + +GRXWriter *locationsWriter = [GRXWriter writerWithContainer:@[point1, point2]]; + +[client recordRouteWithRequestsWriter:locationsWriter + handler:^(RTGRouteSummary *response, NSError *error) { + if (response) { + NSLog(@"Finished trip with %i points", response.pointCount); + NSLog(@"Passed %i features", response.featureCount); + NSLog(@"Travelled %i meters", response.distance); + NSLog(@"It took %i seconds", response.elapsedTime); + } else { + NSLog(@"RPC error: %@", error); + } +}]; + +``` + +The `GRXWriter` class is generic enough to allow for asynchronous streams, streams of future values, +or even infinite streams. + +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. The way to call a +bidirectional streaming RPC is just a combination of how to call request-streaming RPCs and +response-streaming RPCs. + +```objective-c +[client routeChatWithRequestsWriter:notesWriter + eventHandler:^(BOOL done, RTGRouteNote *note, NSError *error) { + if (note) { + NSLog(@"Got message %@ at %@", note.message, note.location); + } else if (error) { + NSLog(@"RPC error: %@", error); + } + if (done) { + NSLog(@"Chat ended."); + } +}]; +``` + +The semantics for the handler block and the `GRXWriter` argument here are exactly the same as for +our request-streaming and response-streaming methods. Although both client and server will always +get the other's messages in the order they were written, the two streams operate completely +independently. diff --git a/grpc-common/objective-c/route_guide/RouteGuide.podspec b/grpc-common/objective-c/route_guide/RouteGuide.podspec new file mode 100644 index 0000000000..7b99a6c6a7 --- /dev/null +++ b/grpc-common/objective-c/route_guide/RouteGuide.podspec @@ -0,0 +1,35 @@ +Pod::Spec.new do |s| + s.name = "RouteGuide" + s.version = "0.0.1" + s.license = "New BSD" + + s.ios.deployment_target = "6.0" + s.osx.deployment_target = "10.8" + + # Base directory where the .proto files are. + src = "../../protos" + + # Directory where the generated files will be place. + dir = "Pods/" + s.name + + # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. + s.prepare_command = <<-CMD + mkdir -p #{dir} + protoc -I #{src} --objc_out=#{dir} --objcgrpc_out=#{dir} #{src}/route_guide.proto + CMD + + s.subspec "Messages" do |ms| + ms.source_files = "#{dir}/*.pbobjc.{h,m}", "#{dir}/**/*.pbobjc.{h,m}" + ms.header_mappings_dir = dir + ms.requires_arc = false + ms.dependency "Protobuf", "~> 3.0.0-alpha-3" + end + + s.subspec "Services" do |ss| + ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}" + ss.header_mappings_dir = dir + ss.requires_arc = true + ss.dependency "gRPC", "~> 0.6" + ss.dependency "#{s.name}/Messages" + end +end diff --git a/grpc-common/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj b/grpc-common/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..6ab6b27a1b --- /dev/null +++ b/grpc-common/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj @@ -0,0 +1,366 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 124E20A2FC8EAE54460D4ED2 /* libPods-RouteGuideClient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 71CEE03D66D40FC37264D6E4 /* libPods-RouteGuideClient.a */; }; + 632527831B1D0396003073D9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 632527821B1D0396003073D9 /* main.m */; }; + 632527861B1D0396003073D9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 632527851B1D0396003073D9 /* AppDelegate.m */; }; + 6325278F1B1D0396003073D9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6325278D1B1D0396003073D9 /* Main.storyboard */; }; + 632527911B1D0396003073D9 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 632527901B1D0396003073D9 /* Images.xcassets */; }; + 6367B55B1B223AFA008861F5 /* route_guide_db.json in Resources */ = {isa = PBXBuildFile; fileRef = 6367B55A1B223AFA008861F5 /* route_guide_db.json */; }; + 63A6015C1B1DAB5000FA5B86 /* ViewControllers.m in Sources */ = {isa = PBXBuildFile; fileRef = 63A6015B1B1DAB5000FA5B86 /* ViewControllers.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 6325277D1B1D0396003073D9 /* RouteGuideClient.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RouteGuideClient.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 632527811B1D0396003073D9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 632527821B1D0396003073D9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 632527841B1D0396003073D9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 632527851B1D0396003073D9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6325278E1B1D0396003073D9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 632527901B1D0396003073D9 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6367B55A1B223AFA008861F5 /* route_guide_db.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = route_guide_db.json; sourceTree = ""; }; + 63A6015B1B1DAB5000FA5B86 /* ViewControllers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewControllers.m; sourceTree = ""; }; + 71CEE03D66D40FC37264D6E4 /* libPods-RouteGuideClient.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RouteGuideClient.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + ADA4C647BAE906F79AD9A45E /* Pods-RouteGuideClient.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RouteGuideClient.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RouteGuideClient/Pods-RouteGuideClient.debug.xcconfig"; sourceTree = ""; }; + C83C5A54D1A4EA07569F1AED /* Pods-RouteGuideClient.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RouteGuideClient.release.xcconfig"; path = "Pods/Target Support Files/Pods-RouteGuideClient/Pods-RouteGuideClient.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 6325277A1B1D0395003073D9 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 124E20A2FC8EAE54460D4ED2 /* libPods-RouteGuideClient.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 56849C29DC376BF4B902CD77 /* Pods */ = { + isa = PBXGroup; + children = ( + ADA4C647BAE906F79AD9A45E /* Pods-RouteGuideClient.debug.xcconfig */, + C83C5A54D1A4EA07569F1AED /* Pods-RouteGuideClient.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 631C63891B1DBC41001295D5 /* Misc */ = { + isa = PBXGroup; + children = ( + 632527841B1D0396003073D9 /* AppDelegate.h */, + 632527851B1D0396003073D9 /* AppDelegate.m */, + 632527901B1D0396003073D9 /* Images.xcassets */, + 632527801B1D0396003073D9 /* Supporting Files */, + ); + path = Misc; + sourceTree = ""; + }; + 632527741B1D0395003073D9 = { + isa = PBXGroup; + children = ( + 6325277F1B1D0396003073D9 /* RouteGuideClient */, + 6325277E1B1D0396003073D9 /* Products */, + 56849C29DC376BF4B902CD77 /* Pods */, + 7482B8A18481F7B13ADE4530 /* Frameworks */, + ); + sourceTree = ""; + }; + 6325277E1B1D0396003073D9 /* Products */ = { + isa = PBXGroup; + children = ( + 6325277D1B1D0396003073D9 /* RouteGuideClient.app */, + ); + name = Products; + sourceTree = ""; + }; + 6325277F1B1D0396003073D9 /* RouteGuideClient */ = { + isa = PBXGroup; + children = ( + 63A6015B1B1DAB5000FA5B86 /* ViewControllers.m */, + 6367B55A1B223AFA008861F5 /* route_guide_db.json */, + 6325278D1B1D0396003073D9 /* Main.storyboard */, + 631C63891B1DBC41001295D5 /* Misc */, + ); + name = RouteGuideClient; + sourceTree = SOURCE_ROOT; + }; + 632527801B1D0396003073D9 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 632527811B1D0396003073D9 /* Info.plist */, + 632527821B1D0396003073D9 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 7482B8A18481F7B13ADE4530 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 71CEE03D66D40FC37264D6E4 /* libPods-RouteGuideClient.a */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 6325277C1B1D0395003073D9 /* RouteGuideClient */ = { + isa = PBXNativeTarget; + buildConfigurationList = 632527A31B1D0396003073D9 /* Build configuration list for PBXNativeTarget "RouteGuideClient" */; + buildPhases = ( + C6FC30AD2376EC04317237C5 /* Check Pods Manifest.lock */, + 632527791B1D0395003073D9 /* Sources */, + 6325277A1B1D0395003073D9 /* Frameworks */, + 6325277B1B1D0395003073D9 /* Resources */, + FFE0BCF30339E7A50A989EAB /* Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RouteGuideClient; + productName = RouteGuideClient; + productReference = 6325277D1B1D0396003073D9 /* RouteGuideClient.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 632527751B1D0395003073D9 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = gRPC; + TargetAttributes = { + 6325277C1B1D0395003073D9 = { + CreatedOnToolsVersion = 6.3.1; + }; + }; + }; + buildConfigurationList = 632527781B1D0395003073D9 /* Build configuration list for PBXProject "RouteGuideClient" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 632527741B1D0395003073D9; + productRefGroup = 6325277E1B1D0396003073D9 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6325277C1B1D0395003073D9 /* RouteGuideClient */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 6325277B1B1D0395003073D9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6325278F1B1D0396003073D9 /* Main.storyboard in Resources */, + 632527911B1D0396003073D9 /* Images.xcassets in Resources */, + 6367B55B1B223AFA008861F5 /* route_guide_db.json in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + C6FC30AD2376EC04317237C5 /* Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + FFE0BCF30339E7A50A989EAB /* Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RouteGuideClient/Pods-RouteGuideClient-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 632527791B1D0395003073D9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 632527861B1D0396003073D9 /* AppDelegate.m in Sources */, + 632527831B1D0396003073D9 /* main.m in Sources */, + 63A6015C1B1DAB5000FA5B86 /* ViewControllers.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6325278D1B1D0396003073D9 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6325278E1B1D0396003073D9 /* Base */, + ); + name = Main.storyboard; + path = Misc; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 632527A11B1D0396003073D9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 632527A21B1D0396003073D9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 632527A41B1D0396003073D9 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = ADA4C647BAE906F79AD9A45E /* Pods-RouteGuideClient.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = Misc/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 632527A51B1D0396003073D9 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C83C5A54D1A4EA07569F1AED /* Pods-RouteGuideClient.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = Misc/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 632527781B1D0395003073D9 /* Build configuration list for PBXProject "RouteGuideClient" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 632527A11B1D0396003073D9 /* Debug */, + 632527A21B1D0396003073D9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 632527A31B1D0396003073D9 /* Build configuration list for PBXNativeTarget "RouteGuideClient" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 632527A41B1D0396003073D9 /* Debug */, + 632527A51B1D0396003073D9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 632527751B1D0395003073D9 /* Project object */; +} diff --git a/grpc-common/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/grpc-common/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..f208589e44 --- /dev/null +++ b/grpc-common/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/grpc-common/objective-c/route_guide/ViewControllers.m b/grpc-common/objective-c/route_guide/ViewControllers.m new file mode 100644 index 0000000000..cfc3338bca --- /dev/null +++ b/grpc-common/objective-c/route_guide/ViewControllers.m @@ -0,0 +1,228 @@ +/* + * + * 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. + * + */ + +#import +#import +#import +#import + +static NSString * const kHostAddress = @"http://localhost:50051"; + +// Category to override RTGPoint's description. +@interface RTGPoint (Description) +- (NSString *)description; +@end + +@implementation RTGPoint (Description) +- (NSString *)description { + NSString *verticalDirection = self.latitude >= 0 ? @"N" : @"S"; + NSString *horizontalDirection = self.longitude >= 0 ? @"E" : @"W"; + return [NSString stringWithFormat:@"%.02f%@ %.02f%@", + abs(self.latitude) / 1E7f, verticalDirection, + abs(self.longitude) / 1E7f, horizontalDirection]; +} +@end + +// Category to give RTGRouteNote a convenience constructor. +@interface RTGRouteNote (Constructors) ++ (instancetype)noteWithMessage:(NSString *)message + latitude:(float)latitude + longitude:(float)longitude; +@end + +@implementation RTGRouteNote (Constructors) ++ (instancetype)noteWithMessage:(NSString *)message + latitude:(float)latitude + longitude:(float)longitude { + RTGRouteNote *note = [self message]; + note.message = message; + note.location.latitude = (int32_t) latitude * 1E7; + note.location.longitude = (int32_t) longitude * 1E7; + return note; +} +@end + + +#pragma mark Demo: Get Feature + +// Run the getFeature demo. Calls getFeature with a point known to have a feature and a point known +// not to have a feature. + +@interface GetFeatureViewController : UIViewController +@end + +@implementation GetFeatureViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + + void (^handler)(RTGFeature *response, NSError *error) = ^(RTGFeature *response, NSError *error) { + if (response.name.length) { + NSLog(@"Found feature called %@ at %@.", response.name, response.location); + } else if (response) { + NSLog(@"Found no features at %@", response.location); + } else { + NSLog(@"RPC error: %@", error); + } + }; + + RTGPoint *point = [RTGPoint message]; + point.latitude = 409146138; + point.longitude = -746188906; + + [client getFeatureWithRequest:point handler:handler]; + [client getFeatureWithRequest:[RTGPoint message] handler:handler]; +} + +@end + + +#pragma mark Demo: List Features + +// Run the listFeatures demo. Calls listFeatures with a rectangle containing all of the features in +// the pre-generated database. Prints each response as it comes in. + +@interface ListFeaturesViewController : UIViewController +@end + +@implementation ListFeaturesViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + + RTGRectangle *rectangle = [RTGRectangle message]; + rectangle.lo.latitude = 405E6; + rectangle.lo.longitude = -750E6; + rectangle.hi.latitude = 410E6; + rectangle.hi.longitude = -745E6; + + NSLog(@"Looking for features between %@ and %@", rectangle.lo, rectangle.hi); + [client listFeaturesWithRequest:rectangle + eventHandler:^(BOOL done, RTGFeature *response, NSError *error) { + if (response) { + NSLog(@"Found feature at %@ called %@.", response.location, response.name); + } else if (error) { + NSLog(@"RPC error: %@", error); + } + }]; +} + +@end + + +#pragma mark Demo: Record Route + +// Run the recordRoute demo. Sends several randomly chosen points from the pre-generated feature +// database with a variable delay in between. Prints the statistics when they are sent from the +// server. + +@interface RecordRouteViewController : UIViewController +@end + +@implementation RecordRouteViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + NSString *dataBasePath = [NSBundle.mainBundle pathForResource:@"route_guide_db" + ofType:@"json"]; + NSData *dataBaseContent = [NSData dataWithContentsOfFile:dataBasePath]; + NSArray *features = [NSJSONSerialization JSONObjectWithData:dataBaseContent options:0 error:NULL]; + + GRXWriter *locations = [[GRXWriter writerWithContainer:features] map:^id(id feature) { + RTGPoint *location = [RTGPoint message]; + location.longitude = [((NSNumber *) feature[@"location"][@"longitude"]) intValue]; + location.latitude = [((NSNumber *) feature[@"location"][@"latitude"]) intValue]; + NSLog(@"Visiting point %@", location); + return location; + }]; + + RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + + [client recordRouteWithRequestsWriter:locations handler:^(RTGRouteSummary *response, NSError *error) { + if (response) { + NSLog(@"Finished trip with %i points", response.pointCount); + NSLog(@"Passed %i features", response.featureCount); + NSLog(@"Travelled %i meters", response.distance); + NSLog(@"It took %i seconds", response.elapsedTime); + } else { + NSLog(@"RPC error: %@", error); + } + }]; +} + +@end + + +#pragma mark Demo: Route Chat + +// Run the routeChat demo. Send some chat messages, and print any chat messages that are sent from +// the server. + +@interface RouteChatViewController : UIViewController +@end + +@implementation RouteChatViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + NSArray *notes = @[[RTGRouteNote noteWithMessage:@"First message" latitude:0 longitude:0], + [RTGRouteNote noteWithMessage:@"Second message" latitude:0 longitude:1], + [RTGRouteNote noteWithMessage:@"Third message" latitude:1 longitude:0], + [RTGRouteNote noteWithMessage:@"Fourth message" latitude:0 longitude:0]]; + GRXWriter *notesWriter = [[GRXWriter writerWithContainer:notes] map:^id(RTGRouteNote *note) { + NSLog(@"Sending message %@ at %@", note.message, note.location); + return note; + }]; + + RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + + [client routeChatWithRequestsWriter:notesWriter + eventHandler:^(BOOL done, RTGRouteNote *note, NSError *error) { + if (note) { + NSLog(@"Got message %@ at %@", note.message, note.location); + } else if (error) { + NSLog(@"RPC error: %@", error); + } + if (done) { + NSLog(@"Chat ended."); + } + }]; +} + +@end diff --git a/grpc-common/objective-c/route_guide/route_guide_db.json b/grpc-common/objective-c/route_guide/route_guide_db.json new file mode 100644 index 0000000000..9caebaa433 --- /dev/null +++ b/grpc-common/objective-c/route_guide/route_guide_db.json @@ -0,0 +1,121 @@ +[{ + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" +}, { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" +}, { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" +}, { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" +}, { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" +}, { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" +}, { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" +}, { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" +}, { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" +}, { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" +}, { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" +}, { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" +}, { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" +}, { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" +}, { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" +}, { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" +}, { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" +}, { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" +}, { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" +}, { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" +}] diff --git a/grpc-common/php/.gitignore b/grpc-common/php/.gitignore new file mode 100644 index 0000000000..d8a7996ab3 --- /dev/null +++ b/grpc-common/php/.gitignore @@ -0,0 +1,2 @@ +composer.lock +vendor/ diff --git a/grpc-common/php/README.md b/grpc-common/php/README.md new file mode 100644 index 0000000000..247235adfd --- /dev/null +++ b/grpc-common/php/README.md @@ -0,0 +1,64 @@ +gRPC in 3 minutes (PHP) +=========================== + +PREREQUISITES +------------- + +This requires PHP 5.5 or greater. + +INSTALL +------- + - On Mac OS X, install [homebrew][]. On Linux, install [linuxbrew][]. Run the following command to install gRPC. + + ```sh + $ curl -fsSL https://goo.gl/getgrpc | bash -s php + ``` + This will download and run the [gRPC install script][] and compile the gRPC PHP extension. + + - Clone this repository + + ```sh + $ git clone https://github.com/grpc/grpc-common.git + ``` + + - Install composer + + ``` + $ cd grpc-common/php + $ curl -sS https://getcomposer.org/installer | php + $ php composer.phar install + ``` + +TRY IT! +------- + + - Run the server + + Please follow the instruction in [Node][] to run the server + ``` + $ cd grpc-common/node + $ nodejs greeter_server.js + ``` + + - Run the client + + ``` + $ cd grpc-common/php + $ ./run_greeter_client.sh + ``` + +NOTE +---- + +This directory has a copy of `helloworld.proto` because it currently depends on +some Protocol Buffer 2.0 syntax. There is no proto3 support for PHP yet. + +TUTORIAL +-------- + +Coming soon + +[homebrew]:http://brew.sh +[linuxbrew]:https://github.com/Homebrew/linuxbrew#installation +[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install +[Node]:https://github.com/grpc/grpc-common/tree/master/node diff --git a/grpc-common/php/composer.json b/grpc-common/php/composer.json new file mode 100644 index 0000000000..f0ce3a2aff --- /dev/null +++ b/grpc-common/php/composer.json @@ -0,0 +1,17 @@ +{ + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/stanley-cheung/Protobuf-PHP" + } + ], + "name": "grpc/grpc-demo", + "description": "gRPC example for PHP", + "minimum-stability": "dev", + "require": { + "php": ">=5.5.0", + "datto/protobuf-php": "dev-master", + "google/auth": "dev-master", + "grpc/grpc": "dev-master" + } +} diff --git a/grpc-common/php/greeter_client.php b/grpc-common/php/greeter_client.php new file mode 100644 index 0000000000..8ae19ae46c --- /dev/null +++ b/grpc-common/php/greeter_client.php @@ -0,0 +1,49 @@ +setName($name); + list($reply, $status) = $client->SayHello($request)->wait(); + $message = $reply->getMessage(); + return $message; +} + +$name = !empty($argv[1]) ? $argv[1] : 'world'; +print(greet($name)."\n"); diff --git a/grpc-common/php/helloworld.php b/grpc-common/php/helloworld.php new file mode 100644 index 0000000000..22da3d3970 --- /dev/null +++ b/grpc-common/php/helloworld.php @@ -0,0 +1,160 @@ +number = 1; + $f->name = "name"; + $f->type = \DrSlump\Protobuf::TYPE_STRING; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasName(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \helloworld\HelloRequest + */ + public function clearName(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return string + */ + public function getName(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param string $value + * @return \helloworld\HelloRequest + */ + public function setName( $value){ + return $this->_set(1, $value); + } + } +} + +namespace helloworld { + + class HelloReply extends \DrSlump\Protobuf\Message { + + /** @var string */ + public $message = null; + + + /** @var \Closure[] */ + protected static $__extensions = array(); + + public static function descriptor() + { + $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloReply'); + + // OPTIONAL STRING message = 1 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 1; + $f->name = "message"; + $f->type = \DrSlump\Protobuf::TYPE_STRING; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasMessage(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \helloworld\HelloReply + */ + public function clearMessage(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return string + */ + public function getMessage(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param string $value + * @return \helloworld\HelloReply + */ + public function setMessage( $value){ + return $this->_set(1, $value); + } + } +} + +namespace helloworld { + + class GreeterClient{ + + private $rpc_impl; + + public function __construct($rpc_impl) { + $this->rpc_impl = $rpc_impl; + } + /** + * @param helloworld\HelloRequest $input + */ + public function SayHello(\helloworld\HelloRequest $argument, $metadata = array()) { + return $this->rpc_impl->_simpleRequest('/helloworld.Greeter/SayHello', $argument, '\helloworld\HelloReply::deserialize', $metadata); + } + } +} diff --git a/grpc-common/php/helloworld.proto b/grpc-common/php/helloworld.proto new file mode 100644 index 0000000000..ad8f7a1524 --- /dev/null +++ b/grpc-common/php/helloworld.proto @@ -0,0 +1,50 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto2"; + +option java_package = "ex.grpc"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + optional string name = 1; +} + +// The response message containing the greetings +message HelloReply { + optional string message = 1; +} diff --git a/grpc-common/php/route_guide/README.md b/grpc-common/php/route_guide/README.md new file mode 100644 index 0000000000..084661a5eb --- /dev/null +++ b/grpc-common/php/route_guide/README.md @@ -0,0 +1,262 @@ +#gRPC Basics: PHP + +This tutorial provides a basic PHP programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate client code using the protocol buffer compiler. +- Use the PHP gRPC API to write a simple client for your service. + +It assumes a passing familiarity with [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto2 version of the protocol buffers language. + +Also note that currently you can only create clients in PHP for gRPC services - you can find out how to create gRPC servers in our other tutorials, e.g. [Node.js](https://github.com/grpc/grpc-common/tree/master/node/route_guide). + +This isn't a comprehensive guide to using gRPC in PHP: more reference documentation is coming soon. + +- [Why use gRPC?](#why-grpc) +- [Example code and setup](#setup) +- [Try it out!](#try) +- [Defining the service](#proto) +- [Generating client code](#protoc) +- [Creating the client](#client) + + + +## Why use gRPC? + +With gRPC you can define your service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. You also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + + + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/php/route_guide](https://github.com/grpc/grpc-common/tree/master/php/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/php/route_guide`: +```shell +$ cd grpc-common/php/route_guide +``` + +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +You also should have the relevant tools installed to generate the client interface code (and a server in another language, for testing). You can obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). + + + +## Try it out! + +To try the sample app, we need a gRPC server running locally. Let's compile and run, for example, the Node.js server in this repository: + +```shell +$ cd ../../node +$ npm install +$ cd route_guide +$ nodejs ./route_guide_server.js --db_path=route_guide_db.json +``` + +Run the PHP client (in a different terminal): + +```shell +$ ./run_route_guide_client.sh +``` + +The next sections guide you step-by-step through how this proto service is defined, how to generate a client library from it, and how to create a client stub that uses that library. + + + +## Defining the service + +First let's look at how the service we're using is defined. A gRPC *service* and its method *request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file for our example in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +```protobuf +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. Protocol buffers let you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server and receives a response later, just like a normal remote procedure call. +```protobuf + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *response-streaming RPC* where the client sends a request to the server and gets back a stream of response messages. You specify a response-streaming method by placing the `stream` keyword before the *response* type. +```protobuf + // 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 *request-streaming RPC* where the client sends a sequence of messages to the server. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a request-streaming method by placing the `stream` keyword before the *request* type. +```protobuf + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages to the other. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +```protobuf + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +```protobuf +// 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; +} +``` + + + +## Generating client code + +The PHP client stub implementation of the proto files can be generated by the [`protoc-gen-php`](https://github.com/datto/protobuf-php) tool. To install the tool: + +```sh +$ cd grpc-common/php +$ php composer.phar install +$ cd vendor/datto/protobuf-php +$ gem install rake ronn +$ rake pear:package version=1.0 +$ sudo pear install Protobuf-1.0.tgz +``` + +To generate the client stub implementation .php file: + +```sh +$ cd php/route_guide +$ protoc-gen-php -i . -o . ./route_guide.proto +``` + +A `route_guide.php` file will be generated in the `php/route_guide` directory. You do not need to modify the file. + +To load the generated client stub file, simply `require` it in your PHP application: + +```php +require dirname(__FILE__) . '/route_guide.php'; +``` + +The file contains: +- All the protocol buffer code to populate, serialize, and retrieve our request and response message types. +- A class called `examples\RouteGuideClient` that lets clients call the methods defined in the `RouteGuide` service. + + + +## Creating the client + +In this section, we'll look at creating a PHP client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/php/route_guide/route_guide_client.php](https://github.com/grpc/grpc-common/blob/master/php/route_guide/route_guide_client.php). + +### Constructing a client object + +To call service methods, we first need to create a client object, an instance of the generated `RouteGuideClient` class. The constructor of the class expects the server address and port we want to connect to: + +```php +$client = new examples\RouteGuideClient(new Grpc\BaseStub('localhost:50051', [])); +``` + +### Calling service methods + +Now let's look at how we call our service methods. + +#### Simple RPC + +Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local asynchronous method. + +```php + $point = new examples\Point(); + $point->setLatitude(409146138); + $point->setLongitude(-746188906); + list($feature, $status) = $client->GetFeature($point)->wait(); +``` + +As you can see, we create and populate a request object, i.e. an `examples\Point` object. Then, we call the method on the stub, passing it the request object. If there is no error, then we can read the response information from the server from our response object, i.e. an `examples\Feature` object. + +```php + print sprintf("Found %s \n at %f, %f\n", $feature->getName(), + $feature->getLocation()->getLatitude() / COORD_FACTOR, + $feature->getLocation()->getLongitude() / COORD_FACTOR); +``` + +#### Streaming RPCs + +Now let's look at our streaming methods. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: + +```php + $lo_point = new examples\Point(); + $hi_point = new examples\Point(); + + $lo_point->setLatitude(400000000); + $lo_point->setLongitude(-750000000); + $hi_point->setLatitude(420000000); + $hi_point->setLongitude(-730000000); + + $rectangle = new examples\Rectangle(); + $rectangle->setLo($lo_point); + $rectangle->setHi($hi_point); + + $call = $client->ListFeatures($rectangle); + // an iterator over the server streaming responses + $features = $call->responses(); + foreach ($features as $feature) { + // process each feature + } // the loop will end when the server indicates there is no more responses to be sent. +``` + +The `$call->responses()` method call returns an iterator. When the server sends a response, a `$feature` object will be returned in the `foreach` loop, until the server indiciates that there will be no more responses to be sent. + +The client-side streaming method `RecordRoute` is similar, except there we pass the method an iterator and get back a `examples\RouteSummary`. + +```php + $points_iter = function($db) { + for ($i = 0; $i < $num_points; $i++) { + $point = new examples\Point(); + $point->setLatitude($lat); + $point->setLongitude($long); + yield $point; + } + }; + // $points_iter is an iterator simulating client streaming + list($route_summary, $status) = + $client->RecordRoute($points_iter($db))->wait(); +``` + +Finally, let's look at our bidirectional streaming RPC `routeChat()`. In this case, we just pass a context to the method and get back a `BidiStreamingCall` stream object, which we can use to both write and read messages. + +```php +$call = $client->RouteChat(); +``` + +To write messages from the client: + +```php + foreach ($notes as $n) { + $route_note = new examples\RouteNote(); + $call->write($route_note); + } + $call->writesDone(); +``` + +To read messages from the server: + +```php + while ($route_note_reply = $call->read()) { + // process $route_note_reply + } +``` + +Each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. diff --git a/grpc-common/php/route_guide/route_guide.php b/grpc-common/php/route_guide/route_guide.php new file mode 100644 index 0000000000..a836e03b55 --- /dev/null +++ b/grpc-common/php/route_guide/route_guide.php @@ -0,0 +1,731 @@ +number = 1; + $f->name = "latitude"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + // OPTIONAL INT32 longitude = 2 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 2; + $f->name = "longitude"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasLatitude(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \examples\Point + */ + public function clearLatitude(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return int + */ + public function getLatitude(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param int $value + * @return \examples\Point + */ + public function setLatitude( $value){ + return $this->_set(1, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasLongitude(){ + return $this->_has(2); + } + + /** + * Clear value + * + * @return \examples\Point + */ + public function clearLongitude(){ + return $this->_clear(2); + } + + /** + * Get value + * + * @return int + */ + public function getLongitude(){ + return $this->_get(2); + } + + /** + * Set value + * + * @param int $value + * @return \examples\Point + */ + public function setLongitude( $value){ + return $this->_set(2, $value); + } + } +} + +namespace examples { + + class Rectangle extends \DrSlump\Protobuf\Message { + + /** @var \examples\Point */ + public $lo = null; + + /** @var \examples\Point */ + public $hi = null; + + + /** @var \Closure[] */ + protected static $__extensions = array(); + + public static function descriptor() + { + $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.Rectangle'); + + // OPTIONAL MESSAGE lo = 1 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 1; + $f->name = "lo"; + $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->reference = '\examples\Point'; + $descriptor->addField($f); + + // OPTIONAL MESSAGE hi = 2 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 2; + $f->name = "hi"; + $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->reference = '\examples\Point'; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasLo(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \examples\Rectangle + */ + public function clearLo(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return \examples\Point + */ + public function getLo(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param \examples\Point $value + * @return \examples\Rectangle + */ + public function setLo(\examples\Point $value){ + return $this->_set(1, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasHi(){ + return $this->_has(2); + } + + /** + * Clear value + * + * @return \examples\Rectangle + */ + public function clearHi(){ + return $this->_clear(2); + } + + /** + * Get value + * + * @return \examples\Point + */ + public function getHi(){ + return $this->_get(2); + } + + /** + * Set value + * + * @param \examples\Point $value + * @return \examples\Rectangle + */ + public function setHi(\examples\Point $value){ + return $this->_set(2, $value); + } + } +} + +namespace examples { + + class Feature extends \DrSlump\Protobuf\Message { + + /** @var string */ + public $name = null; + + /** @var \examples\Point */ + public $location = null; + + + /** @var \Closure[] */ + protected static $__extensions = array(); + + public static function descriptor() + { + $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.Feature'); + + // OPTIONAL STRING name = 1 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 1; + $f->name = "name"; + $f->type = \DrSlump\Protobuf::TYPE_STRING; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $descriptor->addField($f); + + // OPTIONAL MESSAGE location = 2 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 2; + $f->name = "location"; + $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->reference = '\examples\Point'; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasName(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \examples\Feature + */ + public function clearName(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return string + */ + public function getName(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param string $value + * @return \examples\Feature + */ + public function setName( $value){ + return $this->_set(1, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasLocation(){ + return $this->_has(2); + } + + /** + * Clear value + * + * @return \examples\Feature + */ + public function clearLocation(){ + return $this->_clear(2); + } + + /** + * Get value + * + * @return \examples\Point + */ + public function getLocation(){ + return $this->_get(2); + } + + /** + * Set value + * + * @param \examples\Point $value + * @return \examples\Feature + */ + public function setLocation(\examples\Point $value){ + return $this->_set(2, $value); + } + } +} + +namespace examples { + + class RouteNote extends \DrSlump\Protobuf\Message { + + /** @var \examples\Point */ + public $location = null; + + /** @var string */ + public $message = null; + + + /** @var \Closure[] */ + protected static $__extensions = array(); + + public static function descriptor() + { + $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.RouteNote'); + + // OPTIONAL MESSAGE location = 1 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 1; + $f->name = "location"; + $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->reference = '\examples\Point'; + $descriptor->addField($f); + + // OPTIONAL STRING message = 2 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 2; + $f->name = "message"; + $f->type = \DrSlump\Protobuf::TYPE_STRING; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasLocation(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \examples\RouteNote + */ + public function clearLocation(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return \examples\Point + */ + public function getLocation(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param \examples\Point $value + * @return \examples\RouteNote + */ + public function setLocation(\examples\Point $value){ + return $this->_set(1, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasMessage(){ + return $this->_has(2); + } + + /** + * Clear value + * + * @return \examples\RouteNote + */ + public function clearMessage(){ + return $this->_clear(2); + } + + /** + * Get value + * + * @return string + */ + public function getMessage(){ + return $this->_get(2); + } + + /** + * Set value + * + * @param string $value + * @return \examples\RouteNote + */ + public function setMessage( $value){ + return $this->_set(2, $value); + } + } +} + +namespace examples { + + class RouteSummary extends \DrSlump\Protobuf\Message { + + /** @var int */ + public $point_count = 0; + + /** @var int */ + public $feature_count = 0; + + /** @var int */ + public $distance = 0; + + /** @var int */ + public $elapsed_time = 0; + + + /** @var \Closure[] */ + protected static $__extensions = array(); + + public static function descriptor() + { + $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.RouteSummary'); + + // OPTIONAL INT32 point_count = 1 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 1; + $f->name = "point_count"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + // OPTIONAL INT32 feature_count = 2 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 2; + $f->name = "feature_count"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + // OPTIONAL INT32 distance = 3 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 3; + $f->name = "distance"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + // OPTIONAL INT32 elapsed_time = 4 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 4; + $f->name = "elapsed_time"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasPointCount(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \examples\RouteSummary + */ + public function clearPointCount(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return int + */ + public function getPointCount(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param int $value + * @return \examples\RouteSummary + */ + public function setPointCount( $value){ + return $this->_set(1, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasFeatureCount(){ + return $this->_has(2); + } + + /** + * Clear value + * + * @return \examples\RouteSummary + */ + public function clearFeatureCount(){ + return $this->_clear(2); + } + + /** + * Get value + * + * @return int + */ + public function getFeatureCount(){ + return $this->_get(2); + } + + /** + * Set value + * + * @param int $value + * @return \examples\RouteSummary + */ + public function setFeatureCount( $value){ + return $this->_set(2, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasDistance(){ + return $this->_has(3); + } + + /** + * Clear value + * + * @return \examples\RouteSummary + */ + public function clearDistance(){ + return $this->_clear(3); + } + + /** + * Get value + * + * @return int + */ + public function getDistance(){ + return $this->_get(3); + } + + /** + * Set value + * + * @param int $value + * @return \examples\RouteSummary + */ + public function setDistance( $value){ + return $this->_set(3, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasElapsedTime(){ + return $this->_has(4); + } + + /** + * Clear value + * + * @return \examples\RouteSummary + */ + public function clearElapsedTime(){ + return $this->_clear(4); + } + + /** + * Get value + * + * @return int + */ + public function getElapsedTime(){ + return $this->_get(4); + } + + /** + * Set value + * + * @param int $value + * @return \examples\RouteSummary + */ + public function setElapsedTime( $value){ + return $this->_set(4, $value); + } + } +} + +namespace examples { + + class RouteGuideClient{ + + private $rpc_impl; + + public function __construct($rpc_impl) { + $this->rpc_impl = $rpc_impl; + } + /** + * @param examples\Point $input + */ + public function GetFeature(\examples\Point $argument, $metadata = array()) { + return $this->rpc_impl->_simpleRequest('/examples.RouteGuide/GetFeature', $argument, '\examples\Feature::deserialize', $metadata); + } + /** + * @param examples\Rectangle $input + */ + public function ListFeatures($argument, $metadata = array()) { + return $this->rpc_impl->_serverStreamRequest('/examples.RouteGuide/ListFeatures', $argument, '\examples\Feature::deserialize', $metadata); + } + /** + * @param examples\Point $input + */ + public function RecordRoute($arguments, $metadata = array()) { + return $this->rpc_impl->_clientStreamRequest('/examples.RouteGuide/RecordRoute', $arguments, '\examples\RouteSummary::deserialize', $metadata); + } + /** + * @param examples\RouteNote $input + */ + public function RouteChat($metadata = array()) { + return $this->rpc_impl->_bidiRequest('/examples.RouteGuide/RouteChat', '\examples\RouteNote::deserialize', $metadata); + } + } +} diff --git a/grpc-common/php/route_guide/route_guide.proto b/grpc-common/php/route_guide/route_guide.proto new file mode 100644 index 0000000000..0947184dbb --- /dev/null +++ b/grpc-common/php/route_guide/route_guide.proto @@ -0,0 +1,120 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto2"; + +option java_package = "io.grpc.examples"; + +package examples; + +// Interface exported by the server. +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} + + // A server-to-client streaming RPC. + // + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} + + // A client-to-server streaming RPC. + // + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} + + // A Bidirectional streaming RPC. + // + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +} + +// Points are represented as latitude-longitude pairs in the E7 representation +// (degrees multiplied by 10**7 and rounded to the nearest integer). +// Latitudes should be in the range +/- 90 degrees and longitude should be in +// the range +/- 180 degrees (inclusive). +message Point { + optional int32 latitude = 1 [default = 0]; + optional int32 longitude = 2 [default = 0]; +} + +// A latitude-longitude rectangle, represented as two diagonally opposite +// points "lo" and "hi". +message Rectangle { + // One corner of the rectangle. + optional Point lo = 1; + + // The other corner of the rectangle. + optional Point hi = 2; +} + +// A feature names something at a given point. +// +// If a feature could not be named, the name is empty. +message Feature { + // The name of the feature. + optional string name = 1; + + // The point where the feature is detected. + optional Point location = 2; +} + +// A RouteNote is a message sent while at a given point. +message RouteNote { + // The location from which the message is sent. + optional Point location = 1; + + // The message to be sent. + optional string message = 2; +} + +// A RouteSummary is received in response to a RecordRoute rpc. +// +// It contains the number of individual points received, the number of +// detected features, and the total distance covered as the cumulative sum of +// the distance between each point. +message RouteSummary { + // The number of points received. + optional int32 point_count = 1 [default = 0]; + + // The number of known features passed while traversing the route. + optional int32 feature_count = 2 [default = 0]; + + // The distance covered in metres. + optional int32 distance = 3 [default = 0]; + + // The duration of the traversal in seconds. + optional int32 elapsed_time = 4 [default = 0]; +} diff --git a/grpc-common/php/route_guide/route_guide_client.php b/grpc-common/php/route_guide/route_guide_client.php new file mode 100644 index 0000000000..6d9ae58b66 --- /dev/null +++ b/grpc-common/php/route_guide/route_guide_client.php @@ -0,0 +1,205 @@ +getName(); + if (!$name) { + $name_str = "no feature"; + } else { + $name_str = "feature called $name"; + } + print sprintf("Found %s \n at %f, %f\n", $name_str, + $feature->getLocation()->getLatitude() / COORD_FACTOR, + $feature->getLocation()->getLongitude() / COORD_FACTOR); +} + +/** + * Run the getFeature demo. Calls getFeature with a point known to have a + * feature and a point known not to have a feature. + */ +function runGetFeature() { + print "Running GetFeature...\n"; + global $client; + + $point = new examples\Point(); + $points = array( + array(409146138, -746188906), + array(0, 0), + ); + + foreach ($points as $p) { + $point->setLatitude($p[0]); + $point->setLongitude($p[1]); + // make a unary grpc call + list($feature, $status) = $client->GetFeature($point)->wait(); + printFeature($feature); + } +} + +/** + * Run the listFeatures demo. Calls listFeatures with a rectangle + * containing all of the features in the pre-generated + * database. Prints each response as it comes in. + */ +function runListFeatures() { + print "Running ListFeatures...\n"; + global $client; + + $lo_point = new examples\Point(); + $hi_point = new examples\Point(); + + $lo_point->setLatitude(400000000); + $lo_point->setLongitude(-750000000); + $hi_point->setLatitude(420000000); + $hi_point->setLongitude(-730000000); + + $rectangle = new examples\Rectangle(); + $rectangle->setLo($lo_point); + $rectangle->setHi($hi_point); + + $call = $client->ListFeatures($rectangle); + // an iterator over the server streaming responses + $features = $call->responses(); + foreach ($features as $feature) { + printFeature($feature); + } +} + +/** + * Run the recordRoute demo. Sends several randomly chosen points from the + * pre-generated feature database with a variable delay in between. Prints + * the statistics when they are sent from the server. + */ +function runRecordRoute() { + print "Running RecordRoute...\n"; + global $client, $argv; + + $db = json_decode(file_get_contents($argv[1]), true); + $points_iter = function($db) { + $num_points_in_db = count($db); + $num_points = 10; + for ($i = 0; $i < $num_points; $i++) { + $point = new examples\Point(); + $index = rand(0, $num_points_in_db - 1); + $lat = $db[$index]['location']['latitude']; + $long = $db[$index]['location']['longitude']; + $feature_name = $db[$index]['name']; + $point->setLatitude($lat); + $point->setLongitude($long); + print sprintf("Visiting point %f, %f,\n with feature name: %s\n", + $lat / COORD_FACTOR, $long / COORD_FACTOR, + $feature_name ? $feature_name : ''); + usleep(rand(300000, 800000)); + yield $point; + } + }; + // $points_iter is an iterator simulating client streaming + list($route_summary, $status) = + $client->RecordRoute($points_iter($db))->wait(); + print sprintf("Finished trip with %d points\nPassed %d features\n". + "Travelled %d meters\nIt took %d seconds\n", + $route_summary->getPointCount(), + $route_summary->getFeatureCount(), + $route_summary->getDistance(), + $route_summary->getElapsedTime()); +} + +/** + * Run the routeChat demo. Send some chat messages, and print any chat + * messages that are sent from the server. + */ +function runRouteChat() { + print "Running RouteChat...\n"; + global $client; + + // start the bidirectional streaming call + $call = $client->RouteChat(); + + $notes = array( + array(1, 1, 'first message'), + array(1, 2, 'second message'), + array(2, 1, 'third message'), + array(1, 1, 'fourth message'), + array(1, 1, 'fifth message'), + ); + + foreach ($notes as $n) { + $point = new examples\Point(); + $point->setLatitude($lat = $n[0]); + $point->setLongitude($long = $n[1]); + + $route_note = new examples\RouteNote(); + $route_note->setLocation($point); + $route_note->setMessage($message = $n[2]); + + print sprintf("Sending message: '%s' at (%d, %d)\n", + $message, $lat, $long); + // send a bunch of messages to the server + $call->write($route_note); + } + $call->writesDone(); + + // read from the server until there's no more + while ($route_note_reply = $call->read()) { + print sprintf("Previous left message at (%d, %d): '%s'\n", + $route_note_reply->getLocation()->getLatitude(), + $route_note_reply->getLocation()->getLongitude(), + $route_note_reply->getMessage()); + } +} + +/** + * Run all of the demos in order + */ +function main() { + runGetFeature(); + runListFeatures(); + runRecordRoute(); + runRouteChat(); +} + +if (empty($argv[1])) { + print "Usage: php -d extension=grpc.so route_guide_client.php " . + "\n"; + exit(1); +} +main(); diff --git a/grpc-common/php/route_guide/run_route_guide_client.sh b/grpc-common/php/route_guide/run_route_guide_client.sh new file mode 100755 index 0000000000..e5ca07796b --- /dev/null +++ b/grpc-common/php/route_guide/run_route_guide_client.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# 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. + +set -e +cd $(dirname $0) +command -v brew >/dev/null 2>&1 && \ + extension_dir="-d extension_dir="`brew --prefix`/opt/grpc-php +php $extension_dir -d extension=grpc.so \ + route_guide_client.php ../../node/route_guide/route_guide_db.json diff --git a/grpc-common/php/run_greeter_client.sh b/grpc-common/php/run_greeter_client.sh new file mode 100755 index 0000000000..2906de9af8 --- /dev/null +++ b/grpc-common/php/run_greeter_client.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# 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. + +set -e +cd $(dirname $0) +command -v brew >/dev/null 2>&1 && \ + extension_dir="-d extension_dir="`brew --prefix`/opt/grpc-php +php $extension_dir -d extension=grpc.so greeter_client.php $1 diff --git a/grpc-common/protos/README.md b/grpc-common/protos/README.md new file mode 100644 index 0000000000..48df7c8943 --- /dev/null +++ b/grpc-common/protos/README.md @@ -0,0 +1,8 @@ +# Example protos + +## Contents + +- [helloworld.proto] + - The simple example used in the overview. +- [route_guide.proto] + - An example service described in detail in the tutorial. diff --git a/grpc-common/protos/auth_sample.proto b/grpc-common/protos/auth_sample.proto new file mode 100644 index 0000000000..a49caca657 --- /dev/null +++ b/grpc-common/protos/auth_sample.proto @@ -0,0 +1,57 @@ +// 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 grpc.testing; + +option objc_class_prefix = "AUTH"; + +// Unary request. +message Request { + // Whether Response should include username. + bool fill_username = 4; + + // Whether Response should include OAuth scope. + bool fill_oauth_scope = 5; +} + +// Unary response, as configured by the request. +message Response { + // The user the request came from, for verifying authentication was + // successful. + string username = 2; + // OAuth scope. + string oauth_scope = 3; +} + +service TestService { + // One request followed by one response. + rpc UnaryCall(Request) returns (Response); +} diff --git a/grpc-common/protos/hellostreamingworld.proto b/grpc-common/protos/hellostreamingworld.proto new file mode 100644 index 0000000000..bd5af3b2d5 --- /dev/null +++ b/grpc-common/protos/hellostreamingworld.proto @@ -0,0 +1,54 @@ +// 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"; +option objc_class_prefix = "HSW"; + +package hellostreamingworld; + +// The greeting service definition. +service MultiGreeter { + // Sends multiple greetings + rpc sayHello (HelloRequest) returns (stream HelloReply) {} +} + +// The request message containing the user's name and how many greetings +// they want. +message HelloRequest { + string name = 1; + string num_greetings = 2; +} + +// A response message containing a greeting +message HelloReply { + string message = 1; +} + diff --git a/grpc-common/protos/helloworld.proto b/grpc-common/protos/helloworld.proto new file mode 100644 index 0000000000..7d58870a70 --- /dev/null +++ b/grpc-common/protos/helloworld.proto @@ -0,0 +1,51 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "io.grpc.examples"; +option objc_class_prefix = "HLW"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} diff --git a/grpc-common/protos/route_guide.proto b/grpc-common/protos/route_guide.proto new file mode 100644 index 0000000000..bfde5f1ead --- /dev/null +++ b/grpc-common/protos/route_guide.proto @@ -0,0 +1,124 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "ex.grpc"; +option objc_class_prefix = "RTG"; + +package examples; + +// Interface exported by the server. +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + // + // A feature with an empty name is returned if there's no feature at the 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/grpc-common/python/helloworld/.gitignore b/grpc-common/python/helloworld/.gitignore new file mode 100644 index 0000000000..0d20b6487c --- /dev/null +++ b/grpc-common/python/helloworld/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/grpc-common/python/helloworld/README.md b/grpc-common/python/helloworld/README.md new file mode 100644 index 0000000000..0a6a718bae --- /dev/null +++ b/grpc-common/python/helloworld/README.md @@ -0,0 +1,116 @@ +# gRPC Python Hello World + +This is a quick introduction with a simple example and installation instructions: for a more complete tutorial see [gRPC Basics: Python](https://github.com/grpc/grpc-common/tree/master/python/route_guide). + +### Install gRPC +Make sure you have built gRPC Python from source on your system. Follow the instructions here: +[https://github.com/grpc/grpc/blob/master/src/python/README.md](https://github.com/grpc/grpc/blob/master/src/python/README.md). + +This gives you a python virtual environment with installed gRPC Python +in GRPC_ROOT/python2.7_virtual_environment. GRPC_ROOT is the path to which you +have cloned the [gRPC git repo](https://github.com/grpc/grpc). + +### Get the source code + +The example code for our Hello World and our other examples live in the `grpc-common` +GitHub repository. Clone this repository to your local machine by running the +following command: + + +```sh +$ git clone https://github.com/grpc/grpc-common.git +``` + +Change your current directory to grpc-common/python/helloworld + +```sh +$ cd grpc-common/python/helloworld/ +``` + +### Defining a service + +The first step in creating our example is to define a *service*: an RPC +service specifies the methods that can be called remotely with their parameters +and return types. As you saw in the +[overview](#protocolbuffers) above, gRPC does this using [protocol +buffers](https://developers.google.com/protocol-buffers/docs/overview). We +use the protocol buffers interface definition language (IDL) to define our +service methods, and define the parameters and return +types as protocol buffer message types. Both the client and the +server use interface code generated from the service definition. + +Here's our example service definition. The `Greeting` +service has one method, `hello`, that lets the server receive a single +`HelloRequest` +message from the remote client containing the user's name, then send back +a greeting in a single `HelloReply`. This is the simplest type of RPC you +can specify in gRPC. + +``` +syntax = "proto3"; + +option java_package = "io.grpc.examples"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} + +``` + + +### Generating gRPC code + +Once we've defined our service, we use the protocol buffer compiler +`protoc` to generate the special client and server code we need to create +our application. The generated code contains both stub code for clients to +use and an abstract interface for servers to implement, both with the method +defined in our `Greeting` service. + +To generate the client and server side interfaces: + +```sh +$ ./run_codegen.sh +``` +Which internally invokes the proto-compiler as: + +```sh +$ protoc -I ../../protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` ../../protos/helloworld.proto +``` + +Optionally, you can just skip the code generation step as the generated python module has already +been generated for you (helloworld_pb2.py). + +### The client + +Client-side code can be found in [greeter_client.py](https://github.com/grpc/grpc-common/blob/master/python/helloworld/greeter_client.py). + +You can run the client using: + +```sh +$ ./run_client.sh +``` + + +### The server + +Server side code can be found in [greeter_server.py](https://github.com/grpc/grpc-common/blob/master/python/helloworld/greeter_server.py). + +You can run the server using: + +```sh +$ ./run_server.sh +``` diff --git a/grpc-common/python/helloworld/greeter_client.py b/grpc-common/python/helloworld/greeter_client.py new file mode 100755 index 0000000000..370ce46770 --- /dev/null +++ b/grpc-common/python/helloworld/greeter_client.py @@ -0,0 +1,44 @@ +# 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. + +"""The Python implementation of the GRPC helloworld.Greeter client.""" + +import helloworld_pb2 + +_TIMEOUT_SECONDS = 10 + + +def run(): + with helloworld_pb2.early_adopter_create_Greeter_stub('localhost', 50051) as stub: + response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'), _TIMEOUT_SECONDS) + print "Greeter client received: " + response.message + + +if __name__ == '__main__': + run() diff --git a/grpc-common/python/helloworld/greeter_server.py b/grpc-common/python/helloworld/greeter_server.py new file mode 100644 index 0000000000..81353666b1 --- /dev/null +++ b/grpc-common/python/helloworld/greeter_server.py @@ -0,0 +1,56 @@ +# 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. + +"""The Python implementation of the GRPC helloworld.Greeter server.""" + +import time + +import helloworld_pb2 + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +class Greeter(helloworld_pb2.EarlyAdopterGreeterServicer): + + def SayHello(self, request, context): + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) + + +def serve(): + server = helloworld_pb2.early_adopter_create_Greeter_server( + Greeter(), 50051, None, None) + server.start() + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop() + +if __name__ == '__main__': + serve() diff --git a/grpc-common/python/helloworld/run_client.sh b/grpc-common/python/helloworld/run_client.sh new file mode 100755 index 0000000000..095e6bc2f0 --- /dev/null +++ b/grpc-common/python/helloworld/run_client.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# This is where you have cloned out the https://github.com/grpc/grpc repository +# And built gRPC Python. +# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS +GRPC_ROOT=~/github/grpc + +$GRPC_ROOT/python2.7_virtual_environment/bin/python greeter_client.py diff --git a/grpc-common/python/helloworld/run_codegen.sh b/grpc-common/python/helloworld/run_codegen.sh new file mode 100755 index 0000000000..4d826c7946 --- /dev/null +++ b/grpc-common/python/helloworld/run_codegen.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Runs the protoc with gRPC plugin to generate protocol messages and gRPC stubs. +protoc -I ../../protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` ../../protos/helloworld.proto diff --git a/grpc-common/python/helloworld/run_server.sh b/grpc-common/python/helloworld/run_server.sh new file mode 100755 index 0000000000..13b009e6cc --- /dev/null +++ b/grpc-common/python/helloworld/run_server.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# This is where you have cloned out the https://github.com/grpc/grpc repository +# And built gRPC Python. +# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS +GRPC_ROOT=~/github/grpc + +$GRPC_ROOT/python2.7_virtual_environment/bin/python greeter_server.py + diff --git a/grpc-common/python/route_guide/.gitignore b/grpc-common/python/route_guide/.gitignore new file mode 100644 index 0000000000..0d20b6487c --- /dev/null +++ b/grpc-common/python/route_guide/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/grpc-common/python/route_guide/README.md b/grpc-common/python/route_guide/README.md new file mode 100644 index 0000000000..91bef0ac00 --- /dev/null +++ b/grpc-common/python/route_guide/README.md @@ -0,0 +1,303 @@ +#gRPC Basics: Python + +This tutorial provides a basic Python programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate server and client code using the protocol buffer compiler. +- Use the Python gRPC API to write a simple client and server for your service. + +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. + +This isn't a comprehensive guide to using gRPC in Python: more reference documentation is coming soon. + + +## Why use gRPC? + +This example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +With gRPC you can define your service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet, with all the complexity of communication between different languages and environments is handled for you by gRPC. You also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + +## Example code and setup + +The example code for this tutorial is in [grpc/grpc-common/python/route_guide](https://github.com/grpc/grpc-common/tree/master/python/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/python/route_guide`: +```shell +$ cd grpc-common/python/route_guide +``` + +You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Python quick start guide](https://github.com/grpc/grpc-common/tree/master/python). + +## Defining the service + +Your first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +```protobuf +service RouteGuide { + // (Method definitions not shown) +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +```protobuf + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *response-streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in the example, you specify a response-streaming method by placing the `stream` keyword before the *response* type. +```protobuf + // 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 *request-streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a request-streaming method by placing the `stream` keyword before the *request* type. +```protobuf + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectionally-streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +```protobuf + // 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) {} +``` + +Your .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +```protobuf +// 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; +} +``` + +## Generating client and server code + +Next you need to generate the gRPC client and server interfaces from your .proto service definition. You do this using the protocol buffer compiler `protoc` with a special gRPC Python plugin. Make sure you've installed protoc and followed the gRPC Python plugin [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): + +With `protoc` and the gRPC Python plugin installed, use the following command to generate the Python code: + +```shell +$ protoc -I ../../protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` ../../protos/route_guide.proto +``` + +Note that as we've already provided a version of the generated code in the example repository, running this command regenerates the appropriate file rather than creates a new one. The generated code file is called `route_guide_pb2.py` and contains: +- classes for the messages defined in route_guide.proto +- abstract classes for the service defined in route_guide.proto + - `EarlyAdopterRouteGuideServicer`, which defines the interface for implementations of the RouteGuide service + - `EarlyAdopterRouteGuideServer`, which may be started and stopped + - `EarlyAdopterRouteGuideStub`, which can be used by clients to invoke RouteGuide RPCs +- functions for application use + - `early_adopter_create_RouteGuide_server`, which creates a gRPC server given an `EarlyAdopterRouteGuideServicer` object + - `early_adopter_create_RouteGuide_stub`, which can be used by clients to create a stub object + + +## Creating the server + +First let's look at how you create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). + +Creating and running a `RouteGuide` server breaks down into two work items: +- Implementing the servicer interface generated from our service definition with functions that perform the actual "work" of the service. +- Running a gRPC server to listen for requests from clients and transmit responses. + +You can find the example `RouteGuide` server in [grpc-common/python/route_guide/route_guide_server.py](https://github.com/grpc/grpc-common/blob/master/python/route_guide/route_guide_server.py). + +### Implementing RouteGuide + +`route_guide_server.py` has a `RouteGuideServicer` class that implements the generated interface `route_guide_pb2.EarlyAdopterRouteGuideServicer`: + +```python +# RouteGuideServicer provides an implementation of the methods of the RouteGuide service. +class RouteGuideServicer(route_guide_pb2.EarlyAdopterRouteGuideServicer): +``` + +`RouteGuideServicer` implements all the `RouteGuide` service methods. + +#### Simple RPC + +Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. + +```python + def GetFeature(self, request, context): + feature = get_feature(self.db, request) + if feature is None: + return route_guide_pb2.Feature(name="", location=request) + else: + return feature +``` + +The method is passed a `route_guide_pb2.Point` request for the RPC, and an `RpcContext` object that provides RPC-specific information such as timeout limits. It returns a `route_guide_pb2.Feature` response. + +#### Response-streaming RPC + +Now let's look at the next method. `ListFeatures` is a response-streaming RPC that sends multiple `Feature`s to the client. + +```python + def ListFeatures(self, request, context): + left = min(request.lo.longitude, request.hi.longitude) + right = max(request.lo.longitude, request.hi.longitude) + top = max(request.lo.latitude, request.hi.latitude) + bottom = min(request.lo.latitude, request.hi.latitude) + for feature in self.db: + if (feature.location.longitude >= left and + feature.location.longitude <= right and + feature.location.latitude >= bottom and + feature.location.latitude <= top): + yield feature +``` + +Here the request message is a `route_guide_pb2.Rectangle` within which the client wants to find `Feature`s. Instead of returning a single response the method yields zero or more responses. + +#### Request-streaming RPC + +The request-streaming method `RecordRoute` uses an [iterator](https://docs.python.org/2/library/stdtypes.html#iterator-types) of request values and returns a single response value. + +```python + def RecordRoute(self, request_iterator, context): + point_count = 0 + feature_count = 0 + distance = 0.0 + prev_point = None + + start_time = time.time() + for point in request_iterator: + point_count += 1 + if get_feature(self.db, point): + feature_count += 1 + if prev_point: + distance += get_distance(prev_point, point) + prev_point = point + + elapsed_time = time.time() - start_time + return route_guide_pb2.RouteSummary(point_count=point_count, + feature_count=feature_count, + distance=int(distance), + elapsed_time=int(elapsed_time)) +``` + +#### Bidirectional streaming RPC + +Lastly let's look at the bidirectionally-streaming method `RouteChat`. + +```python + def RouteChat(self, request_iterator, context): + prev_notes = [] + for new_note in request_iterator: + for prev_note in prev_notes: + if prev_note.location == new_note.location: + yield prev_note + prev_notes.append(new_note) +``` + +This method's semantics are a combination of those of the request-streaming method and the response-streaming method. It is passed an iterator of request values and is itself an iterator of response values. + +### Starting the server + +Once you have implemented all the `RouteGuide` methods, the next step is to start up a gRPC server so that clients can actually use your service: + +```python +def serve(): + server = route_guide_pb2.early_adopter_create_RouteGuide_server( + RouteGuideServicer(), 50051, None, None) + server.start() +``` + +Because `start()` does not block you may need to sleep-loop if there is nothing else for your code to do while serving. + + +## Creating the client + +You can see the complete example client code in [grpc-common/python/route_guide/route_guide_client.py](https://github.com/grpc/grpc-common/blob/master/python/route_guide/route_guide_client.py). + +### Creating a stub + +To call service methods, we first need to create a *stub*. + +We use the `early_adopter_create_RouteGuide_stub` function of the `route_guide_pb2` module, generated from our .proto. + +```python +stub = RouteGuide::Stub.new('localhost', 50051) +``` + +The returned object implements all the methods defined by the `EarlyAdopterRouteGuideStub` interface, and is also a [context manager](https://docs.python.org/2/library/stdtypes.html#typecontextmanager). All RPCs invoked on the stub must be invoked within the stub's context, so it is common for stubs to be created and used with a [with statement](https://docs.python.org/2/reference/compound_stmts.html#the-with-statement): + +```python +with route_guide_pb2.early_adopter_create_RouteGuide_stub('localhost', 50051) as stub: +``` + +### Calling service methods + +For RPC methods that return a single response ("response-unary" methods), gRPC Python supports both synchronous (blocking) and asynchronous (non-blocking) control flow semantics. For response-streaming RPC methods, calls immediately return an iterator of response values. Calls to that iterator's `next()` method block until the response to be yielded from the iterator becomes available. + +#### Simple RPC + +A synchronous call to the simple RPC `GetFeature` is nearly as straightforward as calling a local method. The RPC call waits for the server to respond, and will either return a response or raise an exception: + +```python +feature = stub.GetFeature(point, timeout_in_seconds) +``` + +An asynchronous call to `GetFeature` is similar, but like calling a local method asynchronously in a thread pool: + +```python +feature_future = stub.GetFeature.async(point, timeout_in_seconds) +feature = feature_future.result() +``` + +#### Response-streaming RPC + +Calling the response-streaming `ListFeatures` is similar to working with sequence types: + +```python +for feature in stub.ListFeatures(rectangle, timeout_in_seconds): +``` + +#### Request-streaming RPC + +Calling the request-streaming `RecordRoute` is similar to passing a sequence to a local method. Like the simple RPC above that also returns a single response, it can be called synchronously or asynchronously: + +```python +route_summary = stub.RecordRoute(point_sequence, timeout_in_seconds) +``` + +```python +route_summary_future = stub.RecordRoute.async(point_sequence, timeout_in_seconds) +route_summary = route_summary_future.result() +``` + +#### Bidirectional streaming RPC + +Calling the bidirectionally-streaming `RouteChat` has (as is the case on the service-side) a combination of the request-streaming and response-streaming semantics: + +```python +for received_route_note in stub.RouteChat(sent_routes, timeout_in_seconds): +``` + +## Try it out! + +Run the server, which will listen on port 50051: + +```shell +$ python route_guide_server.py +``` + +Run the client (in a different terminal): + +```shell +$ python route_guide_client.py +``` diff --git a/grpc-common/python/route_guide/route_guide_client.py b/grpc-common/python/route_guide/route_guide_client.py new file mode 100755 index 0000000000..078231543e --- /dev/null +++ b/grpc-common/python/route_guide/route_guide_client.py @@ -0,0 +1,130 @@ +# 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. + +"""The Python implementation of the gRPC route guide client.""" + +import random +import time + +import route_guide_pb2 +import route_guide_resources + +_TIMEOUT_SECONDS = 30 + + +def make_route_note(message, latitude, longitude): + return route_guide_pb2.RouteNote( + message=message, + location=route_guide_pb2.Point(latitude=latitude, longitude=longitude)) + + +def guide_get_one_feature(stub, point): + feature = stub.GetFeature(point, _TIMEOUT_SECONDS) + if not feature.location: + print "Server returned incomplete feature" + return + + if feature.name: + print "Feature called %s at %s" % (feature.name, feature.location) + else: + print "Found no feature at %s" % feature.location + + +def guide_get_feature(stub): + guide_get_one_feature(stub, route_guide_pb2.Point(latitude=409146138, longitude=-746188906)) + guide_get_one_feature(stub, route_guide_pb2.Point(latitude=0, longitude=0)) + + +def guide_list_features(stub): + rect = route_guide_pb2.Rectangle( + lo=route_guide_pb2.Point( + latitude=400000000, longitude = -750000000), + hi=route_guide_pb2.Point( + latitude = 420000000, longitude = -730000000)) + print "Looking for features between 40, -75 and 42, -73" + + features = stub.ListFeatures(rect, _TIMEOUT_SECONDS) + + for feature in features: + print "Feature called %s at %s" % (feature.name, feature.location) + + +def generate_route(feature_list): + for _ in range(0, 10): + random_feature = feature_list[random.randint(0, len(feature_list) - 1)] + print "Visiting point %s" % random_feature.location + yield random_feature.location + time.sleep(random.uniform(0.5, 1.5)) + + +def guide_record_route(stub): + feature_list = route_guide_resources.read_route_guide_database() + + route_iter = generate_route(feature_list) + route_summary = stub.RecordRoute(route_iter, _TIMEOUT_SECONDS) + print "Finished trip with %s points " % route_summary.point_count + print "Passed %s features " % route_summary.feature_count + print "Travelled %s meters " % route_summary.distance + print "It took %s seconds " % route_summary.elapsed_time + + +def generate_messages(): + messages = [ + make_route_note("First message", 0, 0), + make_route_note("Second message", 0, 1), + make_route_note("Third message", 1, 0), + make_route_note("Fourth message", 0, 0), + make_route_note("Fifth message", 1, 0), + ] + for msg in messages: + print "Sending %s at %s" % (msg.message, msg.location) + yield msg + time.sleep(random.uniform(0.5, 1.0)) + + +def guide_route_chat(stub): + responses = stub.RouteChat(generate_messages(), _TIMEOUT_SECONDS) + for response in responses: + print "Received message %s at %s" % (response.message, response.location) + + +def run(): + with route_guide_pb2.early_adopter_create_RouteGuide_stub('localhost', 50051) as stub: + print "-------------- GetFeature --------------" + guide_get_feature(stub) + print "-------------- ListFeatures --------------" + guide_list_features(stub) + print "-------------- RecordRoute --------------" + guide_record_route(stub) + print "-------------- RouteChat --------------" + guide_route_chat(stub) + + +if __name__ == '__main__': + run() diff --git a/grpc-common/python/route_guide/route_guide_db.json b/grpc-common/python/route_guide/route_guide_db.json new file mode 100644 index 0000000000..9d6a980ab7 --- /dev/null +++ b/grpc-common/python/route_guide/route_guide_db.json @@ -0,0 +1,601 @@ +[{ + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" +}, { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" +}, { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" +}, { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" +}, { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" +}, { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" +}, { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" +}, { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" +}, { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" +}, { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" +}, { + "location": { + "latitude": 415736605, + "longitude": -742847522 + }, + "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" +}, { + "location": { + "latitude": 413843930, + "longitude": -740501726 + }, + "name": "162 Merrill Road, Highland Mills, NY 10930, USA" +}, { + "location": { + "latitude": 410873075, + "longitude": -744459023 + }, + "name": "Clinton Road, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 412346009, + "longitude": -744026814 + }, + "name": "16 Old Brook Lane, Warwick, NY 10990, USA" +}, { + "location": { + "latitude": 402948455, + "longitude": -747903913 + }, + "name": "3 Drake Lane, Pennington, NJ 08534, USA" +}, { + "location": { + "latitude": 406337092, + "longitude": -740122226 + }, + "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" +}, { + "location": { + "latitude": 406421967, + "longitude": -747727624 + }, + "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" +}, { + "location": { + "latitude": 416318082, + "longitude": -749677716 + }, + "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" +}, { + "location": { + "latitude": 415301720, + "longitude": -748416257 + }, + "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" +}, { + "location": { + "latitude": 402647019, + "longitude": -747071791 + }, + "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" +}, { + "location": { + "latitude": 412567807, + "longitude": -741058078 + }, + "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" +}, { + "location": { + "latitude": 416855156, + "longitude": -744420597 + }, + "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" +}, { + "location": { + "latitude": 404663628, + "longitude": -744820157 + }, + "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" +}, { + "location": { + "latitude": 407113723, + "longitude": -749746483 + }, + "name": "" +}, { + "location": { + "latitude": 402133926, + "longitude": -743613249 + }, + "name": "" +}, { + "location": { + "latitude": 400273442, + "longitude": -741220915 + }, + "name": "" +}, { + "location": { + "latitude": 411236786, + "longitude": -744070769 + }, + "name": "" +}, { + "location": { + "latitude": 411633782, + "longitude": -746784970 + }, + "name": "211-225 Plains Road, Augusta, NJ 07822, USA" +}, { + "location": { + "latitude": 415830701, + "longitude": -742952812 + }, + "name": "" +}, { + "location": { + "latitude": 413447164, + "longitude": -748712898 + }, + "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" +}, { + "location": { + "latitude": 405047245, + "longitude": -749800722 + }, + "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" +}, { + "location": { + "latitude": 418858923, + "longitude": -746156790 + }, + "name": "" +}, { + "location": { + "latitude": 417951888, + "longitude": -748484944 + }, + "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" +}, { + "location": { + "latitude": 407033786, + "longitude": -743977337 + }, + "name": "26 East 3rd Street, New Providence, NJ 07974, USA" +}, { + "location": { + "latitude": 417548014, + "longitude": -740075041 + }, + "name": "" +}, { + "location": { + "latitude": 410395868, + "longitude": -744972325 + }, + "name": "" +}, { + "location": { + "latitude": 404615353, + "longitude": -745129803 + }, + "name": "" +}, { + "location": { + "latitude": 406589790, + "longitude": -743560121 + }, + "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" +}, { + "location": { + "latitude": 414653148, + "longitude": -740477477 + }, + "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" +}, { + "location": { + "latitude": 405957808, + "longitude": -743255336 + }, + "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" +}, { + "location": { + "latitude": 411733589, + "longitude": -741648093 + }, + "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" +}, { + "location": { + "latitude": 412676291, + "longitude": -742606606 + }, + "name": "1270 Lakes Road, Monroe, NY 10950, USA" +}, { + "location": { + "latitude": 409224445, + "longitude": -748286738 + }, + "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" +}, { + "location": { + "latitude": 406523420, + "longitude": -742135517 + }, + "name": "652 Garden Street, Elizabeth, NJ 07202, USA" +}, { + "location": { + "latitude": 401827388, + "longitude": -740294537 + }, + "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" +}, { + "location": { + "latitude": 410564152, + "longitude": -743685054 + }, + "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 408472324, + "longitude": -740726046 + }, + "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" +}, { + "location": { + "latitude": 412452168, + "longitude": -740214052 + }, + "name": "5 White Oak Lane, Stony Point, NY 10980, USA" +}, { + "location": { + "latitude": 409146138, + "longitude": -746188906 + }, + "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" +}, { + "location": { + "latitude": 404701380, + "longitude": -744781745 + }, + "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 409642566, + "longitude": -746017679 + }, + "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" +}, { + "location": { + "latitude": 408031728, + "longitude": -748645385 + }, + "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" +}, { + "location": { + "latitude": 413700272, + "longitude": -742135189 + }, + "name": "367 Prospect Road, Chester, NY 10918, USA" +}, { + "location": { + "latitude": 404310607, + "longitude": -740282632 + }, + "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" +}, { + "location": { + "latitude": 409319800, + "longitude": -746201391 + }, + "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" +}, { + "location": { + "latitude": 406685311, + "longitude": -742108603 + }, + "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" +}, { + "location": { + "latitude": 419018117, + "longitude": -749142781 + }, + "name": "43 Dreher Road, Roscoe, NY 12776, USA" +}, { + "location": { + "latitude": 412856162, + "longitude": -745148837 + }, + "name": "Swan Street, Pine Island, NY 10969, USA" +}, { + "location": { + "latitude": 416560744, + "longitude": -746721964 + }, + "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" +}, { + "location": { + "latitude": 405314270, + "longitude": -749836354 + }, + "name": "" +}, { + "location": { + "latitude": 414219548, + "longitude": -743327440 + }, + "name": "" +}, { + "location": { + "latitude": 415534177, + "longitude": -742900616 + }, + "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" +}, { + "location": { + "latitude": 406898530, + "longitude": -749127080 + }, + "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" +}, { + "location": { + "latitude": 407586880, + "longitude": -741670168 + }, + "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" +}, { + "location": { + "latitude": 400106455, + "longitude": -742870190 + }, + "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" +}, { + "location": { + "latitude": 400066188, + "longitude": -746793294 + }, + "name": "" +}, { + "location": { + "latitude": 418803880, + "longitude": -744102673 + }, + "name": "40 Mountain Road, Napanoch, NY 12458, USA" +}, { + "location": { + "latitude": 414204288, + "longitude": -747895140 + }, + "name": "" +}, { + "location": { + "latitude": 414777405, + "longitude": -740615601 + }, + "name": "" +}, { + "location": { + "latitude": 415464475, + "longitude": -747175374 + }, + "name": "48 North Road, Forestburgh, NY 12777, USA" +}, { + "location": { + "latitude": 404062378, + "longitude": -746376177 + }, + "name": "" +}, { + "location": { + "latitude": 405688272, + "longitude": -749285130 + }, + "name": "" +}, { + "location": { + "latitude": 400342070, + "longitude": -748788996 + }, + "name": "" +}, { + "location": { + "latitude": 401809022, + "longitude": -744157964 + }, + "name": "" +}, { + "location": { + "latitude": 404226644, + "longitude": -740517141 + }, + "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" +}, { + "location": { + "latitude": 410322033, + "longitude": -747871659 + }, + "name": "" +}, { + "location": { + "latitude": 407100674, + "longitude": -747742727 + }, + "name": "" +}, { + "location": { + "latitude": 418811433, + "longitude": -741718005 + }, + "name": "213 Bush Road, Stone Ridge, NY 12484, USA" +}, { + "location": { + "latitude": 415034302, + "longitude": -743850945 + }, + "name": "" +}, { + "location": { + "latitude": 411349992, + "longitude": -743694161 + }, + "name": "" +}, { + "location": { + "latitude": 404839914, + "longitude": -744759616 + }, + "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 414638017, + "longitude": -745957854 + }, + "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" +}, { + "location": { + "latitude": 412127800, + "longitude": -740173578 + }, + "name": "" +}, { + "location": { + "latitude": 401263460, + "longitude": -747964303 + }, + "name": "" +}, { + "location": { + "latitude": 412843391, + "longitude": -749086026 + }, + "name": "" +}, { + "location": { + "latitude": 418512773, + "longitude": -743067823 + }, + "name": "" +}, { + "location": { + "latitude": 404318328, + "longitude": -740835638 + }, + "name": "42-102 Main Street, Belford, NJ 07718, USA" +}, { + "location": { + "latitude": 419020746, + "longitude": -741172328 + }, + "name": "" +}, { + "location": { + "latitude": 404080723, + "longitude": -746119569 + }, + "name": "" +}, { + "location": { + "latitude": 401012643, + "longitude": -744035134 + }, + "name": "" +}, { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" +}, { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" +}, { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" +}, { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" +}, { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" +}, { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" +}, { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" +}, { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" +}, { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" +}, { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" +}] diff --git a/grpc-common/python/route_guide/route_guide_pb2.py b/grpc-common/python/route_guide/route_guide_pb2.py new file mode 100644 index 0000000000..2a4532bb75 --- /dev/null +++ b/grpc-common/python/route_guide/route_guide_pb2.py @@ -0,0 +1,370 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: route_guide.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='route_guide.proto', + package='', + serialized_pb=_b('\n\x11route_guide.proto\",\n\x05Point\x12\x10\n\x08latitude\x18\x01 \x01(\x05\x12\x11\n\tlongitude\x18\x02 \x01(\x05\"3\n\tRectangle\x12\x12\n\x02lo\x18\x01 \x01(\x0b\x32\x06.Point\x12\x12\n\x02hi\x18\x02 \x01(\x0b\x32\x06.Point\"1\n\x07\x46\x65\x61ture\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x18\n\x08location\x18\x02 \x01(\x0b\x32\x06.Point\"6\n\tRouteNote\x12\x18\n\x08location\x18\x01 \x01(\x0b\x32\x06.Point\x12\x0f\n\x07message\x18\x02 \x01(\t\"b\n\x0cRouteSummary\x12\x13\n\x0bpoint_count\x18\x01 \x01(\x05\x12\x15\n\rfeature_count\x18\x02 \x01(\x05\x12\x10\n\x08\x64istance\x18\x03 \x01(\x05\x12\x14\n\x0c\x65lapsed_time\x18\x04 \x01(\x05\x32\xad\x01\n\nRouteGuide\x12 \n\nGetFeature\x12\x06.Point\x1a\x08.Feature\"\x00\x12(\n\x0cListFeatures\x12\n.Rectangle\x1a\x08.Feature\"\x00\x30\x01\x12(\n\x0bRecordRoute\x12\x06.Point\x1a\r.RouteSummary\"\x00(\x01\x12)\n\tRouteChat\x12\n.RouteNote\x1a\n.RouteNote\"\x00(\x01\x30\x01') +) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + + + + +_POINT = _descriptor.Descriptor( + name='Point', + full_name='Point', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='latitude', full_name='Point.latitude', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='longitude', full_name='Point.longitude', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=21, + serialized_end=65, +) + + +_RECTANGLE = _descriptor.Descriptor( + name='Rectangle', + full_name='Rectangle', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='lo', full_name='Rectangle.lo', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='hi', full_name='Rectangle.hi', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=67, + serialized_end=118, +) + + +_FEATURE = _descriptor.Descriptor( + name='Feature', + full_name='Feature', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='Feature.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='location', full_name='Feature.location', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=120, + serialized_end=169, +) + + +_ROUTENOTE = _descriptor.Descriptor( + name='RouteNote', + full_name='RouteNote', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='location', full_name='RouteNote.location', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='message', full_name='RouteNote.message', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=171, + serialized_end=225, +) + + +_ROUTESUMMARY = _descriptor.Descriptor( + name='RouteSummary', + full_name='RouteSummary', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='point_count', full_name='RouteSummary.point_count', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='feature_count', full_name='RouteSummary.feature_count', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='distance', full_name='RouteSummary.distance', index=2, + number=3, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='elapsed_time', full_name='RouteSummary.elapsed_time', index=3, + number=4, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=227, + serialized_end=325, +) + +_RECTANGLE.fields_by_name['lo'].message_type = _POINT +_RECTANGLE.fields_by_name['hi'].message_type = _POINT +_FEATURE.fields_by_name['location'].message_type = _POINT +_ROUTENOTE.fields_by_name['location'].message_type = _POINT +DESCRIPTOR.message_types_by_name['Point'] = _POINT +DESCRIPTOR.message_types_by_name['Rectangle'] = _RECTANGLE +DESCRIPTOR.message_types_by_name['Feature'] = _FEATURE +DESCRIPTOR.message_types_by_name['RouteNote'] = _ROUTENOTE +DESCRIPTOR.message_types_by_name['RouteSummary'] = _ROUTESUMMARY + +Point = _reflection.GeneratedProtocolMessageType('Point', (_message.Message,), dict( + DESCRIPTOR = _POINT, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:Point) + )) +_sym_db.RegisterMessage(Point) + +Rectangle = _reflection.GeneratedProtocolMessageType('Rectangle', (_message.Message,), dict( + DESCRIPTOR = _RECTANGLE, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:Rectangle) + )) +_sym_db.RegisterMessage(Rectangle) + +Feature = _reflection.GeneratedProtocolMessageType('Feature', (_message.Message,), dict( + DESCRIPTOR = _FEATURE, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:Feature) + )) +_sym_db.RegisterMessage(Feature) + +RouteNote = _reflection.GeneratedProtocolMessageType('RouteNote', (_message.Message,), dict( + DESCRIPTOR = _ROUTENOTE, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:RouteNote) + )) +_sym_db.RegisterMessage(RouteNote) + +RouteSummary = _reflection.GeneratedProtocolMessageType('RouteSummary', (_message.Message,), dict( + DESCRIPTOR = _ROUTESUMMARY, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:RouteSummary) + )) +_sym_db.RegisterMessage(RouteSummary) + + +import abc +from grpc._adapter import fore +from grpc._adapter import rear +from grpc.framework.assembly import implementations +from grpc.framework.assembly import utilities +class EarlyAdopterRouteGuideServicer(object): + """""" + __metaclass__ = abc.ABCMeta + @abc.abstractmethod + def GetFeature(self, request): + raise NotImplementedError() + @abc.abstractmethod + def ListFeatures(self, request): + raise NotImplementedError() + @abc.abstractmethod + def RecordRoute(self, request_iterator): + raise NotImplementedError() + @abc.abstractmethod + def RouteChat(self, request_iterator): + raise NotImplementedError() +class EarlyAdopterRouteGuideServer(object): + """""" + __metaclass__ = abc.ABCMeta + @abc.abstractmethod + def start(self): + raise NotImplementedError() + @abc.abstractmethod + def stop(self): + raise NotImplementedError() +class EarlyAdopterRouteGuideStub(object): + """""" + __metaclass__ = abc.ABCMeta + @abc.abstractmethod + def GetFeature(self, request): + raise NotImplementedError() + GetFeature.async = None + @abc.abstractmethod + def ListFeatures(self, request): + raise NotImplementedError() + ListFeatures.async = None + @abc.abstractmethod + def RecordRoute(self, request_iterator): + raise NotImplementedError() + RecordRoute.async = None + @abc.abstractmethod + def RouteChat(self, request_iterator): + raise NotImplementedError() + RouteChat.async = None +def early_adopter_create_RouteGuide_server(servicer, port, root_certificates, key_chain_pairs): + method_implementations = { + "GetFeature": utilities.unary_unary_inline(servicer.GetFeature), + "ListFeatures": utilities.unary_stream_inline(servicer.ListFeatures), + "RecordRoute": utilities.stream_unary_inline(servicer.RecordRoute), + "RouteChat": utilities.stream_stream_inline(servicer.RouteChat), + } + import route_guide_pb2 + import route_guide_pb2 + import route_guide_pb2 + import route_guide_pb2 + request_deserializers = { + "GetFeature": route_guide_pb2.Point.FromString, + "ListFeatures": route_guide_pb2.Rectangle.FromString, + "RecordRoute": route_guide_pb2.Point.FromString, + "RouteChat": route_guide_pb2.RouteNote.FromString, + } + response_serializers = { + "GetFeature": lambda x: x.SerializeToString(), + "ListFeatures": lambda x: x.SerializeToString(), + "RecordRoute": lambda x: x.SerializeToString(), + "RouteChat": lambda x: x.SerializeToString(), + } + link = fore.activated_fore_link(port, request_deserializers, response_serializers, root_certificates, key_chain_pairs) + return implementations.assemble_service(method_implementations, link) +def early_adopter_create_RouteGuide_stub(host, port): + method_implementations = { + "GetFeature": utilities.unary_unary_inline(None), + "ListFeatures": utilities.unary_stream_inline(None), + "RecordRoute": utilities.stream_unary_inline(None), + "RouteChat": utilities.stream_stream_inline(None), + } + import route_guide_pb2 + import route_guide_pb2 + import route_guide_pb2 + import route_guide_pb2 + response_deserializers = { + "GetFeature": route_guide_pb2.Feature.FromString, + "ListFeatures": route_guide_pb2.Feature.FromString, + "RecordRoute": route_guide_pb2.RouteSummary.FromString, + "RouteChat": route_guide_pb2.RouteNote.FromString, + } + request_serializers = { + "GetFeature": lambda x: x.SerializeToString(), + "ListFeatures": lambda x: x.SerializeToString(), + "RecordRoute": lambda x: x.SerializeToString(), + "RouteChat": lambda x: x.SerializeToString(), + } + link = rear.activated_rear_link(host, port, request_serializers, response_deserializers) + return implementations.assemble_dynamic_inline_stub(method_implementations, link) +# @@protoc_insertion_point(module_scope) diff --git a/grpc-common/python/route_guide/route_guide_resources.py b/grpc-common/python/route_guide/route_guide_resources.py new file mode 100755 index 0000000000..30c7711019 --- /dev/null +++ b/grpc-common/python/route_guide/route_guide_resources.py @@ -0,0 +1,53 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Common resources used in the gRPC route guide example.""" + +import json + +import route_guide_pb2 + + +def read_route_guide_database(): + """Reads the route guide database. + + Returns: + The full contents of the route guide database as a sequence of + route_guide_pb2.Features. + """ + feature_list = [] + with open("route_guide_db.json") as route_guide_db_file: + for item in json.load(route_guide_db_file): + feature = route_guide_pb2.Feature( + name=item["name"], + location=route_guide_pb2.Point( + latitude=item["location"]["latitude"], + longitude=item["location"]["longitude"])) + feature_list.append(feature) + return feature_list diff --git a/grpc-common/python/route_guide/route_guide_server.py b/grpc-common/python/route_guide/route_guide_server.py new file mode 100644 index 0000000000..44bbacf5f3 --- /dev/null +++ b/grpc-common/python/route_guide/route_guide_server.py @@ -0,0 +1,134 @@ +# 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. + +"""The Python implementation of the gRPC route guide server.""" + +import time +import math + +import route_guide_pb2 +import route_guide_resources + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +def get_feature(feature_db, point): + """Returns Feature at given location or None.""" + for feature in feature_db: + if feature.location == point: + return feature + return None + + +def get_distance(start, end): + """Distance between two points.""" + coord_factor = 10000000.0 + lat_1 = start.latitude / coord_factor + lat_2 = end.latitude / coord_factor + lon_1 = start.latitude / coord_factor + lon_2 = end.longitude / coord_factor + lat_rad_1 = math.radians(lat_1) + lat_rad_2 = math.radians(lat_2) + delta_lat_rad = math.radians(lat_2 - lat_1) + delta_lon_rad = math.radians(lon_2 - lon_1) + + a = (pow(math.sin(delta_lat_rad / 2), 2) + + (math.cos(lat_rad_1) * math.cos(lat_rad_2) * + pow(math.sin(delta_lon_rad / 2), 2))) + c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) + R = 6371000; # metres + return R * c; + +class RouteGuideServicer(route_guide_pb2.EarlyAdopterRouteGuideServicer): + """Provides methods that implement functionality of route guide server.""" + + def __init__(self): + self.db = route_guide_resources.read_route_guide_database() + + def GetFeature(self, request, context): + feature = get_feature(self.db, request) + if feature is None: + return route_guide_pb2.Feature(name="", location=request) + else: + return feature + + def ListFeatures(self, request, context): + left = min(request.lo.longitude, request.hi.longitude) + right = max(request.lo.longitude, request.hi.longitude) + top = max(request.lo.latitude, request.hi.latitude) + bottom = min(request.lo.latitude, request.hi.latitude) + for feature in self.db: + if (feature.location.longitude >= left and + feature.location.longitude <= right and + feature.location.latitude >= bottom and + feature.location.latitude <= top): + yield feature + + def RecordRoute(self, request_iterator, context): + point_count = 0 + feature_count = 0 + distance = 0.0 + prev_point = None + + start_time = time.time() + for point in request_iterator: + point_count += 1 + if get_feature(self.db, point): + feature_count += 1 + if prev_point: + distance += get_distance(prev_point, point) + prev_point = point + + elapsed_time = time.time() - start_time + return route_guide_pb2.RouteSummary(point_count=point_count, + feature_count=feature_count, + distance=int(distance), + elapsed_time=int(elapsed_time)) + + def RouteChat(self, request_iterator, context): + prev_notes = [] + for new_note in request_iterator: + for prev_note in prev_notes: + if prev_note.location == new_note.location: + yield prev_note + prev_notes.append(new_note) + + +def serve(): + server = route_guide_pb2.early_adopter_create_RouteGuide_server( + RouteGuideServicer(), 50051, None, None) + server.start() + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop() + +if __name__ == '__main__': + serve() diff --git a/grpc-common/python/route_guide/run_client.sh b/grpc-common/python/route_guide/run_client.sh new file mode 100755 index 0000000000..d2552c2858 --- /dev/null +++ b/grpc-common/python/route_guide/run_client.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# This is where you have cloned out the https://github.com/grpc/grpc repository +# And built gRPC Python. +# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS +GRPC_ROOT=~/github/grpc + +$GRPC_ROOT/python2.7_virtual_environment/bin/python -B route_guide_client.py diff --git a/grpc-common/python/route_guide/run_codegen.sh b/grpc-common/python/route_guide/run_codegen.sh new file mode 100755 index 0000000000..689e0978de --- /dev/null +++ b/grpc-common/python/route_guide/run_codegen.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Runs the protoc with gRPC plugin to generate protocol messages and gRPC stubs. +protoc -I . --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` route_guide.proto diff --git a/grpc-common/python/route_guide/run_server.sh b/grpc-common/python/route_guide/run_server.sh new file mode 100755 index 0000000000..8f759250c8 --- /dev/null +++ b/grpc-common/python/route_guide/run_server.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# This is where you have cloned out the https://github.com/grpc/grpc repository +# And built gRPC Python. +# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS +GRPC_ROOT=~/github/grpc + +$GRPC_ROOT/python2.7_virtual_environment/bin/python -B route_guide_server.py diff --git a/grpc-common/ruby/.gitignore b/grpc-common/ruby/.gitignore new file mode 100644 index 0000000000..62fcb4fa94 --- /dev/null +++ b/grpc-common/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/grpc-common/ruby/Gemfile b/grpc-common/ruby/Gemfile new file mode 100644 index 0000000000..65d3f0ad4a --- /dev/null +++ b/grpc-common/ruby/Gemfile @@ -0,0 +1,6 @@ +# -*- ruby -*- +# encoding: utf-8 + +source 'https://rubygems.org/' + +gem 'grpc', :git => 'https://github.com/grpc/grpc.git', :submodules => true, glob: 'src/ruby/*.gemspec' diff --git a/grpc-common/ruby/README.md b/grpc-common/ruby/README.md new file mode 100644 index 0000000000..fecd8041e0 --- /dev/null +++ b/grpc-common/ruby/README.md @@ -0,0 +1,61 @@ +gRPC in 3 minutes (Ruby) +======================== + +BACKGROUND +------------- +For this sample, we've already generated the server and client stubs from [helloworld.proto][] + +PREREQUISITES +------------- + +- Ruby 2.x +This requires Ruby 2.x, as the gRPC API surface uses keyword args. +If you don't have that installed locally, you can use [RVM][] to use Ruby 2.x for testing without upgrading the version of Ruby on your whole system. +RVM is also useful if you don't have the necessary privileges to update your system's Ruby. + + ```sh + $ # RVM installation as specified at https://rvm.io/rvm/install + $ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 + $ \curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2 + $ + $ # follow the instructions to ensure that your're using the latest stable version of Ruby + $ # and that the rvm command is installed + ``` +- *N.B* Make sure your run `source $HOME/.rvm/scripts/rvm` as instructed to complete the set-up of RVM. + +INSTALL +------- + +- Clone this repository +- Use bundler to install the example package's dependencies + + ```sh + $ # from this directory + $ gem install bundler # if you don't already have bundler available + $ bundle install + ``` + +Try it! +------- + +- Run the server + + ```sh + $ # from this directory + $ bundle exec ./greeter_server.rb & + ``` + +- Run the client + + ```sh + $ # from this directory + $ bundle exec ./greeter_client.rb + ``` + +Tutorial +-------- + +You can find a more detailed tutorial in [gRPC Basics: Ruby](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/README.md) + +[helloworld.proto]:https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto +[RVM]:https://www.rvm.io/ diff --git a/grpc-common/ruby/greeter_client.rb b/grpc-common/ruby/greeter_client.rb new file mode 100755 index 0000000000..e6cb4bad33 --- /dev/null +++ b/grpc-common/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/grpc-common/ruby/greeter_server.rb b/grpc-common/ruby/greeter_server.rb new file mode 100755 index 0000000000..d4f9cf7d0f --- /dev/null +++ b/grpc-common/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/grpc-common/ruby/grpc-demo.gemspec b/grpc-common/ruby/grpc-demo.gemspec new file mode 100644 index 0000000000..fa69eb20c1 --- /dev/null +++ b/grpc-common/ruby/grpc-demo.gemspec @@ -0,0 +1,23 @@ +# -*- ruby -*- +# encoding: utf-8 + +Gem::Specification.new do |s| + s.name = 'grpc-demo' + s.version = '0.5.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 ruby/route_guide/*.rb`.split("\n").map do |f| + File.basename(f) + end + s.require_paths = ['lib'] + s.platform = Gem::Platform::RUBY + + s.add_dependency 'grpc', '~> 0.6' + + s.add_development_dependency 'bundler', '~> 1.7' +end diff --git a/grpc-common/ruby/lib/helloworld.rb b/grpc-common/ruby/lib/helloworld.rb new file mode 100644 index 0000000000..82bdd78e2a --- /dev/null +++ b/grpc-common/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/grpc-common/ruby/lib/helloworld_services.rb b/grpc-common/ruby/lib/helloworld_services.rb new file mode 100644 index 0000000000..7da45ebc6b --- /dev/null +++ b/grpc-common/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 diff --git a/grpc-common/ruby/lib/route_guide.rb b/grpc-common/ruby/lib/route_guide.rb new file mode 100644 index 0000000000..98bac8395c --- /dev/null +++ b/grpc-common/ruby/lib/route_guide.rb @@ -0,0 +1,37 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: route_guide.proto + +require 'google/protobuf' + +Google::Protobuf::DescriptorPool.generated_pool.build do + add_message "examples.Point" do + optional :latitude, :int32, 1 + optional :longitude, :int32, 2 + end + add_message "examples.Rectangle" do + optional :lo, :message, 1, "examples.Point" + optional :hi, :message, 2, "examples.Point" + end + add_message "examples.Feature" do + optional :name, :string, 1 + optional :location, :message, 2, "examples.Point" + end + add_message "examples.RouteNote" do + optional :location, :message, 1, "examples.Point" + optional :message, :string, 2 + end + add_message "examples.RouteSummary" do + optional :point_count, :int32, 1 + optional :feature_count, :int32, 2 + optional :distance, :int32, 3 + optional :elapsed_time, :int32, 4 + end +end + +module Examples + Point = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.Point").msgclass + Rectangle = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.Rectangle").msgclass + Feature = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.Feature").msgclass + RouteNote = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.RouteNote").msgclass + RouteSummary = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.RouteSummary").msgclass +end diff --git a/grpc-common/ruby/lib/route_guide_services.rb b/grpc-common/ruby/lib/route_guide_services.rb new file mode 100644 index 0000000000..6e07653c42 --- /dev/null +++ b/grpc-common/ruby/lib/route_guide_services.rb @@ -0,0 +1,27 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# Source: route_guide.proto for package 'examples' + +require 'grpc' +require 'route_guide' + +module Examples + module RouteGuide + + # TODO: add proto service documentation here + class Service + + include GRPC::GenericService + + self.marshal_class_method = :encode + self.unmarshal_class_method = :decode + self.service_name = 'examples.RouteGuide' + + rpc :GetFeature, Point, Feature + rpc :ListFeatures, Rectangle, stream(Feature) + rpc :RecordRoute, stream(Point), RouteSummary + rpc :RouteChat, stream(RouteNote), stream(RouteNote) + end + + Stub = Service.rpc_stub_class + end +end diff --git a/grpc-common/ruby/route_guide/README.md b/grpc-common/ruby/route_guide/README.md new file mode 100644 index 0000000000..d22874799f --- /dev/null +++ b/grpc-common/ruby/route_guide/README.md @@ -0,0 +1,285 @@ +#gRPC Basics: Ruby + +This tutorial provides a basic Ruby programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate server and client code using the protocol buffer compiler. +- Use the Ruby gRPC API to write a simple client and server for your service. + +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. + +This isn't a comprehensive guide to using gRPC in Ruby: more reference documentation is coming soon. + +## Why use gRPC? + +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/ruby/route_guide](https://github.com/grpc/grpc-common/tree/master/ruby/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/ruby/route_guide`: +```shell +$ cd grpc-common/ruby/route_guide +``` + +You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Ruby quick start guide](https://github.com/grpc/grpc-common/tree/master/ruby). + + +## Defining the service + +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +```protobuf +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +```protobuf + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. +```protobuf + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} +``` + +- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. +```protobuf + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +```protobuf + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +```protobuf +// 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; +} +``` + + +## Generating client and server code + +Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC Ruby plugin. + +If you want to run this yourself, make sure you've installed protoc and followed the gRPC Ruby plugin [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): + +Once that's done, the following command can be used to generate the ruby code. + +```shell +$ protoc -I ../../protos --ruby_out=lib --grpc_out=lib --plugin=protoc-gen-grpc=`which grpc_ruby_plugin` ../../protos/route_guide.proto +``` + +Running this command regenerates the following files in the lib directory: +- `lib/route_guide.pb` defines a module `Examples::RouteGuide` + - This contain all the protocol buffer code to populate, serialize, and retrieve our request and response message types +- `lib/route_guide_services.pb`, extends `Examples::RouteGuide` with stub and service classes + - a class `Service` for use as a base class when defining RouteGuide service implementations + - a class `Stub` that can be used to access remote RouteGuide instances + + + +## Creating the server + +First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). + +There are two parts to making our `RouteGuide` service do its job: +- Implementing the service interface generated from our service definition: doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and return the service responses. + +You can find our example `RouteGuide` server in [grpc-common/ruby/route_guide/route_guide_server.rb](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/route_guide_server.rb). Let's take a closer look at how it works. + +### Implementing RouteGuide + +As you can see, our server has a `ServerImpl` class that extends the generated `RouteGuide::Service`: + +```ruby +# ServerImpl provides an implementation of the RouteGuide service. +class ServerImpl < RouteGuide::Service +``` + +`ServerImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. + +```ruby + def get_feature(point, _call) + name = @feature_db[{ + 'longitude' => point.longitude, + 'latitude' => point.latitude }] || '' + Feature.new(location: point, name: name) + end +``` + +The method is passed a _call for the RPC, the client's `Point` protocol buffer request, and returns a `Feature` protocol buffer. In the method we create the `Feature` with the appropriate information, and then `return` it. + +Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. + +```ruby +# in ServerImpl + + def list_features(rectangle, _call) + RectangleEnum.new(@feature_db, rectangle).each + end +``` + +As you can see, here the request object is a `Rectangle` in which our client wants to find `Feature`s, but instead of returning a simple response we need to return an [Enumerator](http://ruby-doc.org//core-2.2.0/Enumerator.html) that yields the responses. In the method, we use a helper class `RectangleEnum`, to act as an Enumerator implementation. + +Similarly, the client-side streaming method `record_route` uses an [Enumerable](http://ruby-doc.org//core-2.2.0/Enumerable.html), but here it's obtained from the call object, which we've ignored in the earlier examples. `call.each_remote_read` yields each message sent by the client in turn. + +```ruby + call.each_remote_read do |point| + ... + end +``` +Finally, let's look at our bidirectional streaming RPC `route_chat`. + +```ruby + def route_chat(notes) + q = EnumeratorQueue.new(self) + t = Thread.new do + begin + notes.each do |n| + ... + end + end + q = EnumeratorQueue.new(self) + ... + return q.each_item + end +``` + +Here the method receives an [Enumerable](http://ruby-doc.org//core-2.2.0/Enumerable.html), but also returns an [Enumerator](http://ruby-doc.org//core-2.2.0/Enumerator.html) that yields the responses. The implementation demonstrates how to set these up so that the requests and responses can be handled concurrently. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + +### Starting the server + +Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: + +```ruby + s = GRPC::RpcServer.new + s.add_http2_port(port) + logger.info("... running insecurely on #{port}") + s.handle(ServerImpl.new(feature_db)) + s.run +``` +As you can see, we build and start our server using a `GRPC::RpcServer`. To do this, we: + +1. Create an instance of our service implementation class `ServerImpl`. +2. Specify the address and port we want to use to listen for client requests using the builder's `add_http2_port` method. +3. Register our service implementation with the `GRPC::RpcServer`. +4. Call `run` on the`GRPC::RpcServer` to create and start an RPC server for our service. + + +## Creating the client + +In this section, we'll look at creating a Ruby client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/ruby/route_guide/route_guide_client.rb](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/route_guide_client.rb). + +### Creating a stub + +To call service methods, we first need to create a *stub*. + +We use the `Stub` class of the `RouteGuide` module generated from our .proto. + +```ruby + stub = RouteGuide::Stub.new('localhost:50051') +``` + +### Calling service methods + +Now let's look at how we call our service methods. Note that the gRPC Ruby only provides *blocking/synchronous* versions of each method: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception. + +#### Simple RPC + +Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. + +```ruby +GET_FEATURE_POINTS = [ + Point.new(latitude: 409_146_138, longitude: -746_188_906), + Point.new(latitude: 0, longitude: 0) +] +.. + GET_FEATURE_POINTS.each do |pt| + resp = stub.get_feature(pt) + ... + p "- found '#{resp.name}' at #{pt.inspect}" + end +``` + +As you can see, we create and populate a request protocol buffer object (in our case `Point`), and create a response protocol buffer object for the server to fill in. Finally, we call the method on the stub, passing it the context, request, and response. If the method returns `OK`, then we can read the response information from the server from our response object. + + +#### Streaming RPCs + +Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `list_features`, which returns an `Enumerable` of `Features` + +```ruby + resps = stub.list_features(LIST_FEATURES_RECT) + resps.each do |r| + p "- found '#{r.name}' at #{r.location.inspect}" + end +``` + +The client-side streaming method `record_route` is similar, except there we pass the server an `Enumerable`. + +```ruby + ... + reqs = RandomRoute.new(features, points_on_route) + resp = stub.record_route(reqs.each, deadline) + ... +``` + +Finally, let's look at our bidirectional streaming RPC `route_chat`. In this case, we pass `Enumerable` to the method and get back an `Enumerable`. + +```ruby + resps = stub.route_chat(ROUTE_CHAT_NOTES) + resps.each { |r| p "received #{r.inspect}" } +``` + +Although it's not shown well by this example, each enumerable is independent of the other - both the client and server can read and write in any order — the streams operate completely independently. + +## Try it out! + +Build client and server: + +```shell +$ # from grpc-common/ruby +$ gem install bundler && bundle install +``` +Run the server, which will listen on port 50051: +```shell +$ # from grpc-common/ruby +$ bundle exec route_guide/route_guide_server.rb ../node/route_guide/route_guide_db.json & +``` +Run the client (in a different terminal): +```shell +$ # from grpc-common/ruby +$ bundle exec route_guide/route_guide_client.rb ../node/route_guide/route_guide_db.json & +``` + diff --git a/grpc-common/ruby/route_guide/route_guide_client.rb b/grpc-common/ruby/route_guide/route_guide_client.rb new file mode 100755 index 0000000000..181623a68a --- /dev/null +++ b/grpc-common/ruby/route_guide/route_guide_client.rb @@ -0,0 +1,165 @@ +#!/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 Route Guide service. +# +# Usage: $ path/to/route_guide_client.rb path/to/route_guide_db.json & + +this_dir = File.expand_path(File.dirname(__FILE__)) +lib_dir = File.join(File.dirname(this_dir), 'lib') +$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) + +require 'grpc' +require 'route_guide_services' + +include Examples + +GET_FEATURE_POINTS = [ + Point.new(latitude: 409_146_138, longitude: -746_188_906), + Point.new(latitude: 0, longitude: 0) +] + +# runs a GetFeature rpc. +# +# - once with a point known to be present in the sample route database +# - once with a point that is not in the sample database +def run_get_feature(stub) + p 'GetFeature' + p '----------' + GET_FEATURE_POINTS.each do |pt| + resp = stub.get_feature(pt) + if resp.name != '' + p "- found '#{resp.name}' at #{pt.inspect}" + else + p "- found nothing at #{pt.inspect}" + end + end +end + +LIST_FEATURES_RECT = Rectangle.new( + lo: Point.new(latitude: 400_000_000, longitude: -750_000_000), + hi: Point.new(latitude: 420_000_000, longitude: -730_000_000)) + +# runs a ListFeatures rpc. +# +# - the rectangle to chosen to include most of the known features +# in the sample db. +def run_list_features(stub) + p 'ListFeatures' + p '------------' + resps = stub.list_features(LIST_FEATURES_RECT) + resps.each do |r| + p "- found '#{r.name}' at #{r.location.inspect}" + end +end + +# RandomRoute provides an Enumerable that yields a random 'route' of points +# from a list of Features. +class RandomRoute + def initialize(features, size) + @features = features + @size = size + end + + # yields a point, waiting between 0 and 1 seconds between each yield + # + # @return an Enumerable that yields a random point + def each + return enum_for(:each) unless block_given? + @size.times do + json_feature = @features[rand(0..@features.length)] + next if json_feature.nil? + location = json_feature['location'] + pt = Point.new( + Hash[location.each_pair.map { |k, v| [k.to_sym, v] }]) + p "- next point is #{pt.inspect}" + yield pt + sleep(rand(0..1)) + end + end +end + +# runs a RecordRoute rpc. +# +# - the rectangle to chosen to include most of the known features +# in the sample db. +def run_record_route(stub, features) + p 'RecordRoute' + p '-----------' + points_on_route = 10 # arbitrary + deadline = points_on_route # as delay b/w each is max 1 second + reqs = RandomRoute.new(features, points_on_route) + resp = stub.record_route(reqs.each, deadline) + p "summary: #{resp.inspect}" +end + +ROUTE_CHAT_NOTES = [ + RouteNote.new(message: 'doh - a deer', + location: Point.new(latitude: 0, longitude: 0)), + RouteNote.new(message: 'ray - a drop of golden sun', + location: Point.new(latitude: 0, longitude: 1)), + RouteNote.new(message: 'me - the name I call myself', + location: Point.new(latitude: 1, longitude: 0)), + RouteNote.new(message: 'fa - a longer way to run', + location: Point.new(latitude: 1, longitude: 1)), + RouteNote.new(message: 'soh - with needle and a thread', + location: Point.new(latitude: 0, longitude: 1)) +] + +# runs a RouteChat rpc. +# +# sends a canned set of route notes and prints out the responses. +def run_route_chat(stub) + p 'Route Chat' + p '----------' + # TODO: decouple sending and receiving, i.e have the response enumerator run + # on its own thread. + resps = stub.route_chat(ROUTE_CHAT_NOTES) + resps.each { |r| p "received #{r.inspect}" } +end + +def main + stub = RouteGuide::Stub.new('localhost:50051') + run_get_feature(stub) + run_list_features(stub) + run_route_chat(stub) + if ARGV.length == 0 + p 'no feature database; skipping record_route' + exit + end + raw_data = [] + File.open(ARGV[0]) do |f| + raw_data = MultiJson.load(f.read) + end + run_record_route(stub, raw_data) +end + +main diff --git a/grpc-common/ruby/route_guide/route_guide_server.rb b/grpc-common/ruby/route_guide/route_guide_server.rb new file mode 100755 index 0000000000..2b2b8084ef --- /dev/null +++ b/grpc-common/ruby/route_guide/route_guide_server.rb @@ -0,0 +1,211 @@ +#!/usr/bin/env ruby +# -*- coding: utf-8 -*- + +# 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 Route Guide service. +# +# Usage: $ path/to/route_guide_server.rb path/to/route_guide_db.json & + +this_dir = File.expand_path(File.dirname(__FILE__)) +lib_dir = File.join(File.dirname(this_dir), 'lib') +$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) + +require 'grpc' +require 'multi_json' +require 'route_guide_services' + +include Examples +COORD_FACTOR = 1e7 +RADIUS = 637_100 + +# Determines the distance between two points. +def calculate_distance(point_a, point_b) + to_radians = proc { |x| x * Math::PI / 180 } + lat_a = point_a.latitude / COORD_FACTOR + lat_b = point_b.latitude / COORD_FACTOR + long_a = point_a.longitude / COORD_FACTOR + long_b = point_b.longitude / COORD_FACTOR + φ1 = to_radians.call(lat_a) + φ2 = to_radians.call(lat_b) + Δφ = to_radians.call(lat_a - lat_b) + Δλ = to_radians.call(long_a - long_b) + a = Math.sin(Δφ / 2)**2 + + Math.cos(φ1) * Math.cos(φ2) + + Math.sin(Δλ / 2)**2 + (2 * RADIUS * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))).to_i +end + +# RectangleEnum provides an Enumerator of the points in a feature_db within a +# given Rectangle. +class RectangleEnum + # @param [Hash] feature_db + # @param [Rectangle] bounds + def initialize(feature_db, bounds) + @feature_db = feature_db + @bounds = bounds + lats = [@bounds.lo.latitude, @bounds.hi.latitude] + longs = [@bounds.lo.longitude, @bounds.hi.longitude] + @lo_lat, @hi_lat = lats.min, lats.max + @lo_long, @hi_long = longs.min, longs.max + end + + # in? determines if location lies within the bounds of this instances + # Rectangle. + def in?(location) + location['longitude'] >= @lo_long && + location['longitude'] <= @hi_long && + location['latitude'] >= @lo_lat && + location['latitude'] <= @hi_lat + end + + # each yields the features in the instances feature_db that lie within the + # instance rectangle. + def each + return enum_for(:each) unless block_given? + @feature_db.each_pair do |location, name| + next unless in?(location) + next if name.nil? || name == '' + pt = Point.new( + Hash[location.each_pair.map { |k, v| [k.to_sym, v] }]) + yield Feature.new(location: pt, name: name) + end + end +end + +# A EnumeratorQueue wraps a Queue to yield the items added to it. +class EnumeratorQueue + extend Forwardable + def_delegators :@q, :push + + def initialize(sentinel) + @q = Queue.new + @sentinel = sentinel + @received_notes = {} + end + + def each_item + return enum_for(:each_item) unless block_given? + loop do + r = @q.pop + break if r.equal?(@sentinel) + fail r if r.is_a? Exception + yield r + end + end +end + +# ServerImpl provides an implementation of the RouteGuide service. +class ServerImpl < RouteGuide::Service + # @param [Hash] feature_db {location => name} + def initialize(feature_db) + @feature_db = feature_db + @received_notes = Hash.new { |h, k| h[k] = [] } + end + + def get_feature(point, _call) + name = @feature_db[{ + 'longitude' => point.longitude, + 'latitude' => point.latitude }] || '' + Feature.new(location: point, name: name) + end + + def list_features(rectangle, _call) + RectangleEnum.new(@feature_db, rectangle).each + end + + def record_route(call) + started, elapsed_time = 0, 0 + distance, count, features, last = 0, 0, 0, nil + call.each_remote_read do |point| + count += 1 + name = @feature_db[{ + 'longitude' => point.longitude, + 'latitude' => point.latitude }] || '' + features += 1 unless name == '' + if last.nil? + last = point + started = Time.now.to_i + next + end + elapsed_time = Time.now.to_i - started + distance += calculate_distance(point, last) + last = point + end + RouteSummary.new(point_count: count, + feature_count: features, + distance: distance, + elapsed_time: elapsed_time) + end + + def route_chat(notes) + q = EnumeratorQueue.new(self) + # run a separate thread that processes the incoming requests + t = Thread.new do + begin + notes.each do |n| + key = { + 'latitude' => n.location.latitude, + 'longitude' => n.location.longitude + } + earlier_msgs = @received_notes[key] + @received_notes[key] << n.message + # send back the earlier messages at this point + earlier_msgs.each do |r| + q.push(RouteNote.new(location: n.location, message: r)) + end + end + q.push(self) # signal completion + rescue StandardError => e + q.push(e) # signal completion via an error + end + end + q.each_item + end +end + +def main + if ARGV.length == 0 + fail 'Please specify the path to the route_guide json database' + end + raw_data = [] + File.open(ARGV[0]) do |f| + raw_data = MultiJson.load(f.read) + end + feature_db = Hash[raw_data.map { |x| [x['location'], x['name']] }] + port = '0.0.0.0:50051' + s = GRPC::RpcServer.new + s.add_http2_port(port) + GRPC.logger.info("... running insecurely on #{port}") + s.handle(ServerImpl.new(feature_db)) + s.run +end + +main diff --git a/java/android/.gitignore b/java/android/.gitignore deleted file mode 100644 index 6345b76a48..0000000000 --- a/java/android/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -.gradle -/local.properties -/gradle.properties -/.idea/workspace.xml -/.idea/libraries -.DS_Store -/build -.idea/ - -*.iml -*.apk -*.ap_ -*.dex -*.class -bin/ -gen/ -.gradle/ -/*/build/ -local.properties -proguard/ -*.log diff --git a/java/android/README.md b/java/android/README.md deleted file mode 100644 index 9de65a0267..0000000000 --- a/java/android/README.md +++ /dev/null @@ -1,41 +0,0 @@ -gRPC Hello World Tutorial (Android Java) -======================== - -BACKGROUND -------------- -For this sample, we've already generated the server and client stubs from [helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). - -PREREQUISITES -------------- -- [Java gRPC](https://github.com/grpc/grpc-java) - -- [Android Tutorial](https://developer.android.com/training/basics/firstapp/index.html) if you're new to Android development - -- We only have Android gRPC client in this example. Please follow examples in other languages to build and run a gRPC server. - -INSTALL -------- -**1 Clone the gRPC Java git repo** -```sh -$ git clone https://github.com/grpc/grpc-java -``` - -**2 Install gRPC Java, as described in [How to Build](https://github.com/grpc/grpc-java#how-to-build)** -```sh -$ # from this dir -$ cd grpc-java -$ # follow the instructions in 'How to Build' -``` - -**3 Prepare the app** -- Clone this git repo -```sh -$ git clone https://github.com/grpc/grpc-common - -``` - -**4 Install the app** -```sh -$ cd grpc-common/java/android -$ ./gradlew installDebug -``` diff --git a/java/android/app/.gitignore b/java/android/app/.gitignore deleted file mode 100644 index 796b96d1c4..0000000000 --- a/java/android/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/java/android/app/build.gradle b/java/android/app/build.gradle deleted file mode 100644 index aedf4fe92a..0000000000 --- a/java/android/app/build.gradle +++ /dev/null @@ -1,34 +0,0 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion 21 - buildToolsVersion "21.1.2" - - defaultConfig { - applicationId "io.grpc.helloworldexample" - minSdkVersion 7 - targetSdkVersion 21 - versionCode 1 - versionName "1.0" - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } -} - -dependencies { - compile 'com.android.support:appcompat-v7:21.0.3' - compile 'com.google.code.findbugs:jsr305:3.0.0' - compile 'com.squareup.okhttp:okhttp:2.2.0' - compile 'com.google.guava:guava:18.0' - - // You need to build the https://github.com/grpc/grpc-java - // to obtain these libraries below. - compile 'io.grpc:grpc-core:0.1.0-SNAPSHOT' - compile 'io.grpc:grpc-protobuf-nano:0.1.0-SNAPSHOT' - compile 'io.grpc:grpc-okhttp:0.1.0-SNAPSHOT' - compile 'io.grpc:grpc-stub:0.1.0-SNAPSHOT' -} diff --git a/java/android/app/proguard-rules.pro b/java/android/app/proguard-rules.pro deleted file mode 100644 index 3e659b91f3..0000000000 --- a/java/android/app/proguard-rules.pro +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /Users/thagikura/android-sdk/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/java/android/app/src/main/AndroidManifest.xml b/java/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index 8c40f11684..0000000000 --- a/java/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/java/android/app/src/main/java/io/grpc/helloworldexample/GreeterGrpc.java b/java/android/app/src/main/java/io/grpc/helloworldexample/GreeterGrpc.java deleted file mode 100644 index 817c9fde8f..0000000000 --- a/java/android/app/src/main/java/io/grpc/helloworldexample/GreeterGrpc.java +++ /dev/null @@ -1,179 +0,0 @@ -package io.grpc.helloworldexample; - -import java.io.IOException; - -import static io.grpc.stub.Calls.asyncUnaryCall; -import static io.grpc.stub.Calls.blockingUnaryCall; -import static io.grpc.stub.Calls.createMethodDescriptor; -import static io.grpc.stub.Calls.unaryFutureCall; -import static io.grpc.stub.ServerCalls.asyncUnaryRequestCall; -import static io.grpc.stub.ServerCalls.createMethodDefinition; - -public class GreeterGrpc { - - private static final io.grpc.stub.Method METHOD_SAY_HELLO = - io.grpc.stub.Method.create( - io.grpc.MethodType.UNARY, "SayHello", - io.grpc.protobuf.nano.NanoUtils.marshaller( - new io.grpc.protobuf.nano.Parser() { - @Override - public Helloworld.HelloRequest parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { - return Helloworld.HelloRequest.parseFrom(input); - } - }), - io.grpc.protobuf.nano.NanoUtils.marshaller( - new io.grpc.protobuf.nano.Parser() { - @Override - public Helloworld.HelloReply parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { - return Helloworld.HelloReply.parseFrom(input); - } - })); - - public static GreeterStub newStub(io.grpc.Channel channel) { - return new GreeterStub(channel, CONFIG); - } - - public static GreeterBlockingStub newBlockingStub( - io.grpc.Channel channel) { - return new GreeterBlockingStub(channel, CONFIG); - } - - public static GreeterFutureStub newFutureStub( - io.grpc.Channel channel) { - return new GreeterFutureStub(channel, CONFIG); - } - - public static final GreeterServiceDescriptor CONFIG = - new GreeterServiceDescriptor(); - - public static class GreeterServiceDescriptor extends - io.grpc.stub.AbstractServiceDescriptor { - public final io.grpc.MethodDescriptor sayHello; - - private GreeterServiceDescriptor() { - sayHello = createMethodDescriptor( - "helloworld.Greeter", METHOD_SAY_HELLO); - } - - private GreeterServiceDescriptor( - java.util.Map> methodMap) { - sayHello = (io.grpc.MethodDescriptor) methodMap.get( - CONFIG.sayHello.getName()); - } - - @java.lang.Override - protected GreeterServiceDescriptor build( - java.util.Map> methodMap) { - return new GreeterServiceDescriptor(methodMap); - } - - @java.lang.Override - public com.google.common.collect.ImmutableList> methods() { - return com.google.common.collect.ImmutableList.>of( - sayHello); - } - } - - public static interface Greeter { - - public void sayHello(Helloworld.HelloRequest request, - io.grpc.stub.StreamObserver responseObserver); - } - - public static interface GreeterBlockingClient { - - public Helloworld.HelloReply sayHello(Helloworld.HelloRequest request); - } - - public static interface GreeterFutureClient { - - public com.google.common.util.concurrent.ListenableFuture sayHello( - Helloworld.HelloRequest request); - } - - public static class GreeterStub extends - io.grpc.stub.AbstractStub - implements Greeter { - private GreeterStub(io.grpc.Channel channel, - GreeterServiceDescriptor config) { - super(channel, config); - } - - @java.lang.Override - protected GreeterStub build(io.grpc.Channel channel, - GreeterServiceDescriptor config) { - return new GreeterStub(channel, config); - } - - @java.lang.Override - public void sayHello(Helloworld.HelloRequest request, - io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( - channel.newCall(config.sayHello), request, responseObserver); - } - } - - public static class GreeterBlockingStub extends - io.grpc.stub.AbstractStub - implements GreeterBlockingClient { - private GreeterBlockingStub(io.grpc.Channel channel, - GreeterServiceDescriptor config) { - super(channel, config); - } - - @java.lang.Override - protected GreeterBlockingStub build(io.grpc.Channel channel, - GreeterServiceDescriptor config) { - return new GreeterBlockingStub(channel, config); - } - - @java.lang.Override - public Helloworld.HelloReply sayHello(Helloworld.HelloRequest request) { - return blockingUnaryCall( - channel.newCall(config.sayHello), request); - } - } - - public static class GreeterFutureStub extends - io.grpc.stub.AbstractStub - implements GreeterFutureClient { - private GreeterFutureStub(io.grpc.Channel channel, - GreeterServiceDescriptor config) { - super(channel, config); - } - - @java.lang.Override - protected GreeterFutureStub build(io.grpc.Channel channel, - GreeterServiceDescriptor config) { - return new GreeterFutureStub(channel, config); - } - - @java.lang.Override - public com.google.common.util.concurrent.ListenableFuture sayHello( - Helloworld.HelloRequest request) { - return unaryFutureCall( - channel.newCall(config.sayHello), request); - } - } - - public static io.grpc.ServerServiceDefinition bindService( - final Greeter serviceImpl) { - return io.grpc.ServerServiceDefinition.builder("helloworld.Greeter") - .addMethod(createMethodDefinition( - METHOD_SAY_HELLO, - asyncUnaryRequestCall( - new io.grpc.stub.ServerCalls.UnaryRequestMethod< - Helloworld.HelloRequest, - Helloworld.HelloReply>() { - @java.lang.Override - public void invoke( - Helloworld.HelloRequest request, - io.grpc.stub.StreamObserver responseObserver) { - serviceImpl.sayHello(request, responseObserver); - } - }))).build(); - } -} diff --git a/java/android/app/src/main/java/io/grpc/helloworldexample/Helloworld.java b/java/android/app/src/main/java/io/grpc/helloworldexample/Helloworld.java deleted file mode 100644 index 28da5a91d3..0000000000 --- a/java/android/app/src/main/java/io/grpc/helloworldexample/Helloworld.java +++ /dev/null @@ -1,175 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! - -package io.grpc.helloworldexample; - -@SuppressWarnings("hiding") -public interface Helloworld { - - public static final class HelloRequest extends - com.google.protobuf.nano.MessageNano { - - private static volatile HelloRequest[] _emptyArray; - public static HelloRequest[] emptyArray() { - // Lazily initializes the empty array - if (_emptyArray == null) { - synchronized ( - com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { - if (_emptyArray == null) { - _emptyArray = new HelloRequest[0]; - } - } - } - return _emptyArray; - } - - // optional string name = 1; - public java.lang.String name; - - public HelloRequest() { - clear(); - } - - public HelloRequest clear() { - name = ""; - cachedSize = -1; - return this; - } - - @Override - public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) - throws java.io.IOException { - if (!this.name.equals("")) { - output.writeString(1, this.name); - } - super.writeTo(output); - } - - @Override - protected int computeSerializedSize() { - int size = super.computeSerializedSize(); - if (!this.name.equals("")) { - size += com.google.protobuf.nano.CodedOutputByteBufferNano - .computeStringSize(1, this.name); - } - return size; - } - - @Override - public HelloRequest mergeFrom( - com.google.protobuf.nano.CodedInputByteBufferNano input) - throws java.io.IOException { - while (true) { - int tag = input.readTag(); - switch (tag) { - case 0: - return this; - default: { - if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { - return this; - } - break; - } - case 10: { - this.name = input.readString(); - break; - } - } - } - } - - public static HelloRequest parseFrom(byte[] data) - throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { - return com.google.protobuf.nano.MessageNano.mergeFrom(new HelloRequest(), data); - } - - public static HelloRequest parseFrom( - com.google.protobuf.nano.CodedInputByteBufferNano input) - throws java.io.IOException { - return new HelloRequest().mergeFrom(input); - } - } - - public static final class HelloReply extends - com.google.protobuf.nano.MessageNano { - - private static volatile HelloReply[] _emptyArray; - public static HelloReply[] emptyArray() { - // Lazily initializes the empty array - if (_emptyArray == null) { - synchronized ( - com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { - if (_emptyArray == null) { - _emptyArray = new HelloReply[0]; - } - } - } - return _emptyArray; - } - - // optional string message = 1; - public java.lang.String message; - - public HelloReply() { - clear(); - } - - public HelloReply clear() { - message = ""; - cachedSize = -1; - return this; - } - - @Override - public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) - throws java.io.IOException { - if (!this.message.equals("")) { - output.writeString(1, this.message); - } - super.writeTo(output); - } - - @Override - protected int computeSerializedSize() { - int size = super.computeSerializedSize(); - if (!this.message.equals("")) { - size += com.google.protobuf.nano.CodedOutputByteBufferNano - .computeStringSize(1, this.message); - } - return size; - } - - @Override - public HelloReply mergeFrom( - com.google.protobuf.nano.CodedInputByteBufferNano input) - throws java.io.IOException { - while (true) { - int tag = input.readTag(); - switch (tag) { - case 0: - return this; - default: { - if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { - return this; - } - break; - } - case 10: { - this.message = input.readString(); - break; - } - } - } - } - - public static HelloReply parseFrom(byte[] data) - throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { - return com.google.protobuf.nano.MessageNano.mergeFrom(new HelloReply(), data); - } - - public static HelloReply parseFrom( - com.google.protobuf.nano.CodedInputByteBufferNano input) - throws java.io.IOException { - return new HelloReply().mergeFrom(input); - } - } -} \ No newline at end of file diff --git a/java/android/app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java b/java/android/app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java deleted file mode 100644 index b6d734f9a9..0000000000 --- a/java/android/app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java +++ /dev/null @@ -1,90 +0,0 @@ -package io.grpc.helloworldexample; - -import android.content.Context; -import android.os.AsyncTask; -import android.os.Bundle; -import android.support.v7.app.ActionBarActivity; -import android.text.TextUtils; -import android.view.View; -import android.view.inputmethod.InputMethodManager; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TextView; - -import java.util.concurrent.TimeUnit; - -import io.grpc.ChannelImpl; -import io.grpc.helloworldexample.Helloworld.HelloReply; -import io.grpc.helloworldexample.Helloworld.HelloRequest; -import io.grpc.transport.okhttp.OkHttpChannelBuilder; - -public class HelloworldActivity extends ActionBarActivity { - private Button mSendButton; - private EditText mHostEdit; - private EditText mPortEdit; - private EditText mMessageEdit; - private TextView mResultText; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_helloworld); - mSendButton = (Button) findViewById(R.id.send_button); - mHostEdit = (EditText) findViewById(R.id.host_edit_text); - mPortEdit = (EditText) findViewById(R.id.port_edit_text); - mMessageEdit = (EditText) findViewById(R.id.message_edit_text); - mResultText = (TextView) findViewById(R.id.grpc_response_text); - } - - public void sendMessage(View view) { - ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)) - .hideSoftInputFromWindow(mHostEdit.getWindowToken(), 0); - mSendButton.setEnabled(false); - new GrpcTask().execute(); - } - - private class GrpcTask extends AsyncTask { - private String mHost; - private String mMessage; - private int mPort; - private ChannelImpl mChannel; - - @Override - protected void onPreExecute() { - mHost = mHostEdit.getText().toString(); - mMessage = mMessageEdit.getText().toString(); - String portStr = mPortEdit.getText().toString(); - mPort = TextUtils.isEmpty(portStr) ? 0 : Integer.valueOf(portStr); - mResultText.setText(""); - } - - private String sayHello(ChannelImpl channel) { - GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel); - HelloRequest message = new HelloRequest(); - message.name = mMessage; - HelloReply reply = stub.sayHello(message); - return reply.message; - } - - @Override - protected String doInBackground(Void... nothing) { - try { - mChannel = OkHttpChannelBuilder.forAddress(mHost, mPort).build(); - return sayHello(mChannel); - } catch (Exception e) { - return "Failed... : " + e.getMessage(); - } - } - - @Override - protected void onPostExecute(String result) { - try { - mChannel.shutdown().awaitTerminated(1, TimeUnit.SECONDS); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - mResultText.setText(result); - mSendButton.setEnabled(true); - } - } -} \ No newline at end of file diff --git a/java/android/app/src/main/res/layout/activity_helloworld.xml b/java/android/app/src/main/res/layout/activity_helloworld.xml deleted file mode 100644 index 00ca04ce65..0000000000 --- a/java/android/app/src/main/res/layout/activity_helloworld.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/objective-c/auth_sample/Misc/GoogleService-Info.plist b/objective-c/auth_sample/Misc/GoogleService-Info.plist deleted file mode 100644 index 86909d84a3..0000000000 --- a/objective-c/auth_sample/Misc/GoogleService-Info.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - CLIENT_ID - 15087385131-lh9bpkiai9nls53uadju0if6k7un3uih.apps.googleusercontent.com - REVERSED_CLIENT_ID - com.googleusercontent.apps.15087385131-lh9bpkiai9nls53uadju0if6k7un3uih - - \ No newline at end of file diff --git a/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json b/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 36d2c80d88..0000000000 --- a/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json b/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json deleted file mode 100644 index 33a745102c..0000000000 --- a/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "first.pdf" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf b/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf deleted file mode 100644 index 47d911dea6..0000000000 Binary files a/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf and /dev/null differ diff --git a/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json b/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json deleted file mode 100644 index 03bd9c927f..0000000000 --- a/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "second.pdf" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf b/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf deleted file mode 100644 index 401614e288..0000000000 Binary files a/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf and /dev/null differ diff --git a/objective-c/auth_sample/Misc/Info.plist b/objective-c/auth_sample/Misc/Info.plist deleted file mode 100644 index fc292507c7..0000000000 --- a/objective-c/auth_sample/Misc/Info.plist +++ /dev/null @@ -1,80 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - io.grpc.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleURLTypes - - - CFBundleTypeRole - Editor - CFBundleURLName - REVERSED_CLIENT_ID - CFBundleURLSchemes - - com.googleusercontent.apps.15087385131-lh9bpkiai9nls53uadju0if6k7un3uih - - - - CFBundleTypeRole - Editor - CFBundleURLName - BUNDLE_ID - CFBundleURLSchemes - - io.grpc.AuthSample - - - - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - Main - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarTintParameters - - UINavigationBar - - Style - UIBarStyleDefault - Translucent - - - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/objective-c/auth_sample/Misc/main.m b/objective-c/auth_sample/Misc/main.m deleted file mode 100644 index 81e9d44e54..0000000000 --- a/objective-c/auth_sample/Misc/main.m +++ /dev/null @@ -1,41 +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. - * - */ - -#import -#import "AppDelegate.h" - -int main(int argc, char * argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/objective-c/auth_sample/Podfile b/objective-c/auth_sample/Podfile deleted file mode 100644 index dd4fd558c0..0000000000 --- a/objective-c/auth_sample/Podfile +++ /dev/null @@ -1,10 +0,0 @@ -source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '8.0' - -target 'AuthSample' do - # Depend on the generated AuthTestService library. - pod 'AuthTestService', :path => '.' - - # Depend on Google's OAuth2 library - pod 'Google/SignIn' -end diff --git a/objective-c/auth_sample/README.md b/objective-c/auth_sample/README.md deleted file mode 100644 index 4ca4982f53..0000000000 --- a/objective-c/auth_sample/README.md +++ /dev/null @@ -1,189 +0,0 @@ -#OAuth2 on gRPC: Objective-C - -This example application demostrates how to use OAuth2 on gRPC to make authenticated API calls on -behalf of a user. By walking through it you'll learn how to use the Objective-C gRPC API to: - -- Initialize and configure a remote call object before the RPC is started. -- Set request metadata elements on a call, which are semantically equivalent to HTTP request -headers. -- Read response metadata from a call, which is equivalent to HTTP response headers and trailers. - -It assumes you know the basics on how to make gRPC API calls using the Objective-C client library, -as shown in the [Hello World](https://github.com/grpc/grpc-common/tree/master/objective-c/helloworld) -or [Route Guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide) tutorials, -and are familiar with OAuth2 concepts like _access token_. - -- [Example code and setup](#setup) -- [Try it out!](#try) -- [Create an RPC object and start it later](#rpc-object) -- [Set request metadata of a call: Authorization header with an access token](#request-metadata) -- [Get response metadata of a call: Auth challenge header](#response-metadata) - - -## Example code and setup - -The example code for our tutorial is in [grpc/grpc-common/objective-c/auth_sample](https://github.com/grpc/grpc-common/tree/master/objective-c/auth_sample). -To download the example, clone the `grpc-common` repository by running the following command: -```shell -$ git clone https://github.com/grpc/grpc-common.git -``` - -Then change your current directory to `grpc-common/objective-c/auth_sample`: -```shell -$ cd grpc-common/objective-c/auth_sample -``` - -Our example is a simple application with two views. The first one lets a user sign in and out using -the OAuth2 flow of Google's [iOS SignIn library](https://developers.google.com/identity/sign-in/ios/). -(Google's library is used in this example because the test gRPC service we are going to call expects -Google account credentials, but neither gRPC nor the Objective-C client library is tied to any -specific OAuth2 provider). The second view makes a gRPC request to the test server, using the -access token obtained by the first view. - -Note: OAuth2 libraries need the application to register and obtain an ID from the identity provider -(in the case of this example app, Google). The app's XCode project is configured using that ID, so -you shouldn't copy this project "as is" for your own app: it would result in your app being -identified in the consent screen as "gRPC-AuthSample", and not having access to real Google -services. Instead, configure your own XCode project following the [instructions here](https://developers.google.com/identity/sign-in/ios/). - -As with the other examples, you also should have [Cocoapods](https://cocoapods.org/#install) -installed, as well as the relevant tools to generate the client library code. You can obtain the -latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). - - - -## Try it out! - -To try the sample app, first have Cocoapods generate and install the client library for our .proto -files: - -```shell -$ pod install -``` - -(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet -on your computer's cache). - -Finally, open the XCode workspace created by Cocoapods, and run the app. - -The first view, `SelectUserViewController.h/m`, asks you to sign in with your Google account, and to -give the "gRPC-AuthSample" app the following permissions: - -- View your email address. -- View your basic profile info. -- "Test scope for access to the Zoo service". - -This last permission, corresponding to the scope `https://www.googleapis.com/auth/xapi.zoo` doesn't -grant any real capability: it's only used for testing. You can log out at any time. - -The second view, `MakeRPCViewController.h/m`, makes a gRPC request to a test server at -https://grpc-test.sandbox.google.com, sending the access token along with the request. The test -service simply validates the token and writes in its response which user it belongs to, and which -scopes it gives access to. (The client application already knows those two values; it's a way to -verify that everything went as expected). - -The next sections guide you step-by-step through how the gRPC call in `MakeRPCViewController` is -performed. - - -## Create an RPC object and start it later - -The other basic tutorials show how to invoke an RPC by calling an asynchronous method in a generated -client object. This shows how to initialize an object that represents the RPC, and configure it -before starting the network request. - -Assume you have a proto service definition like this: - -```protobuf -option objc_class_prefix = "AUTH"; - -service TestService { - rpc UnaryCall(Request) returns (Response); -} -``` - -A `unaryCallWithRequest:handler:` method, with which you're already familiar, is generated for the -`AUTHTestService` class: - -```objective-c -[client unaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { - ... -}]; -``` - -In addition, an `RPCToUnaryCallWithRequest:handler:` method is generated, which returns a -not-yet-started RPC object: - -```objective-c -#import - -ProtoRPC *call = - [client RPCToUnaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { - ... - }]; -``` - -The RPC represented by this object can be started at any later time like this: - -```objective-c -[call start]; -``` - - -## Set request metadata of a call: Authorization header with an access token - -The `ProtoRPC` class has a `requestMetadata` property (inherited from `GRPCCall`) defined like this: - -```objective-c -- (NSMutableDictionary *)requestMetadata; // nonatomic -- (void)setRequestMetadata:(NSDictionary *)requestMetadata; // nonatomic, copy -``` - -Setting it to a dictionary of metadata keys and values will have them sent on the wire when the call -is started. gRPC metadata are pieces of information about the call sent by the client to the server -(and vice versa). They take the form of key-value pairs and are essentially opaque to gRPC itself. - -```objective-c -call.requestMetadata = @{@"My-Header": @"Value for this header", - @"Another-Header": @"Its value"}; -``` - -For convenience, the property is initialized with an empty `NSMutableDictionary`, so that request -metadata elements can be set like this: - -```objective-c -call.requestMetadata[@"My-Header"] = @"Value for this header"; -``` - -If you have an access token, OAuth2 specifies it is to be sent in this format: - -```objective-c -call.requestMetadata[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken]; -``` - - -## Get response metadata of a call: Auth challenge header - -The `ProtoRPC` class also inherits a `responseMetadata` property, analogous to the request metadata -we just looked at. It's defined like this: - -```objective-c -@property(atomic, readonly) NSDictionary *responseMetadata; -``` - -To access OAuth2's authentication challenge header you write: - -```objective-c -call.responseMetadata[@"www-authenticate"] -``` - -Note that, as gRPC metadata elements are mapped to HTTP/2 headers (or trailers), the keys of the -response metadata are always ASCII strings in lowercase. - -Many uses cases of response metadata are getting more details about an RPC error. For convenience, -when a `NSError` instance is passed to an RPC handler block, the response metadata dictionary can -also be accessed this way: - -```objective-c -error.userInfo[kGRPCStatusMetadataKey] -``` diff --git a/objective-c/auth_sample/SelectUserViewController.h b/objective-c/auth_sample/SelectUserViewController.h deleted file mode 100644 index eb3c2cf5f0..0000000000 --- a/objective-c/auth_sample/SelectUserViewController.h +++ /dev/null @@ -1,42 +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. - * - */ - -#import -#import - -@interface SelectUserViewController : UIViewController -@property(weak, nonatomic) IBOutlet GIDSignInButton *signInButton; -@property(weak, nonatomic) IBOutlet UIButton *signOutButton; -@property(weak, nonatomic) IBOutlet UILabel *mainLabel; -@property(weak, nonatomic) IBOutlet UILabel *subLabel; -@end diff --git a/objective-c/auth_sample/SelectUserViewController.m b/objective-c/auth_sample/SelectUserViewController.m deleted file mode 100644 index 954c531f3f..0000000000 --- a/objective-c/auth_sample/SelectUserViewController.m +++ /dev/null @@ -1,86 +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. - * - */ - -#import "SelectUserViewController.h" - -#import "MakeRPCViewController.h" - -@implementation SelectUserViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.signOutButton.layer.cornerRadius = 5; - self.signOutButton.hidden = YES; - - // As instructed in https://developers.google.com/identity/sign-in/ios/sign-in - GIDSignIn *signIn = GIDSignIn.sharedInstance; - signIn.delegate = self; - signIn.uiDelegate = self; - - // As instructed in https://developers.google.com/identity/sign-in/ios/additional-scopes - if (![signIn.scopes containsObject:kTestScope]) { - signIn.scopes = [signIn.scopes arrayByAddingObject:kTestScope]; - } - - [signIn signInSilently]; -} - -- (void)signIn:(GIDSignIn *)signIn -didSignInForUser:(GIDGoogleUser *)user - withError:(NSError *)error { - if (error) { - // The user probably cancelled the sign-in flow. - return; - } - - self.mainLabel.text = [NSString stringWithFormat:@"User: %@", user.profile.email]; - NSString *scopes = [user.accessibleScopes componentsJoinedByString:@", "]; - scopes = scopes.length ? scopes : @"(none)"; - self.subLabel.text = [NSString stringWithFormat:@"Scopes: %@", scopes]; - - self.signInButton.hidden = YES; - self.signOutButton.hidden = NO; -} - -- (IBAction)didTapSignOut { - [GIDSignIn.sharedInstance signOut]; - - self.mainLabel.text = @"Please sign in."; - self.subLabel.text = @""; - - self.signInButton.hidden = NO; - self.signOutButton.hidden = YES; -} - -@end diff --git a/objective-c/helloworld/HelloWorld.podspec b/objective-c/helloworld/HelloWorld.podspec deleted file mode 100644 index ae009a688c..0000000000 --- a/objective-c/helloworld/HelloWorld.podspec +++ /dev/null @@ -1,35 +0,0 @@ -Pod::Spec.new do |s| - s.name = "HelloWorld" - s.version = "0.0.1" - s.license = "New BSD" - - s.ios.deployment_target = "6.0" - s.osx.deployment_target = "10.8" - - # Base directory where the .proto files are. - src = "../../protos" - - # Directory where the generated files will be place. - dir = "Pods/" + s.name - - # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.prepare_command = <<-CMD - mkdir -p #{dir} - protoc -I #{src} --objc_out=#{dir} --objcgrpc_out=#{dir} #{src}/helloworld.proto - CMD - - s.subspec "Messages" do |ms| - ms.source_files = "#{dir}/*.pbobjc.{h,m}", "#{dir}/**/*.pbobjc.{h,m}" - ms.header_mappings_dir = dir - ms.requires_arc = false - ms.dependency "Protobuf", "~> 3.0.0-alpha-3" - end - - s.subspec "Services" do |ss| - ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}" - ss.header_mappings_dir = dir - ss.requires_arc = true - ss.dependency "gRPC", "~> 0.6" - ss.dependency "#{s.name}/Messages" - end -end diff --git a/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj b/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj deleted file mode 100644 index 702ad3ff8b..0000000000 --- a/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj +++ /dev/null @@ -1,349 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 5E3690661B2A23800040F884 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3690651B2A23800040F884 /* main.m */; }; - 5E3690691B2A23800040F884 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3690681B2A23800040F884 /* AppDelegate.m */; }; - 5E36906C1B2A23800040F884 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E36906B1B2A23800040F884 /* ViewController.m */; }; - 5E36906F1B2A23800040F884 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E36906D1B2A23800040F884 /* Main.storyboard */; }; - 5E3690711B2A23800040F884 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5E3690701B2A23800040F884 /* Images.xcassets */; }; - EF61CF6AE2536A31D47F0E63 /* libPods-HelloWorld.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B4E1F55F8A2EC95A0E7EE88 /* libPods-HelloWorld.a */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.release.xcconfig"; path = "Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld.release.xcconfig"; sourceTree = ""; }; - 5E3690601B2A23800040F884 /* HelloWorld.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorld.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 5E3690641B2A23800040F884 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5E3690651B2A23800040F884 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 5E3690671B2A23800040F884 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 5E3690681B2A23800040F884 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 5E36906B1B2A23800040F884 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; - 5E36906E1B2A23800040F884 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 5E3690701B2A23800040F884 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6B4E1F55F8A2EC95A0E7EE88 /* libPods-HelloWorld.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HelloWorld.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.debug.xcconfig"; path = "Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld.debug.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 5E36905D1B2A23800040F884 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - EF61CF6AE2536A31D47F0E63 /* libPods-HelloWorld.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 5E3690571B2A23800040F884 = { - isa = PBXGroup; - children = ( - 5E3690651B2A23800040F884 /* main.m */, - 5E3690621B2A23800040F884 /* HelloWorld */, - 5E3690611B2A23800040F884 /* Products */, - BD9CE6458E7C4FF49A1DF69F /* Pods */, - 66CEC7120220DDD2221DD075 /* Frameworks */, - ); - sourceTree = ""; - }; - 5E3690611B2A23800040F884 /* Products */ = { - isa = PBXGroup; - children = ( - 5E3690601B2A23800040F884 /* HelloWorld.app */, - ); - name = Products; - sourceTree = ""; - }; - 5E3690621B2A23800040F884 /* HelloWorld */ = { - isa = PBXGroup; - children = ( - 5E3690631B2A23800040F884 /* Supporting Files */, - ); - path = HelloWorld; - sourceTree = ""; - }; - 5E3690631B2A23800040F884 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 5E3690701B2A23800040F884 /* Images.xcassets */, - 5E36906D1B2A23800040F884 /* Main.storyboard */, - 5E36906B1B2A23800040F884 /* ViewController.m */, - 5E3690681B2A23800040F884 /* AppDelegate.m */, - 5E3690671B2A23800040F884 /* AppDelegate.h */, - 5E3690641B2A23800040F884 /* Info.plist */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 66CEC7120220DDD2221DD075 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 6B4E1F55F8A2EC95A0E7EE88 /* libPods-HelloWorld.a */, - ); - name = Frameworks; - sourceTree = ""; - }; - BD9CE6458E7C4FF49A1DF69F /* Pods */ = { - isa = PBXGroup; - children = ( - DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */, - 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 5E36905F1B2A23800040F884 /* HelloWorld */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5E3690831B2A23810040F884 /* Build configuration list for PBXNativeTarget "HelloWorld" */; - buildPhases = ( - ACF9162361FB8F24C70657DE /* Check Pods Manifest.lock */, - 5E36905C1B2A23800040F884 /* Sources */, - 5E36905D1B2A23800040F884 /* Frameworks */, - 5E36905E1B2A23800040F884 /* Resources */, - 4C7D815378D98AB3BFC1A7D5 /* Copy Pods Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = HelloWorld; - productName = HelloWorld; - productReference = 5E3690601B2A23800040F884 /* HelloWorld.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 5E3690581B2A23800040F884 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0620; - ORGANIZATIONNAME = Google; - TargetAttributes = { - 5E36905F1B2A23800040F884 = { - CreatedOnToolsVersion = 6.2; - }; - }; - }; - buildConfigurationList = 5E36905B1B2A23800040F884 /* Build configuration list for PBXProject "HelloWorld" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 5E3690571B2A23800040F884; - productRefGroup = 5E3690611B2A23800040F884 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 5E36905F1B2A23800040F884 /* HelloWorld */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 5E36905E1B2A23800040F884 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5E36906F1B2A23800040F884 /* Main.storyboard in Resources */, - 5E3690711B2A23800040F884 /* Images.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 4C7D815378D98AB3BFC1A7D5 /* Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - ACF9162361FB8F24C70657DE /* Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Check Pods Manifest.lock"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 5E36905C1B2A23800040F884 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5E36906C1B2A23800040F884 /* ViewController.m in Sources */, - 5E3690691B2A23800040F884 /* AppDelegate.m in Sources */, - 5E3690661B2A23800040F884 /* main.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 5E36906D1B2A23800040F884 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 5E36906E1B2A23800040F884 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 5E3690811B2A23810040F884 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.2; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 5E3690821B2A23810040F884 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.2; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 5E3690841B2A23810040F884 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = HelloWorld/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 5E3690851B2A23810040F884 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = HelloWorld/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 5E36905B1B2A23800040F884 /* Build configuration list for PBXProject "HelloWorld" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5E3690811B2A23810040F884 /* Debug */, - 5E3690821B2A23810040F884 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5E3690831B2A23810040F884 /* Build configuration list for PBXNativeTarget "HelloWorld" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5E3690841B2A23810040F884 /* Debug */, - 5E3690851B2A23810040F884 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 5E3690581B2A23800040F884 /* Project object */; -} diff --git a/objective-c/helloworld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/objective-c/helloworld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 174a04ecb8..0000000000 --- a/objective-c/helloworld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/objective-c/helloworld/HelloWorld/AppDelegate.h b/objective-c/helloworld/HelloWorld/AppDelegate.h deleted file mode 100644 index 102e7f3ade..0000000000 --- a/objective-c/helloworld/HelloWorld/AppDelegate.h +++ /dev/null @@ -1,38 +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. - * - */ - -#import - -@interface AppDelegate : UIResponder -@property (strong, nonatomic) UIWindow *window; -@end diff --git a/objective-c/helloworld/HelloWorld/AppDelegate.m b/objective-c/helloworld/HelloWorld/AppDelegate.m deleted file mode 100644 index a38e36651e..0000000000 --- a/objective-c/helloworld/HelloWorld/AppDelegate.m +++ /dev/null @@ -1,37 +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. - * - */ - -#import "AppDelegate.h" - -@implementation AppDelegate -@end diff --git a/objective-c/helloworld/HelloWorld/Base.lproj/Main.storyboard b/objective-c/helloworld/HelloWorld/Base.lproj/Main.storyboard deleted file mode 100644 index f56d2f3bb5..0000000000 --- a/objective-c/helloworld/HelloWorld/Base.lproj/Main.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/objective-c/helloworld/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json b/objective-c/helloworld/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 36d2c80d88..0000000000 --- a/objective-c/helloworld/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/objective-c/helloworld/HelloWorld/Info.plist b/objective-c/helloworld/HelloWorld/Info.plist deleted file mode 100644 index 1078fff723..0000000000 --- a/objective-c/helloworld/HelloWorld/Info.plist +++ /dev/null @@ -1,47 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - Google.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - Main - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/objective-c/helloworld/HelloWorld/ViewController.m b/objective-c/helloworld/HelloWorld/ViewController.m deleted file mode 100644 index 090fd93689..0000000000 --- a/objective-c/helloworld/HelloWorld/ViewController.m +++ /dev/null @@ -1,40 +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. - * - */ - -#import - -@interface ViewController : UIViewController -@end - -@implementation ViewController -@end diff --git a/objective-c/helloworld/Podfile b/objective-c/helloworld/Podfile deleted file mode 100644 index 2934ebc2c8..0000000000 --- a/objective-c/helloworld/Podfile +++ /dev/null @@ -1,7 +0,0 @@ -source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '8.0' - -target 'HelloWorld' do - # Depend on the generated HelloWorld library. - pod 'HelloWorld', :path => '.' -end diff --git a/objective-c/helloworld/README.md b/objective-c/helloworld/README.md deleted file mode 100644 index 685339e84a..0000000000 --- a/objective-c/helloworld/README.md +++ /dev/null @@ -1,56 +0,0 @@ -#gRPC in 3 minutes (Objective-C) - -## Installation - -To run this example you should have [Cocoapods](https://cocoapods.org/#install) installed, as well -as the relevant tools to generate the client library code (and a server in another language, for -testing). You can obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). - -## Hello Objective-C gRPC! - -Here's how to build and run the Objective-C implementation of the [Hello World](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto) -example used in [Getting started](https://github.com/grpc/grpc-common). - -The example code for this and our other examples lives in the `grpc-common` GitHub repository. Clone -this repository to your local machine by running the following command: - - -```sh -$ git clone https://github.com/grpc/grpc-common.git -``` - -Change your current directory to `grpc-common/objective-c/helloworld` - -```sh -$ cd grpc-common/objective-c/helloworld -``` - -### Try it! -To try the sample app, we need a gRPC server running locally. Let's compile and run, for example, -the C++ server in this repository: - -```shell -$ pushd ../../cpp/helloworld -$ make -$ ./greeter_server & -$ popd -``` - -Now have Cocoapods generate and install the client library for our .proto files: - -```shell -$ pod install -``` - -(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet -on your computer's cache.) - -Finally, open the XCode workspace created by Cocoapods, and run the app. You can check the calling -code in `main.m` and see the results in XCode's log console. - -The code sends a `HLWHelloRequest` containing the string "Objective-C" to a local server. The server -responds with a `HLWHelloResponse`, which contains a string that is then output to the log. - -## Tutorial - -You can find a more detailed tutorial in [gRPC Basics: Objective-C](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/README.md). diff --git a/objective-c/helloworld/main.m b/objective-c/helloworld/main.m deleted file mode 100644 index 458580be30..0000000000 --- a/objective-c/helloworld/main.m +++ /dev/null @@ -1,51 +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. - * - */ - -#import -#import "AppDelegate.h" - -#import - -static NSString * const kHostAddress = @"http://localhost:50051"; - -int main(int argc, char * argv[]) { - @autoreleasepool { - HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress]; - HLWHelloRequest *request = [HLWHelloRequest message]; - request.name = @"Objective-C"; - [client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { - NSLog(@"%@", response.message); - }]; - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/objective-c/route_guide/Misc/AppDelegate.h b/objective-c/route_guide/Misc/AppDelegate.h deleted file mode 100644 index 102e7f3ade..0000000000 --- a/objective-c/route_guide/Misc/AppDelegate.h +++ /dev/null @@ -1,38 +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. - * - */ - -#import - -@interface AppDelegate : UIResponder -@property (strong, nonatomic) UIWindow *window; -@end diff --git a/objective-c/route_guide/Misc/AppDelegate.m b/objective-c/route_guide/Misc/AppDelegate.m deleted file mode 100644 index a38e36651e..0000000000 --- a/objective-c/route_guide/Misc/AppDelegate.m +++ /dev/null @@ -1,37 +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. - * - */ - -#import "AppDelegate.h" - -@implementation AppDelegate -@end diff --git a/objective-c/route_guide/Misc/Base.lproj/Main.storyboard b/objective-c/route_guide/Misc/Base.lproj/Main.storyboard deleted file mode 100644 index 9bf9498d62..0000000000 --- a/objective-c/route_guide/Misc/Base.lproj/Main.storyboard +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json b/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 36d2c80d88..0000000000 --- a/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json b/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json deleted file mode 100644 index 33a745102c..0000000000 --- a/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "first.pdf" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf b/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf deleted file mode 100644 index 47d911dea6..0000000000 Binary files a/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf and /dev/null differ diff --git a/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json b/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json deleted file mode 100644 index 03bd9c927f..0000000000 --- a/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "second.pdf" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf b/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf deleted file mode 100644 index 401614e288..0000000000 Binary files a/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf and /dev/null differ diff --git a/objective-c/route_guide/Misc/Info.plist b/objective-c/route_guide/Misc/Info.plist deleted file mode 100644 index 33ad4800f6..0000000000 --- a/objective-c/route_guide/Misc/Info.plist +++ /dev/null @@ -1,57 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - gRPC.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - Main - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarTintParameters - - UINavigationBar - - Style - UIBarStyleDefault - Translucent - - - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/objective-c/route_guide/Misc/main.m b/objective-c/route_guide/Misc/main.m deleted file mode 100644 index fb701005d1..0000000000 --- a/objective-c/route_guide/Misc/main.m +++ /dev/null @@ -1,41 +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. - * - */ - -#import -#import "AppDelegate.h" - -int main(int argc, char * argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/objective-c/route_guide/Podfile b/objective-c/route_guide/Podfile deleted file mode 100644 index a97f414685..0000000000 --- a/objective-c/route_guide/Podfile +++ /dev/null @@ -1,7 +0,0 @@ -source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '8.0' - -target 'RouteGuideClient' do - # Depend on the generated RouteGuide library. - pod 'RouteGuide', :path => '.' -end diff --git a/objective-c/route_guide/README.md b/objective-c/route_guide/README.md deleted file mode 100644 index bbbd9e020d..0000000000 --- a/objective-c/route_guide/README.md +++ /dev/null @@ -1,360 +0,0 @@ -#gRPC Basics: Objective-C - -This tutorial provides a basic Objective-C programmer's introduction to working with gRPC. By -walking through this example you'll learn how to: - -- Define a service in a .proto file. -- Generate client code using the protocol buffer compiler. -- Use the Objective-C gRPC API to write a simple client for your service. - -It assumes a passing familiarity with [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). -Note that the example in this tutorial uses the proto3 version of the protocol buffers language, -which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) -and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the -protocol buffers Github repository. - -This isn't a comprehensive guide to using gRPC in Objective-C: more reference documentation is -coming soon. - -- [Why use gRPC?](#why-grpc) -- [Example code and setup](#setup) -- [Try it out!](#try) -- [Defining the service](#proto) -- [Generating client code](#protoc) -- [Creating the client](#client) - - -## Why use gRPC? - -With gRPC you can define your service once in a .proto file and implement clients and servers in any -of gRPC's supported languages, which in turn can be run in environments ranging from servers inside -Google to your own tablet - all the complexity of communication between different languages and -environments is handled for you by gRPC. You also get all the advantages of working with protocol -buffers, including efficient serialization, a simple IDL, and easy interface updating. - -gRPC and proto3 are specially suited for mobile clients: gRPC is implemented on top of HTTP/2, which -results in network bandwidth savings over using HTTP/1.1. Serialization and parsing of the proto -binary format is more efficient than the equivalent JSON, resulting in CPU and battery savings. And -proto3 uses a runtime that has been optimized over the years at Google to keep code size to a -minimum. The latter is important in Objective-C, because the ability of the compiler to strip unused -code is limited by the dynamic nature of the language. - - - -## Example code and setup - -The example code for our tutorial is in [grpc/grpc-common/objective-c/route_guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide). -To download the example, clone the `grpc-common` repository by running the following command: -```shell -$ git clone https://github.com/grpc/grpc-common.git -``` - -Then change your current directory to `grpc-common/objective-c/route_guide`: -```shell -$ cd grpc-common/objective-c/route_guide -``` - -Our example is a simple route mapping application that lets clients get information about features -on their route, create a summary of their route, and exchange route information such as traffic -updates with the server and other clients. - -You also should have [Cocoapods](https://cocoapods.org/#install) installed, as well as the relevant -tools to generate the client library code (and a server in another language, for testing). You can -obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). - - - -## Try it out! - -To try the sample app, we need a gRPC server running locally. Let's compile and run, for example, -the C++ server in this repository: - -```shell -$ pushd ../../cpp/route_guide -$ make -$ ./route_guide_server & -$ popd -``` - -Now have Cocoapods generate and install the client library for our .proto files: - -```shell -$ pod install -``` - -(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet -on your computer's cache). - -Finally, open the XCode workspace created by Cocoapods, and run the app. You can check the calling -code in `ViewControllers.m` and see the results in XCode's log console. - -The next sections guide you step-by-step through how this proto service is defined, how to generate -a client library from it, and how to create an app that uses that library. - - - -## Defining the service - -First let's look at how the service we're using is defined. A gRPC *service* and its method -*request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). -You can see the complete .proto file for our example in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). - -To define a service, you specify a named `service` in your .proto file: - -```protobuf -service RouteGuide { - ... -} -``` - -Then you define `rpc` methods inside your service definition, specifying their request and response -types. Protocol buffers let you define four kinds of service method, all of which are used in the -`RouteGuide` service: - -- A *simple RPC* where the client sends a request to the server and receives a response later, just -like a normal remote procedure call. -```protobuf - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} -``` - -- A *response-streaming RPC* where the client sends a request to the server and gets back a stream -of response messages. You specify a response-streaming method by placing the `stream` keyword before -the *response* type. -```protobuf - // 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 *request-streaming RPC* where the client sends a sequence of messages to the server. Once the -client has finished writing the messages, it waits for the server to read them all and return its -response. You specify a request-streaming method by placing the `stream` keyword before the -*request* type. -```protobuf - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} -``` - -- A *bidirectional streaming RPC* where both sides send a sequence of messages to the other. The two -streams operate independently, so clients and servers can read and write in whatever order they -like: for example, the server could wait to receive all the client messages before writing its -responses, or it could alternately read a message then write a message, or some other combination of -reads and writes. The order of messages in each stream is preserved. You specify this type of method -by placing the `stream` keyword before both the request and the response. -```protobuf - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -``` - -Our .proto file also contains protocol buffer message type definitions for all the request and -response types used in our service methods - for example, here's the `Point` message type: -```protobuf -// 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; -} -``` - -You can specify a prefix to be used for your generated classes by adding the `objc_class_prefix` -option at the top of the file. For example: -```protobuf -option objc_class_prefix = "RTG"; -``` - - - -## Generating client code - -Next we need to generate the gRPC client interfaces from our .proto service definition. We do this -using the protocol buffer compiler (`protoc`) with a special gRPC Objective-C plugin. - -For simplicity, we've provided a [Podspec file](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/RouteGuide.podspec) -that runs `protoc` for you with the appropriate plugin, input, and output, and describes how to -compile the generated files. You just need to run in this directory (`grpc-common/objective-c/route_guide`): - -```shell -$ pod install -``` - -which, before installing the generated library in the XCode project of this sample, runs: - -```shell -$ protoc -I ../../protos --objc_out=Pods/RouteGuide --objcgrpc_out=Pods/RouteGuide ../../protos/route_guide.proto -``` - -Running this command generates the following files under `Pods/RouteGuide/`: -- `RouteGuide.pbobjc.h`, the header which declares your generated message classes. -- `RouteGuide.pbobjc.m`, which contains the implementation of your message classes. -- `RouteGuide.pbrpc.h`, the header which declares your generated service classes. -- `RouteGuide.pbrpc.m`, which contains the implementation of your service classes. - -These contain: -- All the protocol buffer code to populate, serialize, and retrieve our request and response message -types. -- A class called `RTGRouteGuide` that lets clients call the methods defined in the `RouteGuide` -service. - -You can also use the provided Podspec file to generate client code from any other proto service -definition; just replace the name (matching the file name), version, and other metadata. - - - -## Creating the client - -In this section, we'll look at creating an Objective-C client for our `RouteGuide` service. You can -see our complete example client code in [grpc-common/objective-c/route_guide/ViewControllers.m](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/ViewControllers.m). -(Note: In your apps, for maintainability and readability reasons, you shouldn't put all of your view -controllers in a single file; it's done here only to simplify the learning process). - -### Constructing a client object - -To call service methods, we first need to create a client object, an instance of the generated -`RTGRouteGuide` class. The designated initializer of the class expects a `NSString *` with the -server address and port we want to connect to: - -```objective-c -#import - -static NSString * const kHostAddress = @"http://localhost:50051"; - -... - -RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; -``` - -Notice that we've specified the HTTP scheme in the host address. This is because the server we will -be using to test our client doesn't use [TLS](http://en.wikipedia.org/wiki/Transport_Layer_Security). -This is fine because it will be running locally on our development machine. The most common case, -though, is connecting with a gRPC server on the internet, running gRPC over TLS. For that case, the -HTTPS scheme can be specified (or no scheme at all, as HTTPS is the default value). The default -value of the port is that of the scheme selected: 443 for HTTPS and 80 for HTTP. - - -### Calling service methods - -Now let's look at how we call our service methods. As you will see, all these methods are -asynchronous, so you can call them from the main thread of your app without worrying about freezing -your UI or the OS killing your app. - -#### Simple RPC - -Calling the simple RPC `GetFeature` is nearly as straightforward as calling any other asynchronous -method on Cocoa. - -```objective-c -RTGPoint *point = [RTGPoint message]; -point.latitude = 40E7; -point.longitude = -74E7; - -[client getFeatureWithRequest:point handler:^(RTGFeature *response, NSError *error) { - if (response) { - // Successful response received - } else { - // RPC error - } -}]; -``` - -As you can see, we create and populate a request protocol buffer object (in our case `RTGPoint`). -Then, we call the method on the client object, passing it the request, and a block to handle the -response (or any RPC error). If the RPC finishes successfully, the handler block is called with a -`nil` error argument, and we can read the response information from the server from the response -argument. If, instead, some RPC error happens, the handler block is called with a `nil` response -argument, and we can read the details of the problem from the error argument. - -```objective-c -NSLog(@"Found feature called %@ at %@.", response.name, response.location); -``` - -#### Streaming RPCs - -Now let's look at our streaming methods. Here's where we call the response-streaming method -`ListFeatures`, which results in our client receiving a stream of geographical `RTGFeature`s: - -```objective-c -[client listFeaturesWithRequest:rectangle - eventHandler:^(BOOL done, RTGFeature *response, NSError *error) { - if (response) { - // Element of the stream of responses received - } else if (error) { - // RPC error; the stream is over. - } - if (done) { - // The stream is over (all the responses were received, or an error occured). Do any cleanup. - } -}]; -``` - -Notice how the signature of the `eventHandler` block now includes a `BOOL done` parameter. The -`eventHandler` block can be called any number of times; only on the last call is the `done` argument -value set to `YES`. If an error occurs, the RPC finishes and the block is called with the arguments -`(YES, nil, error)`. - -The request-streaming method `RecordRoute` expects a stream of `RTGPoint`s from the cient. This -stream is passed to the method as an object of class `GRXWriter`. The simplest way to create one is -to initialize one from a `NSArray` object: - - -```objective-c -#import - -... - -RTGPoint *point1 = [RTGPoint message]; -point.latitude = 40E7; -point.longitude = -74E7; - -RTGPoint *point2 = [RTGPoint message]; -point.latitude = 40E7; -point.longitude = -74E7; - -GRXWriter *locationsWriter = [GRXWriter writerWithContainer:@[point1, point2]]; - -[client recordRouteWithRequestsWriter:locationsWriter - handler:^(RTGRouteSummary *response, NSError *error) { - if (response) { - NSLog(@"Finished trip with %i points", response.pointCount); - NSLog(@"Passed %i features", response.featureCount); - NSLog(@"Travelled %i meters", response.distance); - NSLog(@"It took %i seconds", response.elapsedTime); - } else { - NSLog(@"RPC error: %@", error); - } -}]; - -``` - -The `GRXWriter` class is generic enough to allow for asynchronous streams, streams of future values, -or even infinite streams. - -Finally, let's look at our bidirectional streaming RPC `RouteChat()`. The way to call a -bidirectional streaming RPC is just a combination of how to call request-streaming RPCs and -response-streaming RPCs. - -```objective-c -[client routeChatWithRequestsWriter:notesWriter - eventHandler:^(BOOL done, RTGRouteNote *note, NSError *error) { - if (note) { - NSLog(@"Got message %@ at %@", note.message, note.location); - } else if (error) { - NSLog(@"RPC error: %@", error); - } - if (done) { - NSLog(@"Chat ended."); - } -}]; -``` - -The semantics for the handler block and the `GRXWriter` argument here are exactly the same as for -our request-streaming and response-streaming methods. Although both client and server will always -get the other's messages in the order they were written, the two streams operate completely -independently. diff --git a/objective-c/route_guide/RouteGuide.podspec b/objective-c/route_guide/RouteGuide.podspec deleted file mode 100644 index 7b99a6c6a7..0000000000 --- a/objective-c/route_guide/RouteGuide.podspec +++ /dev/null @@ -1,35 +0,0 @@ -Pod::Spec.new do |s| - s.name = "RouteGuide" - s.version = "0.0.1" - s.license = "New BSD" - - s.ios.deployment_target = "6.0" - s.osx.deployment_target = "10.8" - - # Base directory where the .proto files are. - src = "../../protos" - - # Directory where the generated files will be place. - dir = "Pods/" + s.name - - # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.prepare_command = <<-CMD - mkdir -p #{dir} - protoc -I #{src} --objc_out=#{dir} --objcgrpc_out=#{dir} #{src}/route_guide.proto - CMD - - s.subspec "Messages" do |ms| - ms.source_files = "#{dir}/*.pbobjc.{h,m}", "#{dir}/**/*.pbobjc.{h,m}" - ms.header_mappings_dir = dir - ms.requires_arc = false - ms.dependency "Protobuf", "~> 3.0.0-alpha-3" - end - - s.subspec "Services" do |ss| - ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}" - ss.header_mappings_dir = dir - ss.requires_arc = true - ss.dependency "gRPC", "~> 0.6" - ss.dependency "#{s.name}/Messages" - end -end diff --git a/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj b/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj deleted file mode 100644 index 6ab6b27a1b..0000000000 --- a/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj +++ /dev/null @@ -1,366 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 124E20A2FC8EAE54460D4ED2 /* libPods-RouteGuideClient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 71CEE03D66D40FC37264D6E4 /* libPods-RouteGuideClient.a */; }; - 632527831B1D0396003073D9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 632527821B1D0396003073D9 /* main.m */; }; - 632527861B1D0396003073D9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 632527851B1D0396003073D9 /* AppDelegate.m */; }; - 6325278F1B1D0396003073D9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6325278D1B1D0396003073D9 /* Main.storyboard */; }; - 632527911B1D0396003073D9 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 632527901B1D0396003073D9 /* Images.xcassets */; }; - 6367B55B1B223AFA008861F5 /* route_guide_db.json in Resources */ = {isa = PBXBuildFile; fileRef = 6367B55A1B223AFA008861F5 /* route_guide_db.json */; }; - 63A6015C1B1DAB5000FA5B86 /* ViewControllers.m in Sources */ = {isa = PBXBuildFile; fileRef = 63A6015B1B1DAB5000FA5B86 /* ViewControllers.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 6325277D1B1D0396003073D9 /* RouteGuideClient.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RouteGuideClient.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 632527811B1D0396003073D9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 632527821B1D0396003073D9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 632527841B1D0396003073D9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 632527851B1D0396003073D9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6325278E1B1D0396003073D9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 632527901B1D0396003073D9 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6367B55A1B223AFA008861F5 /* route_guide_db.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = route_guide_db.json; sourceTree = ""; }; - 63A6015B1B1DAB5000FA5B86 /* ViewControllers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewControllers.m; sourceTree = ""; }; - 71CEE03D66D40FC37264D6E4 /* libPods-RouteGuideClient.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RouteGuideClient.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - ADA4C647BAE906F79AD9A45E /* Pods-RouteGuideClient.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RouteGuideClient.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RouteGuideClient/Pods-RouteGuideClient.debug.xcconfig"; sourceTree = ""; }; - C83C5A54D1A4EA07569F1AED /* Pods-RouteGuideClient.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RouteGuideClient.release.xcconfig"; path = "Pods/Target Support Files/Pods-RouteGuideClient/Pods-RouteGuideClient.release.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6325277A1B1D0395003073D9 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 124E20A2FC8EAE54460D4ED2 /* libPods-RouteGuideClient.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 56849C29DC376BF4B902CD77 /* Pods */ = { - isa = PBXGroup; - children = ( - ADA4C647BAE906F79AD9A45E /* Pods-RouteGuideClient.debug.xcconfig */, - C83C5A54D1A4EA07569F1AED /* Pods-RouteGuideClient.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; - 631C63891B1DBC41001295D5 /* Misc */ = { - isa = PBXGroup; - children = ( - 632527841B1D0396003073D9 /* AppDelegate.h */, - 632527851B1D0396003073D9 /* AppDelegate.m */, - 632527901B1D0396003073D9 /* Images.xcassets */, - 632527801B1D0396003073D9 /* Supporting Files */, - ); - path = Misc; - sourceTree = ""; - }; - 632527741B1D0395003073D9 = { - isa = PBXGroup; - children = ( - 6325277F1B1D0396003073D9 /* RouteGuideClient */, - 6325277E1B1D0396003073D9 /* Products */, - 56849C29DC376BF4B902CD77 /* Pods */, - 7482B8A18481F7B13ADE4530 /* Frameworks */, - ); - sourceTree = ""; - }; - 6325277E1B1D0396003073D9 /* Products */ = { - isa = PBXGroup; - children = ( - 6325277D1B1D0396003073D9 /* RouteGuideClient.app */, - ); - name = Products; - sourceTree = ""; - }; - 6325277F1B1D0396003073D9 /* RouteGuideClient */ = { - isa = PBXGroup; - children = ( - 63A6015B1B1DAB5000FA5B86 /* ViewControllers.m */, - 6367B55A1B223AFA008861F5 /* route_guide_db.json */, - 6325278D1B1D0396003073D9 /* Main.storyboard */, - 631C63891B1DBC41001295D5 /* Misc */, - ); - name = RouteGuideClient; - sourceTree = SOURCE_ROOT; - }; - 632527801B1D0396003073D9 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 632527811B1D0396003073D9 /* Info.plist */, - 632527821B1D0396003073D9 /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 7482B8A18481F7B13ADE4530 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 71CEE03D66D40FC37264D6E4 /* libPods-RouteGuideClient.a */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6325277C1B1D0395003073D9 /* RouteGuideClient */ = { - isa = PBXNativeTarget; - buildConfigurationList = 632527A31B1D0396003073D9 /* Build configuration list for PBXNativeTarget "RouteGuideClient" */; - buildPhases = ( - C6FC30AD2376EC04317237C5 /* Check Pods Manifest.lock */, - 632527791B1D0395003073D9 /* Sources */, - 6325277A1B1D0395003073D9 /* Frameworks */, - 6325277B1B1D0395003073D9 /* Resources */, - FFE0BCF30339E7A50A989EAB /* Copy Pods Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = RouteGuideClient; - productName = RouteGuideClient; - productReference = 6325277D1B1D0396003073D9 /* RouteGuideClient.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 632527751B1D0395003073D9 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = gRPC; - TargetAttributes = { - 6325277C1B1D0395003073D9 = { - CreatedOnToolsVersion = 6.3.1; - }; - }; - }; - buildConfigurationList = 632527781B1D0395003073D9 /* Build configuration list for PBXProject "RouteGuideClient" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 632527741B1D0395003073D9; - productRefGroup = 6325277E1B1D0396003073D9 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6325277C1B1D0395003073D9 /* RouteGuideClient */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6325277B1B1D0395003073D9 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6325278F1B1D0396003073D9 /* Main.storyboard in Resources */, - 632527911B1D0396003073D9 /* Images.xcassets in Resources */, - 6367B55B1B223AFA008861F5 /* route_guide_db.json in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - C6FC30AD2376EC04317237C5 /* Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Check Pods Manifest.lock"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; - showEnvVarsInLog = 0; - }; - FFE0BCF30339E7A50A989EAB /* Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RouteGuideClient/Pods-RouteGuideClient-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 632527791B1D0395003073D9 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 632527861B1D0396003073D9 /* AppDelegate.m in Sources */, - 632527831B1D0396003073D9 /* main.m in Sources */, - 63A6015C1B1DAB5000FA5B86 /* ViewControllers.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6325278D1B1D0396003073D9 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6325278E1B1D0396003073D9 /* Base */, - ); - name = Main.storyboard; - path = Misc; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 632527A11B1D0396003073D9 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 632527A21B1D0396003073D9 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 632527A41B1D0396003073D9 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = ADA4C647BAE906F79AD9A45E /* Pods-RouteGuideClient.debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = Misc/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 632527A51B1D0396003073D9 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = C83C5A54D1A4EA07569F1AED /* Pods-RouteGuideClient.release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = Misc/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 632527781B1D0395003073D9 /* Build configuration list for PBXProject "RouteGuideClient" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 632527A11B1D0396003073D9 /* Debug */, - 632527A21B1D0396003073D9 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 632527A31B1D0396003073D9 /* Build configuration list for PBXNativeTarget "RouteGuideClient" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 632527A41B1D0396003073D9 /* Debug */, - 632527A51B1D0396003073D9 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 632527751B1D0395003073D9 /* Project object */; -} diff --git a/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index f208589e44..0000000000 --- a/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/objective-c/route_guide/ViewControllers.m b/objective-c/route_guide/ViewControllers.m deleted file mode 100644 index cfc3338bca..0000000000 --- a/objective-c/route_guide/ViewControllers.m +++ /dev/null @@ -1,228 +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. - * - */ - -#import -#import -#import -#import - -static NSString * const kHostAddress = @"http://localhost:50051"; - -// Category to override RTGPoint's description. -@interface RTGPoint (Description) -- (NSString *)description; -@end - -@implementation RTGPoint (Description) -- (NSString *)description { - NSString *verticalDirection = self.latitude >= 0 ? @"N" : @"S"; - NSString *horizontalDirection = self.longitude >= 0 ? @"E" : @"W"; - return [NSString stringWithFormat:@"%.02f%@ %.02f%@", - abs(self.latitude) / 1E7f, verticalDirection, - abs(self.longitude) / 1E7f, horizontalDirection]; -} -@end - -// Category to give RTGRouteNote a convenience constructor. -@interface RTGRouteNote (Constructors) -+ (instancetype)noteWithMessage:(NSString *)message - latitude:(float)latitude - longitude:(float)longitude; -@end - -@implementation RTGRouteNote (Constructors) -+ (instancetype)noteWithMessage:(NSString *)message - latitude:(float)latitude - longitude:(float)longitude { - RTGRouteNote *note = [self message]; - note.message = message; - note.location.latitude = (int32_t) latitude * 1E7; - note.location.longitude = (int32_t) longitude * 1E7; - return note; -} -@end - - -#pragma mark Demo: Get Feature - -// Run the getFeature demo. Calls getFeature with a point known to have a feature and a point known -// not to have a feature. - -@interface GetFeatureViewController : UIViewController -@end - -@implementation GetFeatureViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; - - void (^handler)(RTGFeature *response, NSError *error) = ^(RTGFeature *response, NSError *error) { - if (response.name.length) { - NSLog(@"Found feature called %@ at %@.", response.name, response.location); - } else if (response) { - NSLog(@"Found no features at %@", response.location); - } else { - NSLog(@"RPC error: %@", error); - } - }; - - RTGPoint *point = [RTGPoint message]; - point.latitude = 409146138; - point.longitude = -746188906; - - [client getFeatureWithRequest:point handler:handler]; - [client getFeatureWithRequest:[RTGPoint message] handler:handler]; -} - -@end - - -#pragma mark Demo: List Features - -// Run the listFeatures demo. Calls listFeatures with a rectangle containing all of the features in -// the pre-generated database. Prints each response as it comes in. - -@interface ListFeaturesViewController : UIViewController -@end - -@implementation ListFeaturesViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; - - RTGRectangle *rectangle = [RTGRectangle message]; - rectangle.lo.latitude = 405E6; - rectangle.lo.longitude = -750E6; - rectangle.hi.latitude = 410E6; - rectangle.hi.longitude = -745E6; - - NSLog(@"Looking for features between %@ and %@", rectangle.lo, rectangle.hi); - [client listFeaturesWithRequest:rectangle - eventHandler:^(BOOL done, RTGFeature *response, NSError *error) { - if (response) { - NSLog(@"Found feature at %@ called %@.", response.location, response.name); - } else if (error) { - NSLog(@"RPC error: %@", error); - } - }]; -} - -@end - - -#pragma mark Demo: Record Route - -// Run the recordRoute demo. Sends several randomly chosen points from the pre-generated feature -// database with a variable delay in between. Prints the statistics when they are sent from the -// server. - -@interface RecordRouteViewController : UIViewController -@end - -@implementation RecordRouteViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - NSString *dataBasePath = [NSBundle.mainBundle pathForResource:@"route_guide_db" - ofType:@"json"]; - NSData *dataBaseContent = [NSData dataWithContentsOfFile:dataBasePath]; - NSArray *features = [NSJSONSerialization JSONObjectWithData:dataBaseContent options:0 error:NULL]; - - GRXWriter *locations = [[GRXWriter writerWithContainer:features] map:^id(id feature) { - RTGPoint *location = [RTGPoint message]; - location.longitude = [((NSNumber *) feature[@"location"][@"longitude"]) intValue]; - location.latitude = [((NSNumber *) feature[@"location"][@"latitude"]) intValue]; - NSLog(@"Visiting point %@", location); - return location; - }]; - - RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; - - [client recordRouteWithRequestsWriter:locations handler:^(RTGRouteSummary *response, NSError *error) { - if (response) { - NSLog(@"Finished trip with %i points", response.pointCount); - NSLog(@"Passed %i features", response.featureCount); - NSLog(@"Travelled %i meters", response.distance); - NSLog(@"It took %i seconds", response.elapsedTime); - } else { - NSLog(@"RPC error: %@", error); - } - }]; -} - -@end - - -#pragma mark Demo: Route Chat - -// Run the routeChat demo. Send some chat messages, and print any chat messages that are sent from -// the server. - -@interface RouteChatViewController : UIViewController -@end - -@implementation RouteChatViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - NSArray *notes = @[[RTGRouteNote noteWithMessage:@"First message" latitude:0 longitude:0], - [RTGRouteNote noteWithMessage:@"Second message" latitude:0 longitude:1], - [RTGRouteNote noteWithMessage:@"Third message" latitude:1 longitude:0], - [RTGRouteNote noteWithMessage:@"Fourth message" latitude:0 longitude:0]]; - GRXWriter *notesWriter = [[GRXWriter writerWithContainer:notes] map:^id(RTGRouteNote *note) { - NSLog(@"Sending message %@ at %@", note.message, note.location); - return note; - }]; - - RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; - - [client routeChatWithRequestsWriter:notesWriter - eventHandler:^(BOOL done, RTGRouteNote *note, NSError *error) { - if (note) { - NSLog(@"Got message %@ at %@", note.message, note.location); - } else if (error) { - NSLog(@"RPC error: %@", error); - } - if (done) { - NSLog(@"Chat ended."); - } - }]; -} - -@end diff --git a/objective-c/route_guide/route_guide_db.json b/objective-c/route_guide/route_guide_db.json deleted file mode 100644 index 9caebaa433..0000000000 --- a/objective-c/route_guide/route_guide_db.json +++ /dev/null @@ -1,121 +0,0 @@ -[{ - "location": { - "latitude": 407838351, - "longitude": -746143763 - }, - "name": "Patriots Path, Mendham, NJ 07945, USA" -}, { - "location": { - "latitude": 408122808, - "longitude": -743999179 - }, - "name": "101 New Jersey 10, Whippany, NJ 07981, USA" -}, { - "location": { - "latitude": 413628156, - "longitude": -749015468 - }, - "name": "U.S. 6, Shohola, PA 18458, USA" -}, { - "location": { - "latitude": 419999544, - "longitude": -740371136 - }, - "name": "5 Conners Road, Kingston, NY 12401, USA" -}, { - "location": { - "latitude": 414008389, - "longitude": -743951297 - }, - "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" -}, { - "location": { - "latitude": 419611318, - "longitude": -746524769 - }, - "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" -}, { - "location": { - "latitude": 406109563, - "longitude": -742186778 - }, - "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" -}, { - "location": { - "latitude": 416802456, - "longitude": -742370183 - }, - "name": "352 South Mountain Road, Wallkill, NY 12589, USA" -}, { - "location": { - "latitude": 412950425, - "longitude": -741077389 - }, - "name": "Bailey Turn Road, Harriman, NY 10926, USA" -}, { - "location": { - "latitude": 412144655, - "longitude": -743949739 - }, - "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" -}, { - "location": { - "latitude": 404306372, - "longitude": -741079661 - }, - "name": "" -}, { - "location": { - "latitude": 403966326, - "longitude": -748519297 - }, - "name": "" -}, { - "location": { - "latitude": 405002031, - "longitude": -748407866 - }, - "name": "" -}, { - "location": { - "latitude": 409532885, - "longitude": -742200683 - }, - "name": "" -}, { - "location": { - "latitude": 416851321, - "longitude": -742674555 - }, - "name": "" -}, { - "location": { - "latitude": 406411633, - "longitude": -741722051 - }, - "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" -}, { - "location": { - "latitude": 413069058, - "longitude": -744597778 - }, - "name": "261 Van Sickle Road, Goshen, NY 10924, USA" -}, { - "location": { - "latitude": 418465462, - "longitude": -746859398 - }, - "name": "" -}, { - "location": { - "latitude": 411733222, - "longitude": -744228360 - }, - "name": "" -}, { - "location": { - "latitude": 410248224, - "longitude": -747127767 - }, - "name": "3 Hasta Way, Newton, NJ 07860, USA" -}] diff --git a/php/.gitignore b/php/.gitignore deleted file mode 100644 index d8a7996ab3..0000000000 --- a/php/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -composer.lock -vendor/ diff --git a/php/README.md b/php/README.md deleted file mode 100644 index 247235adfd..0000000000 --- a/php/README.md +++ /dev/null @@ -1,64 +0,0 @@ -gRPC in 3 minutes (PHP) -=========================== - -PREREQUISITES -------------- - -This requires PHP 5.5 or greater. - -INSTALL -------- - - On Mac OS X, install [homebrew][]. On Linux, install [linuxbrew][]. Run the following command to install gRPC. - - ```sh - $ curl -fsSL https://goo.gl/getgrpc | bash -s php - ``` - This will download and run the [gRPC install script][] and compile the gRPC PHP extension. - - - Clone this repository - - ```sh - $ git clone https://github.com/grpc/grpc-common.git - ``` - - - Install composer - - ``` - $ cd grpc-common/php - $ curl -sS https://getcomposer.org/installer | php - $ php composer.phar install - ``` - -TRY IT! -------- - - - Run the server - - Please follow the instruction in [Node][] to run the server - ``` - $ cd grpc-common/node - $ nodejs greeter_server.js - ``` - - - Run the client - - ``` - $ cd grpc-common/php - $ ./run_greeter_client.sh - ``` - -NOTE ----- - -This directory has a copy of `helloworld.proto` because it currently depends on -some Protocol Buffer 2.0 syntax. There is no proto3 support for PHP yet. - -TUTORIAL --------- - -Coming soon - -[homebrew]:http://brew.sh -[linuxbrew]:https://github.com/Homebrew/linuxbrew#installation -[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install -[Node]:https://github.com/grpc/grpc-common/tree/master/node diff --git a/php/composer.json b/php/composer.json deleted file mode 100644 index f0ce3a2aff..0000000000 --- a/php/composer.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/stanley-cheung/Protobuf-PHP" - } - ], - "name": "grpc/grpc-demo", - "description": "gRPC example for PHP", - "minimum-stability": "dev", - "require": { - "php": ">=5.5.0", - "datto/protobuf-php": "dev-master", - "google/auth": "dev-master", - "grpc/grpc": "dev-master" - } -} diff --git a/php/greeter_client.php b/php/greeter_client.php deleted file mode 100644 index 8ae19ae46c..0000000000 --- a/php/greeter_client.php +++ /dev/null @@ -1,49 +0,0 @@ -setName($name); - list($reply, $status) = $client->SayHello($request)->wait(); - $message = $reply->getMessage(); - return $message; -} - -$name = !empty($argv[1]) ? $argv[1] : 'world'; -print(greet($name)."\n"); diff --git a/php/helloworld.php b/php/helloworld.php deleted file mode 100644 index 22da3d3970..0000000000 --- a/php/helloworld.php +++ /dev/null @@ -1,160 +0,0 @@ -number = 1; - $f->name = "name"; - $f->type = \DrSlump\Protobuf::TYPE_STRING; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasName(){ - return $this->_has(1); - } - - /** - * Clear value - * - * @return \helloworld\HelloRequest - */ - public function clearName(){ - return $this->_clear(1); - } - - /** - * Get value - * - * @return string - */ - public function getName(){ - return $this->_get(1); - } - - /** - * Set value - * - * @param string $value - * @return \helloworld\HelloRequest - */ - public function setName( $value){ - return $this->_set(1, $value); - } - } -} - -namespace helloworld { - - class HelloReply extends \DrSlump\Protobuf\Message { - - /** @var string */ - public $message = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloReply'); - - // OPTIONAL STRING message = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "message"; - $f->type = \DrSlump\Protobuf::TYPE_STRING; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasMessage(){ - return $this->_has(1); - } - - /** - * Clear value - * - * @return \helloworld\HelloReply - */ - public function clearMessage(){ - return $this->_clear(1); - } - - /** - * Get value - * - * @return string - */ - public function getMessage(){ - return $this->_get(1); - } - - /** - * Set value - * - * @param string $value - * @return \helloworld\HelloReply - */ - public function setMessage( $value){ - return $this->_set(1, $value); - } - } -} - -namespace helloworld { - - class GreeterClient{ - - private $rpc_impl; - - public function __construct($rpc_impl) { - $this->rpc_impl = $rpc_impl; - } - /** - * @param helloworld\HelloRequest $input - */ - public function SayHello(\helloworld\HelloRequest $argument, $metadata = array()) { - return $this->rpc_impl->_simpleRequest('/helloworld.Greeter/SayHello', $argument, '\helloworld\HelloReply::deserialize', $metadata); - } - } -} diff --git a/php/helloworld.proto b/php/helloworld.proto deleted file mode 100644 index ad8f7a1524..0000000000 --- a/php/helloworld.proto +++ /dev/null @@ -1,50 +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 = "proto2"; - -option java_package = "ex.grpc"; - -package helloworld; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - optional string name = 1; -} - -// The response message containing the greetings -message HelloReply { - optional string message = 1; -} diff --git a/php/route_guide/README.md b/php/route_guide/README.md deleted file mode 100644 index 084661a5eb..0000000000 --- a/php/route_guide/README.md +++ /dev/null @@ -1,262 +0,0 @@ -#gRPC Basics: PHP - -This tutorial provides a basic PHP programmer's introduction to working with gRPC. By walking through this example you'll learn how to: - -- Define a service in a .proto file. -- Generate client code using the protocol buffer compiler. -- Use the PHP gRPC API to write a simple client for your service. - -It assumes a passing familiarity with [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto2 version of the protocol buffers language. - -Also note that currently you can only create clients in PHP for gRPC services - you can find out how to create gRPC servers in our other tutorials, e.g. [Node.js](https://github.com/grpc/grpc-common/tree/master/node/route_guide). - -This isn't a comprehensive guide to using gRPC in PHP: more reference documentation is coming soon. - -- [Why use gRPC?](#why-grpc) -- [Example code and setup](#setup) -- [Try it out!](#try) -- [Defining the service](#proto) -- [Generating client code](#protoc) -- [Creating the client](#client) - - - -## Why use gRPC? - -With gRPC you can define your service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. You also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. - - - -## Example code and setup - -The example code for our tutorial is in [grpc/grpc-common/php/route_guide](https://github.com/grpc/grpc-common/tree/master/php/route_guide). To download the example, clone the `grpc-common` repository by running the following command: -```shell -$ git clone https://github.com/grpc/grpc-common.git -``` - -Then change your current directory to `grpc-common/php/route_guide`: -```shell -$ cd grpc-common/php/route_guide -``` - -Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. - -You also should have the relevant tools installed to generate the client interface code (and a server in another language, for testing). You can obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). - - - -## Try it out! - -To try the sample app, we need a gRPC server running locally. Let's compile and run, for example, the Node.js server in this repository: - -```shell -$ cd ../../node -$ npm install -$ cd route_guide -$ nodejs ./route_guide_server.js --db_path=route_guide_db.json -``` - -Run the PHP client (in a different terminal): - -```shell -$ ./run_route_guide_client.sh -``` - -The next sections guide you step-by-step through how this proto service is defined, how to generate a client library from it, and how to create a client stub that uses that library. - - - -## Defining the service - -First let's look at how the service we're using is defined. A gRPC *service* and its method *request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file for our example in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). - -To define a service, you specify a named `service` in your .proto file: - -```protobuf -service RouteGuide { - ... -} -``` - -Then you define `rpc` methods inside your service definition, specifying their request and response types. Protocol buffers let you define four kinds of service method, all of which are used in the `RouteGuide` service: - -- A *simple RPC* where the client sends a request to the server and receives a response later, just like a normal remote procedure call. -```protobuf - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} -``` - -- A *response-streaming RPC* where the client sends a request to the server and gets back a stream of response messages. You specify a response-streaming method by placing the `stream` keyword before the *response* type. -```protobuf - // 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 *request-streaming RPC* where the client sends a sequence of messages to the server. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a request-streaming method by placing the `stream` keyword before the *request* type. -```protobuf - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} -``` - -- A *bidirectional streaming RPC* where both sides send a sequence of messages to the other. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -```protobuf - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -``` - -Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -```protobuf -// 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; -} -``` - - - -## Generating client code - -The PHP client stub implementation of the proto files can be generated by the [`protoc-gen-php`](https://github.com/datto/protobuf-php) tool. To install the tool: - -```sh -$ cd grpc-common/php -$ php composer.phar install -$ cd vendor/datto/protobuf-php -$ gem install rake ronn -$ rake pear:package version=1.0 -$ sudo pear install Protobuf-1.0.tgz -``` - -To generate the client stub implementation .php file: - -```sh -$ cd php/route_guide -$ protoc-gen-php -i . -o . ./route_guide.proto -``` - -A `route_guide.php` file will be generated in the `php/route_guide` directory. You do not need to modify the file. - -To load the generated client stub file, simply `require` it in your PHP application: - -```php -require dirname(__FILE__) . '/route_guide.php'; -``` - -The file contains: -- All the protocol buffer code to populate, serialize, and retrieve our request and response message types. -- A class called `examples\RouteGuideClient` that lets clients call the methods defined in the `RouteGuide` service. - - - -## Creating the client - -In this section, we'll look at creating a PHP client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/php/route_guide/route_guide_client.php](https://github.com/grpc/grpc-common/blob/master/php/route_guide/route_guide_client.php). - -### Constructing a client object - -To call service methods, we first need to create a client object, an instance of the generated `RouteGuideClient` class. The constructor of the class expects the server address and port we want to connect to: - -```php -$client = new examples\RouteGuideClient(new Grpc\BaseStub('localhost:50051', [])); -``` - -### Calling service methods - -Now let's look at how we call our service methods. - -#### Simple RPC - -Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local asynchronous method. - -```php - $point = new examples\Point(); - $point->setLatitude(409146138); - $point->setLongitude(-746188906); - list($feature, $status) = $client->GetFeature($point)->wait(); -``` - -As you can see, we create and populate a request object, i.e. an `examples\Point` object. Then, we call the method on the stub, passing it the request object. If there is no error, then we can read the response information from the server from our response object, i.e. an `examples\Feature` object. - -```php - print sprintf("Found %s \n at %f, %f\n", $feature->getName(), - $feature->getLocation()->getLatitude() / COORD_FACTOR, - $feature->getLocation()->getLongitude() / COORD_FACTOR); -``` - -#### Streaming RPCs - -Now let's look at our streaming methods. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: - -```php - $lo_point = new examples\Point(); - $hi_point = new examples\Point(); - - $lo_point->setLatitude(400000000); - $lo_point->setLongitude(-750000000); - $hi_point->setLatitude(420000000); - $hi_point->setLongitude(-730000000); - - $rectangle = new examples\Rectangle(); - $rectangle->setLo($lo_point); - $rectangle->setHi($hi_point); - - $call = $client->ListFeatures($rectangle); - // an iterator over the server streaming responses - $features = $call->responses(); - foreach ($features as $feature) { - // process each feature - } // the loop will end when the server indicates there is no more responses to be sent. -``` - -The `$call->responses()` method call returns an iterator. When the server sends a response, a `$feature` object will be returned in the `foreach` loop, until the server indiciates that there will be no more responses to be sent. - -The client-side streaming method `RecordRoute` is similar, except there we pass the method an iterator and get back a `examples\RouteSummary`. - -```php - $points_iter = function($db) { - for ($i = 0; $i < $num_points; $i++) { - $point = new examples\Point(); - $point->setLatitude($lat); - $point->setLongitude($long); - yield $point; - } - }; - // $points_iter is an iterator simulating client streaming - list($route_summary, $status) = - $client->RecordRoute($points_iter($db))->wait(); -``` - -Finally, let's look at our bidirectional streaming RPC `routeChat()`. In this case, we just pass a context to the method and get back a `BidiStreamingCall` stream object, which we can use to both write and read messages. - -```php -$call = $client->RouteChat(); -``` - -To write messages from the client: - -```php - foreach ($notes as $n) { - $route_note = new examples\RouteNote(); - $call->write($route_note); - } - $call->writesDone(); -``` - -To read messages from the server: - -```php - while ($route_note_reply = $call->read()) { - // process $route_note_reply - } -``` - -Each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. diff --git a/php/route_guide/route_guide.php b/php/route_guide/route_guide.php deleted file mode 100644 index a836e03b55..0000000000 --- a/php/route_guide/route_guide.php +++ /dev/null @@ -1,731 +0,0 @@ -number = 1; - $f->name = "latitude"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->default = 0; - $descriptor->addField($f); - - // OPTIONAL INT32 longitude = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "longitude"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->default = 0; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasLatitude(){ - return $this->_has(1); - } - - /** - * Clear value - * - * @return \examples\Point - */ - public function clearLatitude(){ - return $this->_clear(1); - } - - /** - * Get value - * - * @return int - */ - public function getLatitude(){ - return $this->_get(1); - } - - /** - * Set value - * - * @param int $value - * @return \examples\Point - */ - public function setLatitude( $value){ - return $this->_set(1, $value); - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasLongitude(){ - return $this->_has(2); - } - - /** - * Clear value - * - * @return \examples\Point - */ - public function clearLongitude(){ - return $this->_clear(2); - } - - /** - * Get value - * - * @return int - */ - public function getLongitude(){ - return $this->_get(2); - } - - /** - * Set value - * - * @param int $value - * @return \examples\Point - */ - public function setLongitude( $value){ - return $this->_set(2, $value); - } - } -} - -namespace examples { - - class Rectangle extends \DrSlump\Protobuf\Message { - - /** @var \examples\Point */ - public $lo = null; - - /** @var \examples\Point */ - public $hi = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.Rectangle'); - - // OPTIONAL MESSAGE lo = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "lo"; - $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\examples\Point'; - $descriptor->addField($f); - - // OPTIONAL MESSAGE hi = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "hi"; - $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\examples\Point'; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasLo(){ - return $this->_has(1); - } - - /** - * Clear value - * - * @return \examples\Rectangle - */ - public function clearLo(){ - return $this->_clear(1); - } - - /** - * Get value - * - * @return \examples\Point - */ - public function getLo(){ - return $this->_get(1); - } - - /** - * Set value - * - * @param \examples\Point $value - * @return \examples\Rectangle - */ - public function setLo(\examples\Point $value){ - return $this->_set(1, $value); - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasHi(){ - return $this->_has(2); - } - - /** - * Clear value - * - * @return \examples\Rectangle - */ - public function clearHi(){ - return $this->_clear(2); - } - - /** - * Get value - * - * @return \examples\Point - */ - public function getHi(){ - return $this->_get(2); - } - - /** - * Set value - * - * @param \examples\Point $value - * @return \examples\Rectangle - */ - public function setHi(\examples\Point $value){ - return $this->_set(2, $value); - } - } -} - -namespace examples { - - class Feature extends \DrSlump\Protobuf\Message { - - /** @var string */ - public $name = null; - - /** @var \examples\Point */ - public $location = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.Feature'); - - // OPTIONAL STRING name = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "name"; - $f->type = \DrSlump\Protobuf::TYPE_STRING; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - // OPTIONAL MESSAGE location = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "location"; - $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\examples\Point'; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasName(){ - return $this->_has(1); - } - - /** - * Clear value - * - * @return \examples\Feature - */ - public function clearName(){ - return $this->_clear(1); - } - - /** - * Get value - * - * @return string - */ - public function getName(){ - return $this->_get(1); - } - - /** - * Set value - * - * @param string $value - * @return \examples\Feature - */ - public function setName( $value){ - return $this->_set(1, $value); - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasLocation(){ - return $this->_has(2); - } - - /** - * Clear value - * - * @return \examples\Feature - */ - public function clearLocation(){ - return $this->_clear(2); - } - - /** - * Get value - * - * @return \examples\Point - */ - public function getLocation(){ - return $this->_get(2); - } - - /** - * Set value - * - * @param \examples\Point $value - * @return \examples\Feature - */ - public function setLocation(\examples\Point $value){ - return $this->_set(2, $value); - } - } -} - -namespace examples { - - class RouteNote extends \DrSlump\Protobuf\Message { - - /** @var \examples\Point */ - public $location = null; - - /** @var string */ - public $message = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.RouteNote'); - - // OPTIONAL MESSAGE location = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "location"; - $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\examples\Point'; - $descriptor->addField($f); - - // OPTIONAL STRING message = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "message"; - $f->type = \DrSlump\Protobuf::TYPE_STRING; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasLocation(){ - return $this->_has(1); - } - - /** - * Clear value - * - * @return \examples\RouteNote - */ - public function clearLocation(){ - return $this->_clear(1); - } - - /** - * Get value - * - * @return \examples\Point - */ - public function getLocation(){ - return $this->_get(1); - } - - /** - * Set value - * - * @param \examples\Point $value - * @return \examples\RouteNote - */ - public function setLocation(\examples\Point $value){ - return $this->_set(1, $value); - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasMessage(){ - return $this->_has(2); - } - - /** - * Clear value - * - * @return \examples\RouteNote - */ - public function clearMessage(){ - return $this->_clear(2); - } - - /** - * Get value - * - * @return string - */ - public function getMessage(){ - return $this->_get(2); - } - - /** - * Set value - * - * @param string $value - * @return \examples\RouteNote - */ - public function setMessage( $value){ - return $this->_set(2, $value); - } - } -} - -namespace examples { - - class RouteSummary extends \DrSlump\Protobuf\Message { - - /** @var int */ - public $point_count = 0; - - /** @var int */ - public $feature_count = 0; - - /** @var int */ - public $distance = 0; - - /** @var int */ - public $elapsed_time = 0; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.RouteSummary'); - - // OPTIONAL INT32 point_count = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "point_count"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->default = 0; - $descriptor->addField($f); - - // OPTIONAL INT32 feature_count = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "feature_count"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->default = 0; - $descriptor->addField($f); - - // OPTIONAL INT32 distance = 3 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 3; - $f->name = "distance"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->default = 0; - $descriptor->addField($f); - - // OPTIONAL INT32 elapsed_time = 4 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 4; - $f->name = "elapsed_time"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->default = 0; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasPointCount(){ - return $this->_has(1); - } - - /** - * Clear value - * - * @return \examples\RouteSummary - */ - public function clearPointCount(){ - return $this->_clear(1); - } - - /** - * Get value - * - * @return int - */ - public function getPointCount(){ - return $this->_get(1); - } - - /** - * Set value - * - * @param int $value - * @return \examples\RouteSummary - */ - public function setPointCount( $value){ - return $this->_set(1, $value); - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasFeatureCount(){ - return $this->_has(2); - } - - /** - * Clear value - * - * @return \examples\RouteSummary - */ - public function clearFeatureCount(){ - return $this->_clear(2); - } - - /** - * Get value - * - * @return int - */ - public function getFeatureCount(){ - return $this->_get(2); - } - - /** - * Set value - * - * @param int $value - * @return \examples\RouteSummary - */ - public function setFeatureCount( $value){ - return $this->_set(2, $value); - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasDistance(){ - return $this->_has(3); - } - - /** - * Clear value - * - * @return \examples\RouteSummary - */ - public function clearDistance(){ - return $this->_clear(3); - } - - /** - * Get value - * - * @return int - */ - public function getDistance(){ - return $this->_get(3); - } - - /** - * Set value - * - * @param int $value - * @return \examples\RouteSummary - */ - public function setDistance( $value){ - return $this->_set(3, $value); - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasElapsedTime(){ - return $this->_has(4); - } - - /** - * Clear value - * - * @return \examples\RouteSummary - */ - public function clearElapsedTime(){ - return $this->_clear(4); - } - - /** - * Get value - * - * @return int - */ - public function getElapsedTime(){ - return $this->_get(4); - } - - /** - * Set value - * - * @param int $value - * @return \examples\RouteSummary - */ - public function setElapsedTime( $value){ - return $this->_set(4, $value); - } - } -} - -namespace examples { - - class RouteGuideClient{ - - private $rpc_impl; - - public function __construct($rpc_impl) { - $this->rpc_impl = $rpc_impl; - } - /** - * @param examples\Point $input - */ - public function GetFeature(\examples\Point $argument, $metadata = array()) { - return $this->rpc_impl->_simpleRequest('/examples.RouteGuide/GetFeature', $argument, '\examples\Feature::deserialize', $metadata); - } - /** - * @param examples\Rectangle $input - */ - public function ListFeatures($argument, $metadata = array()) { - return $this->rpc_impl->_serverStreamRequest('/examples.RouteGuide/ListFeatures', $argument, '\examples\Feature::deserialize', $metadata); - } - /** - * @param examples\Point $input - */ - public function RecordRoute($arguments, $metadata = array()) { - return $this->rpc_impl->_clientStreamRequest('/examples.RouteGuide/RecordRoute', $arguments, '\examples\RouteSummary::deserialize', $metadata); - } - /** - * @param examples\RouteNote $input - */ - public function RouteChat($metadata = array()) { - return $this->rpc_impl->_bidiRequest('/examples.RouteGuide/RouteChat', '\examples\RouteNote::deserialize', $metadata); - } - } -} diff --git a/php/route_guide/route_guide.proto b/php/route_guide/route_guide.proto deleted file mode 100644 index 0947184dbb..0000000000 --- a/php/route_guide/route_guide.proto +++ /dev/null @@ -1,120 +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 = "proto2"; - -option java_package = "io.grpc.examples"; - -package examples; - -// Interface exported by the server. -service RouteGuide { - // A simple RPC. - // - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} - - // A server-to-client streaming RPC. - // - // Obtains the Features available within the given Rectangle. Results are - // streamed rather than returned at once (e.g. in a response message with a - // repeated field), as the rectangle may cover a large area and contain a - // huge number of features. - rpc ListFeatures(Rectangle) returns (stream Feature) {} - - // A client-to-server streaming RPC. - // - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} - - // A Bidirectional streaming RPC. - // - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -} - -// Points are represented as latitude-longitude pairs in the E7 representation -// (degrees multiplied by 10**7 and rounded to the nearest integer). -// Latitudes should be in the range +/- 90 degrees and longitude should be in -// the range +/- 180 degrees (inclusive). -message Point { - optional int32 latitude = 1 [default = 0]; - optional int32 longitude = 2 [default = 0]; -} - -// A latitude-longitude rectangle, represented as two diagonally opposite -// points "lo" and "hi". -message Rectangle { - // One corner of the rectangle. - optional Point lo = 1; - - // The other corner of the rectangle. - optional Point hi = 2; -} - -// A feature names something at a given point. -// -// If a feature could not be named, the name is empty. -message Feature { - // The name of the feature. - optional string name = 1; - - // The point where the feature is detected. - optional Point location = 2; -} - -// A RouteNote is a message sent while at a given point. -message RouteNote { - // The location from which the message is sent. - optional Point location = 1; - - // The message to be sent. - optional string message = 2; -} - -// A RouteSummary is received in response to a RecordRoute rpc. -// -// It contains the number of individual points received, the number of -// detected features, and the total distance covered as the cumulative sum of -// the distance between each point. -message RouteSummary { - // The number of points received. - optional int32 point_count = 1 [default = 0]; - - // The number of known features passed while traversing the route. - optional int32 feature_count = 2 [default = 0]; - - // The distance covered in metres. - optional int32 distance = 3 [default = 0]; - - // The duration of the traversal in seconds. - optional int32 elapsed_time = 4 [default = 0]; -} diff --git a/php/route_guide/route_guide_client.php b/php/route_guide/route_guide_client.php deleted file mode 100644 index 6d9ae58b66..0000000000 --- a/php/route_guide/route_guide_client.php +++ /dev/null @@ -1,205 +0,0 @@ -getName(); - if (!$name) { - $name_str = "no feature"; - } else { - $name_str = "feature called $name"; - } - print sprintf("Found %s \n at %f, %f\n", $name_str, - $feature->getLocation()->getLatitude() / COORD_FACTOR, - $feature->getLocation()->getLongitude() / COORD_FACTOR); -} - -/** - * Run the getFeature demo. Calls getFeature with a point known to have a - * feature and a point known not to have a feature. - */ -function runGetFeature() { - print "Running GetFeature...\n"; - global $client; - - $point = new examples\Point(); - $points = array( - array(409146138, -746188906), - array(0, 0), - ); - - foreach ($points as $p) { - $point->setLatitude($p[0]); - $point->setLongitude($p[1]); - // make a unary grpc call - list($feature, $status) = $client->GetFeature($point)->wait(); - printFeature($feature); - } -} - -/** - * Run the listFeatures demo. Calls listFeatures with a rectangle - * containing all of the features in the pre-generated - * database. Prints each response as it comes in. - */ -function runListFeatures() { - print "Running ListFeatures...\n"; - global $client; - - $lo_point = new examples\Point(); - $hi_point = new examples\Point(); - - $lo_point->setLatitude(400000000); - $lo_point->setLongitude(-750000000); - $hi_point->setLatitude(420000000); - $hi_point->setLongitude(-730000000); - - $rectangle = new examples\Rectangle(); - $rectangle->setLo($lo_point); - $rectangle->setHi($hi_point); - - $call = $client->ListFeatures($rectangle); - // an iterator over the server streaming responses - $features = $call->responses(); - foreach ($features as $feature) { - printFeature($feature); - } -} - -/** - * Run the recordRoute demo. Sends several randomly chosen points from the - * pre-generated feature database with a variable delay in between. Prints - * the statistics when they are sent from the server. - */ -function runRecordRoute() { - print "Running RecordRoute...\n"; - global $client, $argv; - - $db = json_decode(file_get_contents($argv[1]), true); - $points_iter = function($db) { - $num_points_in_db = count($db); - $num_points = 10; - for ($i = 0; $i < $num_points; $i++) { - $point = new examples\Point(); - $index = rand(0, $num_points_in_db - 1); - $lat = $db[$index]['location']['latitude']; - $long = $db[$index]['location']['longitude']; - $feature_name = $db[$index]['name']; - $point->setLatitude($lat); - $point->setLongitude($long); - print sprintf("Visiting point %f, %f,\n with feature name: %s\n", - $lat / COORD_FACTOR, $long / COORD_FACTOR, - $feature_name ? $feature_name : ''); - usleep(rand(300000, 800000)); - yield $point; - } - }; - // $points_iter is an iterator simulating client streaming - list($route_summary, $status) = - $client->RecordRoute($points_iter($db))->wait(); - print sprintf("Finished trip with %d points\nPassed %d features\n". - "Travelled %d meters\nIt took %d seconds\n", - $route_summary->getPointCount(), - $route_summary->getFeatureCount(), - $route_summary->getDistance(), - $route_summary->getElapsedTime()); -} - -/** - * Run the routeChat demo. Send some chat messages, and print any chat - * messages that are sent from the server. - */ -function runRouteChat() { - print "Running RouteChat...\n"; - global $client; - - // start the bidirectional streaming call - $call = $client->RouteChat(); - - $notes = array( - array(1, 1, 'first message'), - array(1, 2, 'second message'), - array(2, 1, 'third message'), - array(1, 1, 'fourth message'), - array(1, 1, 'fifth message'), - ); - - foreach ($notes as $n) { - $point = new examples\Point(); - $point->setLatitude($lat = $n[0]); - $point->setLongitude($long = $n[1]); - - $route_note = new examples\RouteNote(); - $route_note->setLocation($point); - $route_note->setMessage($message = $n[2]); - - print sprintf("Sending message: '%s' at (%d, %d)\n", - $message, $lat, $long); - // send a bunch of messages to the server - $call->write($route_note); - } - $call->writesDone(); - - // read from the server until there's no more - while ($route_note_reply = $call->read()) { - print sprintf("Previous left message at (%d, %d): '%s'\n", - $route_note_reply->getLocation()->getLatitude(), - $route_note_reply->getLocation()->getLongitude(), - $route_note_reply->getMessage()); - } -} - -/** - * Run all of the demos in order - */ -function main() { - runGetFeature(); - runListFeatures(); - runRecordRoute(); - runRouteChat(); -} - -if (empty($argv[1])) { - print "Usage: php -d extension=grpc.so route_guide_client.php " . - "\n"; - exit(1); -} -main(); diff --git a/php/route_guide/run_route_guide_client.sh b/php/route_guide/run_route_guide_client.sh deleted file mode 100755 index e5ca07796b..0000000000 --- a/php/route_guide/run_route_guide_client.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -# 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. - -set -e -cd $(dirname $0) -command -v brew >/dev/null 2>&1 && \ - extension_dir="-d extension_dir="`brew --prefix`/opt/grpc-php -php $extension_dir -d extension=grpc.so \ - route_guide_client.php ../../node/route_guide/route_guide_db.json diff --git a/php/run_greeter_client.sh b/php/run_greeter_client.sh deleted file mode 100755 index 2906de9af8..0000000000 --- a/php/run_greeter_client.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash -# 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. - -set -e -cd $(dirname $0) -command -v brew >/dev/null 2>&1 && \ - extension_dir="-d extension_dir="`brew --prefix`/opt/grpc-php -php $extension_dir -d extension=grpc.so greeter_client.php $1 diff --git a/protos/README.md b/protos/README.md deleted file mode 100644 index 48df7c8943..0000000000 --- a/protos/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Example protos - -## Contents - -- [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/auth_sample.proto b/protos/auth_sample.proto deleted file mode 100644 index a49caca657..0000000000 --- a/protos/auth_sample.proto +++ /dev/null @@ -1,57 +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 grpc.testing; - -option objc_class_prefix = "AUTH"; - -// Unary request. -message Request { - // Whether Response should include username. - bool fill_username = 4; - - // Whether Response should include OAuth scope. - bool fill_oauth_scope = 5; -} - -// Unary response, as configured by the request. -message Response { - // The user the request came from, for verifying authentication was - // successful. - string username = 2; - // OAuth scope. - string oauth_scope = 3; -} - -service TestService { - // One request followed by one response. - rpc UnaryCall(Request) returns (Response); -} diff --git a/protos/hellostreamingworld.proto b/protos/hellostreamingworld.proto deleted file mode 100644 index bd5af3b2d5..0000000000 --- a/protos/hellostreamingworld.proto +++ /dev/null @@ -1,54 +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"; - -option java_package = "ex.grpc"; -option objc_class_prefix = "HSW"; - -package hellostreamingworld; - -// The greeting service definition. -service MultiGreeter { - // Sends multiple greetings - rpc sayHello (HelloRequest) returns (stream HelloReply) {} -} - -// The request message containing the user's name and how many greetings -// they want. -message HelloRequest { - string name = 1; - string num_greetings = 2; -} - -// A response message containing a greeting -message HelloReply { - string message = 1; -} - diff --git a/protos/helloworld.proto b/protos/helloworld.proto deleted file mode 100644 index 7d58870a70..0000000000 --- a/protos/helloworld.proto +++ /dev/null @@ -1,51 +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"; - -option java_package = "io.grpc.examples"; -option objc_class_prefix = "HLW"; - -package helloworld; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} diff --git a/protos/route_guide.proto b/protos/route_guide.proto deleted file mode 100644 index bfde5f1ead..0000000000 --- a/protos/route_guide.proto +++ /dev/null @@ -1,124 +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"; - -option java_package = "ex.grpc"; -option objc_class_prefix = "RTG"; - -package examples; - -// Interface exported by the server. -service RouteGuide { - // A simple RPC. - // - // Obtains the feature at a given position. - // - // A feature with an empty name is returned if there's no feature at the 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/python/helloworld/.gitignore b/python/helloworld/.gitignore deleted file mode 100644 index 0d20b6487c..0000000000 --- a/python/helloworld/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/python/helloworld/README.md b/python/helloworld/README.md deleted file mode 100644 index 0a6a718bae..0000000000 --- a/python/helloworld/README.md +++ /dev/null @@ -1,116 +0,0 @@ -# gRPC Python Hello World - -This is a quick introduction with a simple example and installation instructions: for a more complete tutorial see [gRPC Basics: Python](https://github.com/grpc/grpc-common/tree/master/python/route_guide). - -### Install gRPC -Make sure you have built gRPC Python from source on your system. Follow the instructions here: -[https://github.com/grpc/grpc/blob/master/src/python/README.md](https://github.com/grpc/grpc/blob/master/src/python/README.md). - -This gives you a python virtual environment with installed gRPC Python -in GRPC_ROOT/python2.7_virtual_environment. GRPC_ROOT is the path to which you -have cloned the [gRPC git repo](https://github.com/grpc/grpc). - -### Get the source code - -The example code for our Hello World and our other examples live in the `grpc-common` -GitHub repository. Clone this repository to your local machine by running the -following command: - - -```sh -$ git clone https://github.com/grpc/grpc-common.git -``` - -Change your current directory to grpc-common/python/helloworld - -```sh -$ cd grpc-common/python/helloworld/ -``` - -### Defining a service - -The first step in creating our example is to define a *service*: an RPC -service specifies the methods that can be called remotely with their parameters -and return types. As you saw in the -[overview](#protocolbuffers) above, gRPC does this using [protocol -buffers](https://developers.google.com/protocol-buffers/docs/overview). We -use the protocol buffers interface definition language (IDL) to define our -service methods, and define the parameters and return -types as protocol buffer message types. Both the client and the -server use interface code generated from the service definition. - -Here's our example service definition. The `Greeting` -service has one method, `hello`, that lets the server receive a single -`HelloRequest` -message from the remote client containing the user's name, then send back -a greeting in a single `HelloReply`. This is the simplest type of RPC you -can specify in gRPC. - -``` -syntax = "proto3"; - -option java_package = "io.grpc.examples"; - -package helloworld; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} - -``` - - -### Generating gRPC code - -Once we've defined our service, we use the protocol buffer compiler -`protoc` to generate the special client and server code we need to create -our application. The generated code contains both stub code for clients to -use and an abstract interface for servers to implement, both with the method -defined in our `Greeting` service. - -To generate the client and server side interfaces: - -```sh -$ ./run_codegen.sh -``` -Which internally invokes the proto-compiler as: - -```sh -$ protoc -I ../../protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` ../../protos/helloworld.proto -``` - -Optionally, you can just skip the code generation step as the generated python module has already -been generated for you (helloworld_pb2.py). - -### The client - -Client-side code can be found in [greeter_client.py](https://github.com/grpc/grpc-common/blob/master/python/helloworld/greeter_client.py). - -You can run the client using: - -```sh -$ ./run_client.sh -``` - - -### The server - -Server side code can be found in [greeter_server.py](https://github.com/grpc/grpc-common/blob/master/python/helloworld/greeter_server.py). - -You can run the server using: - -```sh -$ ./run_server.sh -``` diff --git a/python/helloworld/greeter_client.py b/python/helloworld/greeter_client.py deleted file mode 100755 index 370ce46770..0000000000 --- a/python/helloworld/greeter_client.py +++ /dev/null @@ -1,44 +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. - -"""The Python implementation of the GRPC helloworld.Greeter client.""" - -import helloworld_pb2 - -_TIMEOUT_SECONDS = 10 - - -def run(): - with helloworld_pb2.early_adopter_create_Greeter_stub('localhost', 50051) as stub: - response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'), _TIMEOUT_SECONDS) - print "Greeter client received: " + response.message - - -if __name__ == '__main__': - run() diff --git a/python/helloworld/greeter_server.py b/python/helloworld/greeter_server.py deleted file mode 100644 index 81353666b1..0000000000 --- a/python/helloworld/greeter_server.py +++ /dev/null @@ -1,56 +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. - -"""The Python implementation of the GRPC helloworld.Greeter server.""" - -import time - -import helloworld_pb2 - -_ONE_DAY_IN_SECONDS = 60 * 60 * 24 - - -class Greeter(helloworld_pb2.EarlyAdopterGreeterServicer): - - def SayHello(self, request, context): - return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) - - -def serve(): - server = helloworld_pb2.early_adopter_create_Greeter_server( - Greeter(), 50051, None, None) - server.start() - try: - while True: - time.sleep(_ONE_DAY_IN_SECONDS) - except KeyboardInterrupt: - server.stop() - -if __name__ == '__main__': - serve() diff --git a/python/helloworld/run_client.sh b/python/helloworld/run_client.sh deleted file mode 100755 index 095e6bc2f0..0000000000 --- a/python/helloworld/run_client.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -# This is where you have cloned out the https://github.com/grpc/grpc repository -# And built gRPC Python. -# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS -GRPC_ROOT=~/github/grpc - -$GRPC_ROOT/python2.7_virtual_environment/bin/python greeter_client.py diff --git a/python/helloworld/run_codegen.sh b/python/helloworld/run_codegen.sh deleted file mode 100755 index 4d826c7946..0000000000 --- a/python/helloworld/run_codegen.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -# Runs the protoc with gRPC plugin to generate protocol messages and gRPC stubs. -protoc -I ../../protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` ../../protos/helloworld.proto diff --git a/python/helloworld/run_server.sh b/python/helloworld/run_server.sh deleted file mode 100755 index 13b009e6cc..0000000000 --- a/python/helloworld/run_server.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -# This is where you have cloned out the https://github.com/grpc/grpc repository -# And built gRPC Python. -# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS -GRPC_ROOT=~/github/grpc - -$GRPC_ROOT/python2.7_virtual_environment/bin/python greeter_server.py - diff --git a/python/route_guide/.gitignore b/python/route_guide/.gitignore deleted file mode 100644 index 0d20b6487c..0000000000 --- a/python/route_guide/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/python/route_guide/README.md b/python/route_guide/README.md deleted file mode 100644 index 91bef0ac00..0000000000 --- a/python/route_guide/README.md +++ /dev/null @@ -1,303 +0,0 @@ -#gRPC Basics: Python - -This tutorial provides a basic Python programmer's introduction to working with gRPC. By walking through this example you'll learn how to: - -- Define a service in a .proto file. -- Generate server and client code using the protocol buffer compiler. -- Use the Python gRPC API to write a simple client and server for your service. - -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. - -This isn't a comprehensive guide to using gRPC in Python: more reference documentation is coming soon. - - -## Why use gRPC? - -This example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. - -With gRPC you can define your service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet, with all the complexity of communication between different languages and environments is handled for you by gRPC. You also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. - -## Example code and setup - -The example code for this tutorial is in [grpc/grpc-common/python/route_guide](https://github.com/grpc/grpc-common/tree/master/python/route_guide). To download the example, clone the `grpc-common` repository by running the following command: -```shell -$ git clone https://github.com/grpc/grpc-common.git -``` - -Then change your current directory to `grpc-common/python/route_guide`: -```shell -$ cd grpc-common/python/route_guide -``` - -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Python quick start guide](https://github.com/grpc/grpc-common/tree/master/python). - -## Defining the service - -Your first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). - -To define a service, you specify a named `service` in your .proto file: - -```protobuf -service RouteGuide { - // (Method definitions not shown) -} -``` - -Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: - -- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. -```protobuf - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} -``` - -- A *response-streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in the example, you specify a response-streaming method by placing the `stream` keyword before the *response* type. -```protobuf - // 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 *request-streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a request-streaming method by placing the `stream` keyword before the *request* type. -```protobuf - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} -``` - -- A *bidirectionally-streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -```protobuf - // 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) {} -``` - -Your .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -```protobuf -// 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; -} -``` - -## Generating client and server code - -Next you need to generate the gRPC client and server interfaces from your .proto service definition. You do this using the protocol buffer compiler `protoc` with a special gRPC Python plugin. Make sure you've installed protoc and followed the gRPC Python plugin [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): - -With `protoc` and the gRPC Python plugin installed, use the following command to generate the Python code: - -```shell -$ protoc -I ../../protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` ../../protos/route_guide.proto -``` - -Note that as we've already provided a version of the generated code in the example repository, running this command regenerates the appropriate file rather than creates a new one. The generated code file is called `route_guide_pb2.py` and contains: -- classes for the messages defined in route_guide.proto -- abstract classes for the service defined in route_guide.proto - - `EarlyAdopterRouteGuideServicer`, which defines the interface for implementations of the RouteGuide service - - `EarlyAdopterRouteGuideServer`, which may be started and stopped - - `EarlyAdopterRouteGuideStub`, which can be used by clients to invoke RouteGuide RPCs -- functions for application use - - `early_adopter_create_RouteGuide_server`, which creates a gRPC server given an `EarlyAdopterRouteGuideServicer` object - - `early_adopter_create_RouteGuide_stub`, which can be used by clients to create a stub object - - -## Creating the server - -First let's look at how you create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). - -Creating and running a `RouteGuide` server breaks down into two work items: -- Implementing the servicer interface generated from our service definition with functions that perform the actual "work" of the service. -- Running a gRPC server to listen for requests from clients and transmit responses. - -You can find the example `RouteGuide` server in [grpc-common/python/route_guide/route_guide_server.py](https://github.com/grpc/grpc-common/blob/master/python/route_guide/route_guide_server.py). - -### Implementing RouteGuide - -`route_guide_server.py` has a `RouteGuideServicer` class that implements the generated interface `route_guide_pb2.EarlyAdopterRouteGuideServicer`: - -```python -# RouteGuideServicer provides an implementation of the methods of the RouteGuide service. -class RouteGuideServicer(route_guide_pb2.EarlyAdopterRouteGuideServicer): -``` - -`RouteGuideServicer` implements all the `RouteGuide` service methods. - -#### Simple RPC - -Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. - -```python - def GetFeature(self, request, context): - feature = get_feature(self.db, request) - if feature is None: - return route_guide_pb2.Feature(name="", location=request) - else: - return feature -``` - -The method is passed a `route_guide_pb2.Point` request for the RPC, and an `RpcContext` object that provides RPC-specific information such as timeout limits. It returns a `route_guide_pb2.Feature` response. - -#### Response-streaming RPC - -Now let's look at the next method. `ListFeatures` is a response-streaming RPC that sends multiple `Feature`s to the client. - -```python - def ListFeatures(self, request, context): - left = min(request.lo.longitude, request.hi.longitude) - right = max(request.lo.longitude, request.hi.longitude) - top = max(request.lo.latitude, request.hi.latitude) - bottom = min(request.lo.latitude, request.hi.latitude) - for feature in self.db: - if (feature.location.longitude >= left and - feature.location.longitude <= right and - feature.location.latitude >= bottom and - feature.location.latitude <= top): - yield feature -``` - -Here the request message is a `route_guide_pb2.Rectangle` within which the client wants to find `Feature`s. Instead of returning a single response the method yields zero or more responses. - -#### Request-streaming RPC - -The request-streaming method `RecordRoute` uses an [iterator](https://docs.python.org/2/library/stdtypes.html#iterator-types) of request values and returns a single response value. - -```python - def RecordRoute(self, request_iterator, context): - point_count = 0 - feature_count = 0 - distance = 0.0 - prev_point = None - - start_time = time.time() - for point in request_iterator: - point_count += 1 - if get_feature(self.db, point): - feature_count += 1 - if prev_point: - distance += get_distance(prev_point, point) - prev_point = point - - elapsed_time = time.time() - start_time - return route_guide_pb2.RouteSummary(point_count=point_count, - feature_count=feature_count, - distance=int(distance), - elapsed_time=int(elapsed_time)) -``` - -#### Bidirectional streaming RPC - -Lastly let's look at the bidirectionally-streaming method `RouteChat`. - -```python - def RouteChat(self, request_iterator, context): - prev_notes = [] - for new_note in request_iterator: - for prev_note in prev_notes: - if prev_note.location == new_note.location: - yield prev_note - prev_notes.append(new_note) -``` - -This method's semantics are a combination of those of the request-streaming method and the response-streaming method. It is passed an iterator of request values and is itself an iterator of response values. - -### Starting the server - -Once you have implemented all the `RouteGuide` methods, the next step is to start up a gRPC server so that clients can actually use your service: - -```python -def serve(): - server = route_guide_pb2.early_adopter_create_RouteGuide_server( - RouteGuideServicer(), 50051, None, None) - server.start() -``` - -Because `start()` does not block you may need to sleep-loop if there is nothing else for your code to do while serving. - - -## Creating the client - -You can see the complete example client code in [grpc-common/python/route_guide/route_guide_client.py](https://github.com/grpc/grpc-common/blob/master/python/route_guide/route_guide_client.py). - -### Creating a stub - -To call service methods, we first need to create a *stub*. - -We use the `early_adopter_create_RouteGuide_stub` function of the `route_guide_pb2` module, generated from our .proto. - -```python -stub = RouteGuide::Stub.new('localhost', 50051) -``` - -The returned object implements all the methods defined by the `EarlyAdopterRouteGuideStub` interface, and is also a [context manager](https://docs.python.org/2/library/stdtypes.html#typecontextmanager). All RPCs invoked on the stub must be invoked within the stub's context, so it is common for stubs to be created and used with a [with statement](https://docs.python.org/2/reference/compound_stmts.html#the-with-statement): - -```python -with route_guide_pb2.early_adopter_create_RouteGuide_stub('localhost', 50051) as stub: -``` - -### Calling service methods - -For RPC methods that return a single response ("response-unary" methods), gRPC Python supports both synchronous (blocking) and asynchronous (non-blocking) control flow semantics. For response-streaming RPC methods, calls immediately return an iterator of response values. Calls to that iterator's `next()` method block until the response to be yielded from the iterator becomes available. - -#### Simple RPC - -A synchronous call to the simple RPC `GetFeature` is nearly as straightforward as calling a local method. The RPC call waits for the server to respond, and will either return a response or raise an exception: - -```python -feature = stub.GetFeature(point, timeout_in_seconds) -``` - -An asynchronous call to `GetFeature` is similar, but like calling a local method asynchronously in a thread pool: - -```python -feature_future = stub.GetFeature.async(point, timeout_in_seconds) -feature = feature_future.result() -``` - -#### Response-streaming RPC - -Calling the response-streaming `ListFeatures` is similar to working with sequence types: - -```python -for feature in stub.ListFeatures(rectangle, timeout_in_seconds): -``` - -#### Request-streaming RPC - -Calling the request-streaming `RecordRoute` is similar to passing a sequence to a local method. Like the simple RPC above that also returns a single response, it can be called synchronously or asynchronously: - -```python -route_summary = stub.RecordRoute(point_sequence, timeout_in_seconds) -``` - -```python -route_summary_future = stub.RecordRoute.async(point_sequence, timeout_in_seconds) -route_summary = route_summary_future.result() -``` - -#### Bidirectional streaming RPC - -Calling the bidirectionally-streaming `RouteChat` has (as is the case on the service-side) a combination of the request-streaming and response-streaming semantics: - -```python -for received_route_note in stub.RouteChat(sent_routes, timeout_in_seconds): -``` - -## Try it out! - -Run the server, which will listen on port 50051: - -```shell -$ python route_guide_server.py -``` - -Run the client (in a different terminal): - -```shell -$ python route_guide_client.py -``` diff --git a/python/route_guide/route_guide_client.py b/python/route_guide/route_guide_client.py deleted file mode 100755 index 078231543e..0000000000 --- a/python/route_guide/route_guide_client.py +++ /dev/null @@ -1,130 +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. - -"""The Python implementation of the gRPC route guide client.""" - -import random -import time - -import route_guide_pb2 -import route_guide_resources - -_TIMEOUT_SECONDS = 30 - - -def make_route_note(message, latitude, longitude): - return route_guide_pb2.RouteNote( - message=message, - location=route_guide_pb2.Point(latitude=latitude, longitude=longitude)) - - -def guide_get_one_feature(stub, point): - feature = stub.GetFeature(point, _TIMEOUT_SECONDS) - if not feature.location: - print "Server returned incomplete feature" - return - - if feature.name: - print "Feature called %s at %s" % (feature.name, feature.location) - else: - print "Found no feature at %s" % feature.location - - -def guide_get_feature(stub): - guide_get_one_feature(stub, route_guide_pb2.Point(latitude=409146138, longitude=-746188906)) - guide_get_one_feature(stub, route_guide_pb2.Point(latitude=0, longitude=0)) - - -def guide_list_features(stub): - rect = route_guide_pb2.Rectangle( - lo=route_guide_pb2.Point( - latitude=400000000, longitude = -750000000), - hi=route_guide_pb2.Point( - latitude = 420000000, longitude = -730000000)) - print "Looking for features between 40, -75 and 42, -73" - - features = stub.ListFeatures(rect, _TIMEOUT_SECONDS) - - for feature in features: - print "Feature called %s at %s" % (feature.name, feature.location) - - -def generate_route(feature_list): - for _ in range(0, 10): - random_feature = feature_list[random.randint(0, len(feature_list) - 1)] - print "Visiting point %s" % random_feature.location - yield random_feature.location - time.sleep(random.uniform(0.5, 1.5)) - - -def guide_record_route(stub): - feature_list = route_guide_resources.read_route_guide_database() - - route_iter = generate_route(feature_list) - route_summary = stub.RecordRoute(route_iter, _TIMEOUT_SECONDS) - print "Finished trip with %s points " % route_summary.point_count - print "Passed %s features " % route_summary.feature_count - print "Travelled %s meters " % route_summary.distance - print "It took %s seconds " % route_summary.elapsed_time - - -def generate_messages(): - messages = [ - make_route_note("First message", 0, 0), - make_route_note("Second message", 0, 1), - make_route_note("Third message", 1, 0), - make_route_note("Fourth message", 0, 0), - make_route_note("Fifth message", 1, 0), - ] - for msg in messages: - print "Sending %s at %s" % (msg.message, msg.location) - yield msg - time.sleep(random.uniform(0.5, 1.0)) - - -def guide_route_chat(stub): - responses = stub.RouteChat(generate_messages(), _TIMEOUT_SECONDS) - for response in responses: - print "Received message %s at %s" % (response.message, response.location) - - -def run(): - with route_guide_pb2.early_adopter_create_RouteGuide_stub('localhost', 50051) as stub: - print "-------------- GetFeature --------------" - guide_get_feature(stub) - print "-------------- ListFeatures --------------" - guide_list_features(stub) - print "-------------- RecordRoute --------------" - guide_record_route(stub) - print "-------------- RouteChat --------------" - guide_route_chat(stub) - - -if __name__ == '__main__': - run() diff --git a/python/route_guide/route_guide_db.json b/python/route_guide/route_guide_db.json deleted file mode 100644 index 9d6a980ab7..0000000000 --- a/python/route_guide/route_guide_db.json +++ /dev/null @@ -1,601 +0,0 @@ -[{ - "location": { - "latitude": 407838351, - "longitude": -746143763 - }, - "name": "Patriots Path, Mendham, NJ 07945, USA" -}, { - "location": { - "latitude": 408122808, - "longitude": -743999179 - }, - "name": "101 New Jersey 10, Whippany, NJ 07981, USA" -}, { - "location": { - "latitude": 413628156, - "longitude": -749015468 - }, - "name": "U.S. 6, Shohola, PA 18458, USA" -}, { - "location": { - "latitude": 419999544, - "longitude": -740371136 - }, - "name": "5 Conners Road, Kingston, NY 12401, USA" -}, { - "location": { - "latitude": 414008389, - "longitude": -743951297 - }, - "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" -}, { - "location": { - "latitude": 419611318, - "longitude": -746524769 - }, - "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" -}, { - "location": { - "latitude": 406109563, - "longitude": -742186778 - }, - "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" -}, { - "location": { - "latitude": 416802456, - "longitude": -742370183 - }, - "name": "352 South Mountain Road, Wallkill, NY 12589, USA" -}, { - "location": { - "latitude": 412950425, - "longitude": -741077389 - }, - "name": "Bailey Turn Road, Harriman, NY 10926, USA" -}, { - "location": { - "latitude": 412144655, - "longitude": -743949739 - }, - "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" -}, { - "location": { - "latitude": 415736605, - "longitude": -742847522 - }, - "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" -}, { - "location": { - "latitude": 413843930, - "longitude": -740501726 - }, - "name": "162 Merrill Road, Highland Mills, NY 10930, USA" -}, { - "location": { - "latitude": 410873075, - "longitude": -744459023 - }, - "name": "Clinton Road, West Milford, NJ 07480, USA" -}, { - "location": { - "latitude": 412346009, - "longitude": -744026814 - }, - "name": "16 Old Brook Lane, Warwick, NY 10990, USA" -}, { - "location": { - "latitude": 402948455, - "longitude": -747903913 - }, - "name": "3 Drake Lane, Pennington, NJ 08534, USA" -}, { - "location": { - "latitude": 406337092, - "longitude": -740122226 - }, - "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" -}, { - "location": { - "latitude": 406421967, - "longitude": -747727624 - }, - "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" -}, { - "location": { - "latitude": 416318082, - "longitude": -749677716 - }, - "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" -}, { - "location": { - "latitude": 415301720, - "longitude": -748416257 - }, - "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" -}, { - "location": { - "latitude": 402647019, - "longitude": -747071791 - }, - "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" -}, { - "location": { - "latitude": 412567807, - "longitude": -741058078 - }, - "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" -}, { - "location": { - "latitude": 416855156, - "longitude": -744420597 - }, - "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" -}, { - "location": { - "latitude": 404663628, - "longitude": -744820157 - }, - "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" -}, { - "location": { - "latitude": 407113723, - "longitude": -749746483 - }, - "name": "" -}, { - "location": { - "latitude": 402133926, - "longitude": -743613249 - }, - "name": "" -}, { - "location": { - "latitude": 400273442, - "longitude": -741220915 - }, - "name": "" -}, { - "location": { - "latitude": 411236786, - "longitude": -744070769 - }, - "name": "" -}, { - "location": { - "latitude": 411633782, - "longitude": -746784970 - }, - "name": "211-225 Plains Road, Augusta, NJ 07822, USA" -}, { - "location": { - "latitude": 415830701, - "longitude": -742952812 - }, - "name": "" -}, { - "location": { - "latitude": 413447164, - "longitude": -748712898 - }, - "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" -}, { - "location": { - "latitude": 405047245, - "longitude": -749800722 - }, - "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" -}, { - "location": { - "latitude": 418858923, - "longitude": -746156790 - }, - "name": "" -}, { - "location": { - "latitude": 417951888, - "longitude": -748484944 - }, - "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" -}, { - "location": { - "latitude": 407033786, - "longitude": -743977337 - }, - "name": "26 East 3rd Street, New Providence, NJ 07974, USA" -}, { - "location": { - "latitude": 417548014, - "longitude": -740075041 - }, - "name": "" -}, { - "location": { - "latitude": 410395868, - "longitude": -744972325 - }, - "name": "" -}, { - "location": { - "latitude": 404615353, - "longitude": -745129803 - }, - "name": "" -}, { - "location": { - "latitude": 406589790, - "longitude": -743560121 - }, - "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" -}, { - "location": { - "latitude": 414653148, - "longitude": -740477477 - }, - "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" -}, { - "location": { - "latitude": 405957808, - "longitude": -743255336 - }, - "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" -}, { - "location": { - "latitude": 411733589, - "longitude": -741648093 - }, - "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" -}, { - "location": { - "latitude": 412676291, - "longitude": -742606606 - }, - "name": "1270 Lakes Road, Monroe, NY 10950, USA" -}, { - "location": { - "latitude": 409224445, - "longitude": -748286738 - }, - "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" -}, { - "location": { - "latitude": 406523420, - "longitude": -742135517 - }, - "name": "652 Garden Street, Elizabeth, NJ 07202, USA" -}, { - "location": { - "latitude": 401827388, - "longitude": -740294537 - }, - "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" -}, { - "location": { - "latitude": 410564152, - "longitude": -743685054 - }, - "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" -}, { - "location": { - "latitude": 408472324, - "longitude": -740726046 - }, - "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" -}, { - "location": { - "latitude": 412452168, - "longitude": -740214052 - }, - "name": "5 White Oak Lane, Stony Point, NY 10980, USA" -}, { - "location": { - "latitude": 409146138, - "longitude": -746188906 - }, - "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" -}, { - "location": { - "latitude": 404701380, - "longitude": -744781745 - }, - "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" -}, { - "location": { - "latitude": 409642566, - "longitude": -746017679 - }, - "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" -}, { - "location": { - "latitude": 408031728, - "longitude": -748645385 - }, - "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" -}, { - "location": { - "latitude": 413700272, - "longitude": -742135189 - }, - "name": "367 Prospect Road, Chester, NY 10918, USA" -}, { - "location": { - "latitude": 404310607, - "longitude": -740282632 - }, - "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" -}, { - "location": { - "latitude": 409319800, - "longitude": -746201391 - }, - "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" -}, { - "location": { - "latitude": 406685311, - "longitude": -742108603 - }, - "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" -}, { - "location": { - "latitude": 419018117, - "longitude": -749142781 - }, - "name": "43 Dreher Road, Roscoe, NY 12776, USA" -}, { - "location": { - "latitude": 412856162, - "longitude": -745148837 - }, - "name": "Swan Street, Pine Island, NY 10969, USA" -}, { - "location": { - "latitude": 416560744, - "longitude": -746721964 - }, - "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" -}, { - "location": { - "latitude": 405314270, - "longitude": -749836354 - }, - "name": "" -}, { - "location": { - "latitude": 414219548, - "longitude": -743327440 - }, - "name": "" -}, { - "location": { - "latitude": 415534177, - "longitude": -742900616 - }, - "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" -}, { - "location": { - "latitude": 406898530, - "longitude": -749127080 - }, - "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" -}, { - "location": { - "latitude": 407586880, - "longitude": -741670168 - }, - "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" -}, { - "location": { - "latitude": 400106455, - "longitude": -742870190 - }, - "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" -}, { - "location": { - "latitude": 400066188, - "longitude": -746793294 - }, - "name": "" -}, { - "location": { - "latitude": 418803880, - "longitude": -744102673 - }, - "name": "40 Mountain Road, Napanoch, NY 12458, USA" -}, { - "location": { - "latitude": 414204288, - "longitude": -747895140 - }, - "name": "" -}, { - "location": { - "latitude": 414777405, - "longitude": -740615601 - }, - "name": "" -}, { - "location": { - "latitude": 415464475, - "longitude": -747175374 - }, - "name": "48 North Road, Forestburgh, NY 12777, USA" -}, { - "location": { - "latitude": 404062378, - "longitude": -746376177 - }, - "name": "" -}, { - "location": { - "latitude": 405688272, - "longitude": -749285130 - }, - "name": "" -}, { - "location": { - "latitude": 400342070, - "longitude": -748788996 - }, - "name": "" -}, { - "location": { - "latitude": 401809022, - "longitude": -744157964 - }, - "name": "" -}, { - "location": { - "latitude": 404226644, - "longitude": -740517141 - }, - "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" -}, { - "location": { - "latitude": 410322033, - "longitude": -747871659 - }, - "name": "" -}, { - "location": { - "latitude": 407100674, - "longitude": -747742727 - }, - "name": "" -}, { - "location": { - "latitude": 418811433, - "longitude": -741718005 - }, - "name": "213 Bush Road, Stone Ridge, NY 12484, USA" -}, { - "location": { - "latitude": 415034302, - "longitude": -743850945 - }, - "name": "" -}, { - "location": { - "latitude": 411349992, - "longitude": -743694161 - }, - "name": "" -}, { - "location": { - "latitude": 404839914, - "longitude": -744759616 - }, - "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" -}, { - "location": { - "latitude": 414638017, - "longitude": -745957854 - }, - "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" -}, { - "location": { - "latitude": 412127800, - "longitude": -740173578 - }, - "name": "" -}, { - "location": { - "latitude": 401263460, - "longitude": -747964303 - }, - "name": "" -}, { - "location": { - "latitude": 412843391, - "longitude": -749086026 - }, - "name": "" -}, { - "location": { - "latitude": 418512773, - "longitude": -743067823 - }, - "name": "" -}, { - "location": { - "latitude": 404318328, - "longitude": -740835638 - }, - "name": "42-102 Main Street, Belford, NJ 07718, USA" -}, { - "location": { - "latitude": 419020746, - "longitude": -741172328 - }, - "name": "" -}, { - "location": { - "latitude": 404080723, - "longitude": -746119569 - }, - "name": "" -}, { - "location": { - "latitude": 401012643, - "longitude": -744035134 - }, - "name": "" -}, { - "location": { - "latitude": 404306372, - "longitude": -741079661 - }, - "name": "" -}, { - "location": { - "latitude": 403966326, - "longitude": -748519297 - }, - "name": "" -}, { - "location": { - "latitude": 405002031, - "longitude": -748407866 - }, - "name": "" -}, { - "location": { - "latitude": 409532885, - "longitude": -742200683 - }, - "name": "" -}, { - "location": { - "latitude": 416851321, - "longitude": -742674555 - }, - "name": "" -}, { - "location": { - "latitude": 406411633, - "longitude": -741722051 - }, - "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" -}, { - "location": { - "latitude": 413069058, - "longitude": -744597778 - }, - "name": "261 Van Sickle Road, Goshen, NY 10924, USA" -}, { - "location": { - "latitude": 418465462, - "longitude": -746859398 - }, - "name": "" -}, { - "location": { - "latitude": 411733222, - "longitude": -744228360 - }, - "name": "" -}, { - "location": { - "latitude": 410248224, - "longitude": -747127767 - }, - "name": "3 Hasta Way, Newton, NJ 07860, USA" -}] diff --git a/python/route_guide/route_guide_pb2.py b/python/route_guide/route_guide_pb2.py deleted file mode 100644 index 2a4532bb75..0000000000 --- a/python/route_guide/route_guide_pb2.py +++ /dev/null @@ -1,370 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: route_guide.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='route_guide.proto', - package='', - serialized_pb=_b('\n\x11route_guide.proto\",\n\x05Point\x12\x10\n\x08latitude\x18\x01 \x01(\x05\x12\x11\n\tlongitude\x18\x02 \x01(\x05\"3\n\tRectangle\x12\x12\n\x02lo\x18\x01 \x01(\x0b\x32\x06.Point\x12\x12\n\x02hi\x18\x02 \x01(\x0b\x32\x06.Point\"1\n\x07\x46\x65\x61ture\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x18\n\x08location\x18\x02 \x01(\x0b\x32\x06.Point\"6\n\tRouteNote\x12\x18\n\x08location\x18\x01 \x01(\x0b\x32\x06.Point\x12\x0f\n\x07message\x18\x02 \x01(\t\"b\n\x0cRouteSummary\x12\x13\n\x0bpoint_count\x18\x01 \x01(\x05\x12\x15\n\rfeature_count\x18\x02 \x01(\x05\x12\x10\n\x08\x64istance\x18\x03 \x01(\x05\x12\x14\n\x0c\x65lapsed_time\x18\x04 \x01(\x05\x32\xad\x01\n\nRouteGuide\x12 \n\nGetFeature\x12\x06.Point\x1a\x08.Feature\"\x00\x12(\n\x0cListFeatures\x12\n.Rectangle\x1a\x08.Feature\"\x00\x30\x01\x12(\n\x0bRecordRoute\x12\x06.Point\x1a\r.RouteSummary\"\x00(\x01\x12)\n\tRouteChat\x12\n.RouteNote\x1a\n.RouteNote\"\x00(\x01\x30\x01') -) -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - - - - -_POINT = _descriptor.Descriptor( - name='Point', - full_name='Point', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='latitude', full_name='Point.latitude', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='longitude', full_name='Point.longitude', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - serialized_start=21, - serialized_end=65, -) - - -_RECTANGLE = _descriptor.Descriptor( - name='Rectangle', - full_name='Rectangle', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='lo', full_name='Rectangle.lo', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='hi', full_name='Rectangle.hi', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - serialized_start=67, - serialized_end=118, -) - - -_FEATURE = _descriptor.Descriptor( - name='Feature', - full_name='Feature', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='Feature.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='location', full_name='Feature.location', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - serialized_start=120, - serialized_end=169, -) - - -_ROUTENOTE = _descriptor.Descriptor( - name='RouteNote', - full_name='RouteNote', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='location', full_name='RouteNote.location', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='message', full_name='RouteNote.message', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - serialized_start=171, - serialized_end=225, -) - - -_ROUTESUMMARY = _descriptor.Descriptor( - name='RouteSummary', - full_name='RouteSummary', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='point_count', full_name='RouteSummary.point_count', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='feature_count', full_name='RouteSummary.feature_count', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='distance', full_name='RouteSummary.distance', index=2, - number=3, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='elapsed_time', full_name='RouteSummary.elapsed_time', index=3, - number=4, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - serialized_start=227, - serialized_end=325, -) - -_RECTANGLE.fields_by_name['lo'].message_type = _POINT -_RECTANGLE.fields_by_name['hi'].message_type = _POINT -_FEATURE.fields_by_name['location'].message_type = _POINT -_ROUTENOTE.fields_by_name['location'].message_type = _POINT -DESCRIPTOR.message_types_by_name['Point'] = _POINT -DESCRIPTOR.message_types_by_name['Rectangle'] = _RECTANGLE -DESCRIPTOR.message_types_by_name['Feature'] = _FEATURE -DESCRIPTOR.message_types_by_name['RouteNote'] = _ROUTENOTE -DESCRIPTOR.message_types_by_name['RouteSummary'] = _ROUTESUMMARY - -Point = _reflection.GeneratedProtocolMessageType('Point', (_message.Message,), dict( - DESCRIPTOR = _POINT, - __module__ = 'route_guide_pb2' - # @@protoc_insertion_point(class_scope:Point) - )) -_sym_db.RegisterMessage(Point) - -Rectangle = _reflection.GeneratedProtocolMessageType('Rectangle', (_message.Message,), dict( - DESCRIPTOR = _RECTANGLE, - __module__ = 'route_guide_pb2' - # @@protoc_insertion_point(class_scope:Rectangle) - )) -_sym_db.RegisterMessage(Rectangle) - -Feature = _reflection.GeneratedProtocolMessageType('Feature', (_message.Message,), dict( - DESCRIPTOR = _FEATURE, - __module__ = 'route_guide_pb2' - # @@protoc_insertion_point(class_scope:Feature) - )) -_sym_db.RegisterMessage(Feature) - -RouteNote = _reflection.GeneratedProtocolMessageType('RouteNote', (_message.Message,), dict( - DESCRIPTOR = _ROUTENOTE, - __module__ = 'route_guide_pb2' - # @@protoc_insertion_point(class_scope:RouteNote) - )) -_sym_db.RegisterMessage(RouteNote) - -RouteSummary = _reflection.GeneratedProtocolMessageType('RouteSummary', (_message.Message,), dict( - DESCRIPTOR = _ROUTESUMMARY, - __module__ = 'route_guide_pb2' - # @@protoc_insertion_point(class_scope:RouteSummary) - )) -_sym_db.RegisterMessage(RouteSummary) - - -import abc -from grpc._adapter import fore -from grpc._adapter import rear -from grpc.framework.assembly import implementations -from grpc.framework.assembly import utilities -class EarlyAdopterRouteGuideServicer(object): - """""" - __metaclass__ = abc.ABCMeta - @abc.abstractmethod - def GetFeature(self, request): - raise NotImplementedError() - @abc.abstractmethod - def ListFeatures(self, request): - raise NotImplementedError() - @abc.abstractmethod - def RecordRoute(self, request_iterator): - raise NotImplementedError() - @abc.abstractmethod - def RouteChat(self, request_iterator): - raise NotImplementedError() -class EarlyAdopterRouteGuideServer(object): - """""" - __metaclass__ = abc.ABCMeta - @abc.abstractmethod - def start(self): - raise NotImplementedError() - @abc.abstractmethod - def stop(self): - raise NotImplementedError() -class EarlyAdopterRouteGuideStub(object): - """""" - __metaclass__ = abc.ABCMeta - @abc.abstractmethod - def GetFeature(self, request): - raise NotImplementedError() - GetFeature.async = None - @abc.abstractmethod - def ListFeatures(self, request): - raise NotImplementedError() - ListFeatures.async = None - @abc.abstractmethod - def RecordRoute(self, request_iterator): - raise NotImplementedError() - RecordRoute.async = None - @abc.abstractmethod - def RouteChat(self, request_iterator): - raise NotImplementedError() - RouteChat.async = None -def early_adopter_create_RouteGuide_server(servicer, port, root_certificates, key_chain_pairs): - method_implementations = { - "GetFeature": utilities.unary_unary_inline(servicer.GetFeature), - "ListFeatures": utilities.unary_stream_inline(servicer.ListFeatures), - "RecordRoute": utilities.stream_unary_inline(servicer.RecordRoute), - "RouteChat": utilities.stream_stream_inline(servicer.RouteChat), - } - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - request_deserializers = { - "GetFeature": route_guide_pb2.Point.FromString, - "ListFeatures": route_guide_pb2.Rectangle.FromString, - "RecordRoute": route_guide_pb2.Point.FromString, - "RouteChat": route_guide_pb2.RouteNote.FromString, - } - response_serializers = { - "GetFeature": lambda x: x.SerializeToString(), - "ListFeatures": lambda x: x.SerializeToString(), - "RecordRoute": lambda x: x.SerializeToString(), - "RouteChat": lambda x: x.SerializeToString(), - } - link = fore.activated_fore_link(port, request_deserializers, response_serializers, root_certificates, key_chain_pairs) - return implementations.assemble_service(method_implementations, link) -def early_adopter_create_RouteGuide_stub(host, port): - method_implementations = { - "GetFeature": utilities.unary_unary_inline(None), - "ListFeatures": utilities.unary_stream_inline(None), - "RecordRoute": utilities.stream_unary_inline(None), - "RouteChat": utilities.stream_stream_inline(None), - } - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - response_deserializers = { - "GetFeature": route_guide_pb2.Feature.FromString, - "ListFeatures": route_guide_pb2.Feature.FromString, - "RecordRoute": route_guide_pb2.RouteSummary.FromString, - "RouteChat": route_guide_pb2.RouteNote.FromString, - } - request_serializers = { - "GetFeature": lambda x: x.SerializeToString(), - "ListFeatures": lambda x: x.SerializeToString(), - "RecordRoute": lambda x: x.SerializeToString(), - "RouteChat": lambda x: x.SerializeToString(), - } - link = rear.activated_rear_link(host, port, request_serializers, response_deserializers) - return implementations.assemble_dynamic_inline_stub(method_implementations, link) -# @@protoc_insertion_point(module_scope) diff --git a/python/route_guide/route_guide_resources.py b/python/route_guide/route_guide_resources.py deleted file mode 100755 index 30c7711019..0000000000 --- a/python/route_guide/route_guide_resources.py +++ /dev/null @@ -1,53 +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. - -"""Common resources used in the gRPC route guide example.""" - -import json - -import route_guide_pb2 - - -def read_route_guide_database(): - """Reads the route guide database. - - Returns: - The full contents of the route guide database as a sequence of - route_guide_pb2.Features. - """ - feature_list = [] - with open("route_guide_db.json") as route_guide_db_file: - for item in json.load(route_guide_db_file): - feature = route_guide_pb2.Feature( - name=item["name"], - location=route_guide_pb2.Point( - latitude=item["location"]["latitude"], - longitude=item["location"]["longitude"])) - feature_list.append(feature) - return feature_list diff --git a/python/route_guide/route_guide_server.py b/python/route_guide/route_guide_server.py deleted file mode 100644 index 44bbacf5f3..0000000000 --- a/python/route_guide/route_guide_server.py +++ /dev/null @@ -1,134 +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. - -"""The Python implementation of the gRPC route guide server.""" - -import time -import math - -import route_guide_pb2 -import route_guide_resources - -_ONE_DAY_IN_SECONDS = 60 * 60 * 24 - - -def get_feature(feature_db, point): - """Returns Feature at given location or None.""" - for feature in feature_db: - if feature.location == point: - return feature - return None - - -def get_distance(start, end): - """Distance between two points.""" - coord_factor = 10000000.0 - lat_1 = start.latitude / coord_factor - lat_2 = end.latitude / coord_factor - lon_1 = start.latitude / coord_factor - lon_2 = end.longitude / coord_factor - lat_rad_1 = math.radians(lat_1) - lat_rad_2 = math.radians(lat_2) - delta_lat_rad = math.radians(lat_2 - lat_1) - delta_lon_rad = math.radians(lon_2 - lon_1) - - a = (pow(math.sin(delta_lat_rad / 2), 2) + - (math.cos(lat_rad_1) * math.cos(lat_rad_2) * - pow(math.sin(delta_lon_rad / 2), 2))) - c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) - R = 6371000; # metres - return R * c; - -class RouteGuideServicer(route_guide_pb2.EarlyAdopterRouteGuideServicer): - """Provides methods that implement functionality of route guide server.""" - - def __init__(self): - self.db = route_guide_resources.read_route_guide_database() - - def GetFeature(self, request, context): - feature = get_feature(self.db, request) - if feature is None: - return route_guide_pb2.Feature(name="", location=request) - else: - return feature - - def ListFeatures(self, request, context): - left = min(request.lo.longitude, request.hi.longitude) - right = max(request.lo.longitude, request.hi.longitude) - top = max(request.lo.latitude, request.hi.latitude) - bottom = min(request.lo.latitude, request.hi.latitude) - for feature in self.db: - if (feature.location.longitude >= left and - feature.location.longitude <= right and - feature.location.latitude >= bottom and - feature.location.latitude <= top): - yield feature - - def RecordRoute(self, request_iterator, context): - point_count = 0 - feature_count = 0 - distance = 0.0 - prev_point = None - - start_time = time.time() - for point in request_iterator: - point_count += 1 - if get_feature(self.db, point): - feature_count += 1 - if prev_point: - distance += get_distance(prev_point, point) - prev_point = point - - elapsed_time = time.time() - start_time - return route_guide_pb2.RouteSummary(point_count=point_count, - feature_count=feature_count, - distance=int(distance), - elapsed_time=int(elapsed_time)) - - def RouteChat(self, request_iterator, context): - prev_notes = [] - for new_note in request_iterator: - for prev_note in prev_notes: - if prev_note.location == new_note.location: - yield prev_note - prev_notes.append(new_note) - - -def serve(): - server = route_guide_pb2.early_adopter_create_RouteGuide_server( - RouteGuideServicer(), 50051, None, None) - server.start() - try: - while True: - time.sleep(_ONE_DAY_IN_SECONDS) - except KeyboardInterrupt: - server.stop() - -if __name__ == '__main__': - serve() diff --git a/python/route_guide/run_client.sh b/python/route_guide/run_client.sh deleted file mode 100755 index d2552c2858..0000000000 --- a/python/route_guide/run_client.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -# This is where you have cloned out the https://github.com/grpc/grpc repository -# And built gRPC Python. -# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS -GRPC_ROOT=~/github/grpc - -$GRPC_ROOT/python2.7_virtual_environment/bin/python -B route_guide_client.py diff --git a/python/route_guide/run_codegen.sh b/python/route_guide/run_codegen.sh deleted file mode 100755 index 689e0978de..0000000000 --- a/python/route_guide/run_codegen.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -# Runs the protoc with gRPC plugin to generate protocol messages and gRPC stubs. -protoc -I . --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` route_guide.proto diff --git a/python/route_guide/run_server.sh b/python/route_guide/run_server.sh deleted file mode 100755 index 8f759250c8..0000000000 --- a/python/route_guide/run_server.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -# This is where you have cloned out the https://github.com/grpc/grpc repository -# And built gRPC Python. -# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS -GRPC_ROOT=~/github/grpc - -$GRPC_ROOT/python2.7_virtual_environment/bin/python -B route_guide_server.py diff --git a/ruby/.gitignore b/ruby/.gitignore deleted file mode 100644 index 62fcb4fa94..0000000000 --- a/ruby/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -/.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 deleted file mode 100644 index 65d3f0ad4a..0000000000 --- a/ruby/Gemfile +++ /dev/null @@ -1,6 +0,0 @@ -# -*- ruby -*- -# encoding: utf-8 - -source 'https://rubygems.org/' - -gem 'grpc', :git => 'https://github.com/grpc/grpc.git', :submodules => true, glob: 'src/ruby/*.gemspec' diff --git a/ruby/README.md b/ruby/README.md deleted file mode 100644 index fecd8041e0..0000000000 --- a/ruby/README.md +++ /dev/null @@ -1,61 +0,0 @@ -gRPC in 3 minutes (Ruby) -======================== - -BACKGROUND -------------- -For this sample, we've already generated the server and client stubs from [helloworld.proto][] - -PREREQUISITES -------------- - -- Ruby 2.x -This requires Ruby 2.x, as the gRPC API surface uses keyword args. -If you don't have that installed locally, you can use [RVM][] to use Ruby 2.x for testing without upgrading the version of Ruby on your whole system. -RVM is also useful if you don't have the necessary privileges to update your system's Ruby. - - ```sh - $ # RVM installation as specified at https://rvm.io/rvm/install - $ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 - $ \curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2 - $ - $ # follow the instructions to ensure that your're using the latest stable version of Ruby - $ # and that the rvm command is installed - ``` -- *N.B* Make sure your run `source $HOME/.rvm/scripts/rvm` as instructed to complete the set-up of RVM. - -INSTALL -------- - -- Clone this repository -- Use bundler to install the example package's dependencies - - ```sh - $ # from this directory - $ gem install bundler # if you don't already have bundler available - $ bundle install - ``` - -Try it! -------- - -- Run the server - - ```sh - $ # from this directory - $ bundle exec ./greeter_server.rb & - ``` - -- Run the client - - ```sh - $ # from this directory - $ bundle exec ./greeter_client.rb - ``` - -Tutorial --------- - -You can find a more detailed tutorial in [gRPC Basics: Ruby](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/README.md) - -[helloworld.proto]:https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto -[RVM]:https://www.rvm.io/ diff --git a/ruby/greeter_client.rb b/ruby/greeter_client.rb deleted file mode 100755 index e6cb4bad33..0000000000 --- a/ruby/greeter_client.rb +++ /dev/null @@ -1,50 +0,0 @@ -#!/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 deleted file mode 100755 index d4f9cf7d0f..0000000000 --- a/ruby/greeter_server.rb +++ /dev/null @@ -1,60 +0,0 @@ -#!/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/grpc-demo.gemspec b/ruby/grpc-demo.gemspec deleted file mode 100644 index fa69eb20c1..0000000000 --- a/ruby/grpc-demo.gemspec +++ /dev/null @@ -1,23 +0,0 @@ -# -*- ruby -*- -# encoding: utf-8 - -Gem::Specification.new do |s| - s.name = 'grpc-demo' - s.version = '0.5.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 ruby/route_guide/*.rb`.split("\n").map do |f| - File.basename(f) - end - s.require_paths = ['lib'] - s.platform = Gem::Platform::RUBY - - s.add_dependency 'grpc', '~> 0.6' - - s.add_development_dependency 'bundler', '~> 1.7' -end diff --git a/ruby/lib/helloworld.rb b/ruby/lib/helloworld.rb deleted file mode 100644 index 82bdd78e2a..0000000000 --- a/ruby/lib/helloworld.rb +++ /dev/null @@ -1,18 +0,0 @@ -# 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 deleted file mode 100644 index 7da45ebc6b..0000000000 --- a/ruby/lib/helloworld_services.rb +++ /dev/null @@ -1,24 +0,0 @@ -# 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 diff --git a/ruby/lib/route_guide.rb b/ruby/lib/route_guide.rb deleted file mode 100644 index 98bac8395c..0000000000 --- a/ruby/lib/route_guide.rb +++ /dev/null @@ -1,37 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: route_guide.proto - -require 'google/protobuf' - -Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "examples.Point" do - optional :latitude, :int32, 1 - optional :longitude, :int32, 2 - end - add_message "examples.Rectangle" do - optional :lo, :message, 1, "examples.Point" - optional :hi, :message, 2, "examples.Point" - end - add_message "examples.Feature" do - optional :name, :string, 1 - optional :location, :message, 2, "examples.Point" - end - add_message "examples.RouteNote" do - optional :location, :message, 1, "examples.Point" - optional :message, :string, 2 - end - add_message "examples.RouteSummary" do - optional :point_count, :int32, 1 - optional :feature_count, :int32, 2 - optional :distance, :int32, 3 - optional :elapsed_time, :int32, 4 - end -end - -module Examples - Point = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.Point").msgclass - Rectangle = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.Rectangle").msgclass - Feature = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.Feature").msgclass - RouteNote = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.RouteNote").msgclass - RouteSummary = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.RouteSummary").msgclass -end diff --git a/ruby/lib/route_guide_services.rb b/ruby/lib/route_guide_services.rb deleted file mode 100644 index 6e07653c42..0000000000 --- a/ruby/lib/route_guide_services.rb +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# Source: route_guide.proto for package 'examples' - -require 'grpc' -require 'route_guide' - -module Examples - module RouteGuide - - # TODO: add proto service documentation here - class Service - - include GRPC::GenericService - - self.marshal_class_method = :encode - self.unmarshal_class_method = :decode - self.service_name = 'examples.RouteGuide' - - rpc :GetFeature, Point, Feature - rpc :ListFeatures, Rectangle, stream(Feature) - rpc :RecordRoute, stream(Point), RouteSummary - rpc :RouteChat, stream(RouteNote), stream(RouteNote) - end - - Stub = Service.rpc_stub_class - end -end diff --git a/ruby/route_guide/README.md b/ruby/route_guide/README.md deleted file mode 100644 index d22874799f..0000000000 --- a/ruby/route_guide/README.md +++ /dev/null @@ -1,285 +0,0 @@ -#gRPC Basics: Ruby - -This tutorial provides a basic Ruby programmer's introduction to working with gRPC. By walking through this example you'll learn how to: - -- Define a service in a .proto file. -- Generate server and client code using the protocol buffer compiler. -- Use the Ruby gRPC API to write a simple client and server for your service. - -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. - -This isn't a comprehensive guide to using gRPC in Ruby: more reference documentation is coming soon. - -## Why use gRPC? - -Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. - -With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. - -## Example code and setup - -The example code for our tutorial is in [grpc/grpc-common/ruby/route_guide](https://github.com/grpc/grpc-common/tree/master/ruby/route_guide). To download the example, clone the `grpc-common` repository by running the following command: -```shell -$ git clone https://github.com/grpc/grpc-common.git -``` - -Then change your current directory to `grpc-common/ruby/route_guide`: -```shell -$ cd grpc-common/ruby/route_guide -``` - -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Ruby quick start guide](https://github.com/grpc/grpc-common/tree/master/ruby). - - -## Defining the service - -Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). - -To define a service, you specify a named `service` in your .proto file: - -```protobuf -service RouteGuide { - ... -} -``` - -Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: - -- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. -```protobuf - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} -``` - -- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. -```protobuf - // Obtains the Features available within the given Rectangle. Results are - // streamed rather than returned at once (e.g. in a response message with a - // repeated field), as the rectangle may cover a large area and contain a - // huge number of features. - rpc ListFeatures(Rectangle) returns (stream Feature) {} -``` - -- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. -```protobuf - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} -``` - -- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -```protobuf - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -``` - -Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -```protobuf -// 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; -} -``` - - -## Generating client and server code - -Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC Ruby plugin. - -If you want to run this yourself, make sure you've installed protoc and followed the gRPC Ruby plugin [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): - -Once that's done, the following command can be used to generate the ruby code. - -```shell -$ protoc -I ../../protos --ruby_out=lib --grpc_out=lib --plugin=protoc-gen-grpc=`which grpc_ruby_plugin` ../../protos/route_guide.proto -``` - -Running this command regenerates the following files in the lib directory: -- `lib/route_guide.pb` defines a module `Examples::RouteGuide` - - This contain all the protocol buffer code to populate, serialize, and retrieve our request and response message types -- `lib/route_guide_services.pb`, extends `Examples::RouteGuide` with stub and service classes - - a class `Service` for use as a base class when defining RouteGuide service implementations - - a class `Stub` that can be used to access remote RouteGuide instances - - - -## Creating the server - -First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). - -There are two parts to making our `RouteGuide` service do its job: -- Implementing the service interface generated from our service definition: doing the actual "work" of our service. -- Running a gRPC server to listen for requests from clients and return the service responses. - -You can find our example `RouteGuide` server in [grpc-common/ruby/route_guide/route_guide_server.rb](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/route_guide_server.rb). Let's take a closer look at how it works. - -### Implementing RouteGuide - -As you can see, our server has a `ServerImpl` class that extends the generated `RouteGuide::Service`: - -```ruby -# ServerImpl provides an implementation of the RouteGuide service. -class ServerImpl < RouteGuide::Service -``` - -`ServerImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. - -```ruby - def get_feature(point, _call) - name = @feature_db[{ - 'longitude' => point.longitude, - 'latitude' => point.latitude }] || '' - Feature.new(location: point, name: name) - end -``` - -The method is passed a _call for the RPC, the client's `Point` protocol buffer request, and returns a `Feature` protocol buffer. In the method we create the `Feature` with the appropriate information, and then `return` it. - -Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. - -```ruby -# in ServerImpl - - def list_features(rectangle, _call) - RectangleEnum.new(@feature_db, rectangle).each - end -``` - -As you can see, here the request object is a `Rectangle` in which our client wants to find `Feature`s, but instead of returning a simple response we need to return an [Enumerator](http://ruby-doc.org//core-2.2.0/Enumerator.html) that yields the responses. In the method, we use a helper class `RectangleEnum`, to act as an Enumerator implementation. - -Similarly, the client-side streaming method `record_route` uses an [Enumerable](http://ruby-doc.org//core-2.2.0/Enumerable.html), but here it's obtained from the call object, which we've ignored in the earlier examples. `call.each_remote_read` yields each message sent by the client in turn. - -```ruby - call.each_remote_read do |point| - ... - end -``` -Finally, let's look at our bidirectional streaming RPC `route_chat`. - -```ruby - def route_chat(notes) - q = EnumeratorQueue.new(self) - t = Thread.new do - begin - notes.each do |n| - ... - end - end - q = EnumeratorQueue.new(self) - ... - return q.each_item - end -``` - -Here the method receives an [Enumerable](http://ruby-doc.org//core-2.2.0/Enumerable.html), but also returns an [Enumerator](http://ruby-doc.org//core-2.2.0/Enumerator.html) that yields the responses. The implementation demonstrates how to set these up so that the requests and responses can be handled concurrently. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. - -### Starting the server - -Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: - -```ruby - s = GRPC::RpcServer.new - s.add_http2_port(port) - logger.info("... running insecurely on #{port}") - s.handle(ServerImpl.new(feature_db)) - s.run -``` -As you can see, we build and start our server using a `GRPC::RpcServer`. To do this, we: - -1. Create an instance of our service implementation class `ServerImpl`. -2. Specify the address and port we want to use to listen for client requests using the builder's `add_http2_port` method. -3. Register our service implementation with the `GRPC::RpcServer`. -4. Call `run` on the`GRPC::RpcServer` to create and start an RPC server for our service. - - -## Creating the client - -In this section, we'll look at creating a Ruby client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/ruby/route_guide/route_guide_client.rb](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/route_guide_client.rb). - -### Creating a stub - -To call service methods, we first need to create a *stub*. - -We use the `Stub` class of the `RouteGuide` module generated from our .proto. - -```ruby - stub = RouteGuide::Stub.new('localhost:50051') -``` - -### Calling service methods - -Now let's look at how we call our service methods. Note that the gRPC Ruby only provides *blocking/synchronous* versions of each method: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception. - -#### Simple RPC - -Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. - -```ruby -GET_FEATURE_POINTS = [ - Point.new(latitude: 409_146_138, longitude: -746_188_906), - Point.new(latitude: 0, longitude: 0) -] -.. - GET_FEATURE_POINTS.each do |pt| - resp = stub.get_feature(pt) - ... - p "- found '#{resp.name}' at #{pt.inspect}" - end -``` - -As you can see, we create and populate a request protocol buffer object (in our case `Point`), and create a response protocol buffer object for the server to fill in. Finally, we call the method on the stub, passing it the context, request, and response. If the method returns `OK`, then we can read the response information from the server from our response object. - - -#### Streaming RPCs - -Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `list_features`, which returns an `Enumerable` of `Features` - -```ruby - resps = stub.list_features(LIST_FEATURES_RECT) - resps.each do |r| - p "- found '#{r.name}' at #{r.location.inspect}" - end -``` - -The client-side streaming method `record_route` is similar, except there we pass the server an `Enumerable`. - -```ruby - ... - reqs = RandomRoute.new(features, points_on_route) - resp = stub.record_route(reqs.each, deadline) - ... -``` - -Finally, let's look at our bidirectional streaming RPC `route_chat`. In this case, we pass `Enumerable` to the method and get back an `Enumerable`. - -```ruby - resps = stub.route_chat(ROUTE_CHAT_NOTES) - resps.each { |r| p "received #{r.inspect}" } -``` - -Although it's not shown well by this example, each enumerable is independent of the other - both the client and server can read and write in any order — the streams operate completely independently. - -## Try it out! - -Build client and server: - -```shell -$ # from grpc-common/ruby -$ gem install bundler && bundle install -``` -Run the server, which will listen on port 50051: -```shell -$ # from grpc-common/ruby -$ bundle exec route_guide/route_guide_server.rb ../node/route_guide/route_guide_db.json & -``` -Run the client (in a different terminal): -```shell -$ # from grpc-common/ruby -$ bundle exec route_guide/route_guide_client.rb ../node/route_guide/route_guide_db.json & -``` - diff --git a/ruby/route_guide/route_guide_client.rb b/ruby/route_guide/route_guide_client.rb deleted file mode 100755 index 181623a68a..0000000000 --- a/ruby/route_guide/route_guide_client.rb +++ /dev/null @@ -1,165 +0,0 @@ -#!/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 Route Guide service. -# -# Usage: $ path/to/route_guide_client.rb path/to/route_guide_db.json & - -this_dir = File.expand_path(File.dirname(__FILE__)) -lib_dir = File.join(File.dirname(this_dir), 'lib') -$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) - -require 'grpc' -require 'route_guide_services' - -include Examples - -GET_FEATURE_POINTS = [ - Point.new(latitude: 409_146_138, longitude: -746_188_906), - Point.new(latitude: 0, longitude: 0) -] - -# runs a GetFeature rpc. -# -# - once with a point known to be present in the sample route database -# - once with a point that is not in the sample database -def run_get_feature(stub) - p 'GetFeature' - p '----------' - GET_FEATURE_POINTS.each do |pt| - resp = stub.get_feature(pt) - if resp.name != '' - p "- found '#{resp.name}' at #{pt.inspect}" - else - p "- found nothing at #{pt.inspect}" - end - end -end - -LIST_FEATURES_RECT = Rectangle.new( - lo: Point.new(latitude: 400_000_000, longitude: -750_000_000), - hi: Point.new(latitude: 420_000_000, longitude: -730_000_000)) - -# runs a ListFeatures rpc. -# -# - the rectangle to chosen to include most of the known features -# in the sample db. -def run_list_features(stub) - p 'ListFeatures' - p '------------' - resps = stub.list_features(LIST_FEATURES_RECT) - resps.each do |r| - p "- found '#{r.name}' at #{r.location.inspect}" - end -end - -# RandomRoute provides an Enumerable that yields a random 'route' of points -# from a list of Features. -class RandomRoute - def initialize(features, size) - @features = features - @size = size - end - - # yields a point, waiting between 0 and 1 seconds between each yield - # - # @return an Enumerable that yields a random point - def each - return enum_for(:each) unless block_given? - @size.times do - json_feature = @features[rand(0..@features.length)] - next if json_feature.nil? - location = json_feature['location'] - pt = Point.new( - Hash[location.each_pair.map { |k, v| [k.to_sym, v] }]) - p "- next point is #{pt.inspect}" - yield pt - sleep(rand(0..1)) - end - end -end - -# runs a RecordRoute rpc. -# -# - the rectangle to chosen to include most of the known features -# in the sample db. -def run_record_route(stub, features) - p 'RecordRoute' - p '-----------' - points_on_route = 10 # arbitrary - deadline = points_on_route # as delay b/w each is max 1 second - reqs = RandomRoute.new(features, points_on_route) - resp = stub.record_route(reqs.each, deadline) - p "summary: #{resp.inspect}" -end - -ROUTE_CHAT_NOTES = [ - RouteNote.new(message: 'doh - a deer', - location: Point.new(latitude: 0, longitude: 0)), - RouteNote.new(message: 'ray - a drop of golden sun', - location: Point.new(latitude: 0, longitude: 1)), - RouteNote.new(message: 'me - the name I call myself', - location: Point.new(latitude: 1, longitude: 0)), - RouteNote.new(message: 'fa - a longer way to run', - location: Point.new(latitude: 1, longitude: 1)), - RouteNote.new(message: 'soh - with needle and a thread', - location: Point.new(latitude: 0, longitude: 1)) -] - -# runs a RouteChat rpc. -# -# sends a canned set of route notes and prints out the responses. -def run_route_chat(stub) - p 'Route Chat' - p '----------' - # TODO: decouple sending and receiving, i.e have the response enumerator run - # on its own thread. - resps = stub.route_chat(ROUTE_CHAT_NOTES) - resps.each { |r| p "received #{r.inspect}" } -end - -def main - stub = RouteGuide::Stub.new('localhost:50051') - run_get_feature(stub) - run_list_features(stub) - run_route_chat(stub) - if ARGV.length == 0 - p 'no feature database; skipping record_route' - exit - end - raw_data = [] - File.open(ARGV[0]) do |f| - raw_data = MultiJson.load(f.read) - end - run_record_route(stub, raw_data) -end - -main diff --git a/ruby/route_guide/route_guide_server.rb b/ruby/route_guide/route_guide_server.rb deleted file mode 100755 index 2b2b8084ef..0000000000 --- a/ruby/route_guide/route_guide_server.rb +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/env ruby -# -*- coding: utf-8 -*- - -# 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 Route Guide service. -# -# Usage: $ path/to/route_guide_server.rb path/to/route_guide_db.json & - -this_dir = File.expand_path(File.dirname(__FILE__)) -lib_dir = File.join(File.dirname(this_dir), 'lib') -$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) - -require 'grpc' -require 'multi_json' -require 'route_guide_services' - -include Examples -COORD_FACTOR = 1e7 -RADIUS = 637_100 - -# Determines the distance between two points. -def calculate_distance(point_a, point_b) - to_radians = proc { |x| x * Math::PI / 180 } - lat_a = point_a.latitude / COORD_FACTOR - lat_b = point_b.latitude / COORD_FACTOR - long_a = point_a.longitude / COORD_FACTOR - long_b = point_b.longitude / COORD_FACTOR - φ1 = to_radians.call(lat_a) - φ2 = to_radians.call(lat_b) - Δφ = to_radians.call(lat_a - lat_b) - Δλ = to_radians.call(long_a - long_b) - a = Math.sin(Δφ / 2)**2 + - Math.cos(φ1) * Math.cos(φ2) + - Math.sin(Δλ / 2)**2 - (2 * RADIUS * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))).to_i -end - -# RectangleEnum provides an Enumerator of the points in a feature_db within a -# given Rectangle. -class RectangleEnum - # @param [Hash] feature_db - # @param [Rectangle] bounds - def initialize(feature_db, bounds) - @feature_db = feature_db - @bounds = bounds - lats = [@bounds.lo.latitude, @bounds.hi.latitude] - longs = [@bounds.lo.longitude, @bounds.hi.longitude] - @lo_lat, @hi_lat = lats.min, lats.max - @lo_long, @hi_long = longs.min, longs.max - end - - # in? determines if location lies within the bounds of this instances - # Rectangle. - def in?(location) - location['longitude'] >= @lo_long && - location['longitude'] <= @hi_long && - location['latitude'] >= @lo_lat && - location['latitude'] <= @hi_lat - end - - # each yields the features in the instances feature_db that lie within the - # instance rectangle. - def each - return enum_for(:each) unless block_given? - @feature_db.each_pair do |location, name| - next unless in?(location) - next if name.nil? || name == '' - pt = Point.new( - Hash[location.each_pair.map { |k, v| [k.to_sym, v] }]) - yield Feature.new(location: pt, name: name) - end - end -end - -# A EnumeratorQueue wraps a Queue to yield the items added to it. -class EnumeratorQueue - extend Forwardable - def_delegators :@q, :push - - def initialize(sentinel) - @q = Queue.new - @sentinel = sentinel - @received_notes = {} - end - - def each_item - return enum_for(:each_item) unless block_given? - loop do - r = @q.pop - break if r.equal?(@sentinel) - fail r if r.is_a? Exception - yield r - end - end -end - -# ServerImpl provides an implementation of the RouteGuide service. -class ServerImpl < RouteGuide::Service - # @param [Hash] feature_db {location => name} - def initialize(feature_db) - @feature_db = feature_db - @received_notes = Hash.new { |h, k| h[k] = [] } - end - - def get_feature(point, _call) - name = @feature_db[{ - 'longitude' => point.longitude, - 'latitude' => point.latitude }] || '' - Feature.new(location: point, name: name) - end - - def list_features(rectangle, _call) - RectangleEnum.new(@feature_db, rectangle).each - end - - def record_route(call) - started, elapsed_time = 0, 0 - distance, count, features, last = 0, 0, 0, nil - call.each_remote_read do |point| - count += 1 - name = @feature_db[{ - 'longitude' => point.longitude, - 'latitude' => point.latitude }] || '' - features += 1 unless name == '' - if last.nil? - last = point - started = Time.now.to_i - next - end - elapsed_time = Time.now.to_i - started - distance += calculate_distance(point, last) - last = point - end - RouteSummary.new(point_count: count, - feature_count: features, - distance: distance, - elapsed_time: elapsed_time) - end - - def route_chat(notes) - q = EnumeratorQueue.new(self) - # run a separate thread that processes the incoming requests - t = Thread.new do - begin - notes.each do |n| - key = { - 'latitude' => n.location.latitude, - 'longitude' => n.location.longitude - } - earlier_msgs = @received_notes[key] - @received_notes[key] << n.message - # send back the earlier messages at this point - earlier_msgs.each do |r| - q.push(RouteNote.new(location: n.location, message: r)) - end - end - q.push(self) # signal completion - rescue StandardError => e - q.push(e) # signal completion via an error - end - end - q.each_item - end -end - -def main - if ARGV.length == 0 - fail 'Please specify the path to the route_guide json database' - end - raw_data = [] - File.open(ARGV[0]) do |f| - raw_data = MultiJson.load(f.read) - end - feature_db = Hash[raw_data.map { |x| [x['location'], x['name']] }] - port = '0.0.0.0:50051' - s = GRPC::RpcServer.new - s.add_http2_port(port) - GRPC.logger.info("... running insecurely on #{port}") - s.handle(ServerImpl.new(feature_db)) - s.run -end - -main -- cgit v1.2.3 From 20fa6693f3836bf1418176ec78b26feaf51a369d Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Thu, 27 Aug 2015 14:00:20 -0700 Subject: move examples to correct locations --- doc/PROTOCOL-HTTP2.md | 192 ++ doc/grpc-auth-support.md | 289 +++ examples/README.md | 449 +++++ examples/cpp/README.md | 65 + examples/cpp/cpptutorial.md | 365 ++++ examples/cpp/helloworld/Makefile | 119 ++ examples/cpp/helloworld/README.md | 260 +++ examples/cpp/helloworld/greeter_async_client.cc | 98 + examples/cpp/helloworld/greeter_async_server.cc | 136 ++ examples/cpp/helloworld/greeter_client.cc | 85 + examples/cpp/helloworld/greeter_server.cc | 78 + examples/cpp/route_guide/Makefile | 113 ++ examples/cpp/route_guide/helper.cc | 178 ++ examples/cpp/route_guide/helper.h | 50 + examples/cpp/route_guide/route_guide_client.cc | 252 +++ examples/cpp/route_guide/route_guide_db.json | 601 +++++++ examples/cpp/route_guide/route_guide_server.cc | 202 +++ examples/csharp/.gitignore | 5 + examples/csharp/.nuget/packages.config | 4 + examples/csharp/Greeter.sln | 42 + examples/csharp/Greeter/.gitignore | 2 + examples/csharp/Greeter/Greeter.csproj | 81 + examples/csharp/Greeter/Helloworld.cs | 617 +++++++ examples/csharp/Greeter/HelloworldGrpc.cs | 78 + examples/csharp/Greeter/Properties/AssemblyInfo.cs | 22 + examples/csharp/Greeter/packages.config | 11 + examples/csharp/Greeter/protos/helloworld.proto | 52 + examples/csharp/GreeterClient/.gitignore | 2 + examples/csharp/GreeterClient/GreeterClient.csproj | 84 + examples/csharp/GreeterClient/Program.cs | 25 + .../GreeterClient/Properties/AssemblyInfo.cs | 22 + examples/csharp/GreeterClient/packages.config | 11 + examples/csharp/GreeterServer/.gitignore | 2 + examples/csharp/GreeterServer/GreeterServer.csproj | 84 + examples/csharp/GreeterServer/Program.cs | 37 + .../GreeterServer/Properties/AssemblyInfo.cs | 22 + examples/csharp/GreeterServer/packages.config | 11 + examples/csharp/README.md | 72 + examples/csharp/route_guide/.gitignore | 5 + examples/csharp/route_guide/.nuget/packages.config | 4 + examples/csharp/route_guide/README.md | 409 +++++ examples/csharp/route_guide/RouteGuide.sln | 39 + .../RouteGuide/Properties/AssemblyInfo.cs | 36 + .../csharp/route_guide/RouteGuide/RouteGuide.cs | 1873 ++++++++++++++++++++ .../route_guide/RouteGuide/RouteGuide.csproj | 101 ++ .../route_guide/RouteGuide/RouteGuideGrpc.cs | 123 ++ .../route_guide/RouteGuide/RouteGuideUtil.cs | 67 + .../csharp/route_guide/RouteGuide/packages.config | 12 + .../RouteGuide/protos/route_guide.proto | 123 ++ .../route_guide/RouteGuide/route_guide_db.json | 601 +++++++ .../csharp/route_guide/RouteGuideClient/App.config | 6 + .../csharp/route_guide/RouteGuideClient/Program.cs | 223 +++ .../RouteGuideClient/Properties/AssemblyInfo.cs | 36 + .../RouteGuideClient/RouteGuideClient.csproj | 100 ++ .../route_guide/RouteGuideClient/packages.config | 11 + .../csharp/route_guide/RouteGuideServer/App.config | 6 + .../csharp/route_guide/RouteGuideServer/Program.cs | 30 + .../RouteGuideServer/Properties/AssemblyInfo.cs | 36 + .../route_guide/RouteGuideServer/RouteGuideImpl.cs | 184 ++ .../RouteGuideServer/RouteGuideServer.csproj | 101 ++ .../route_guide/RouteGuideServer/packages.config | 11 + examples/node/.gitignore | 3 + examples/node/README.md | 60 + examples/node/greeter_client.js | 52 + examples/node/greeter_server.js | 63 + examples/node/helloworld.proto | 50 + examples/node/package.json | 10 + examples/node/route_guide/README.md | 362 ++++ examples/node/route_guide/route_guide.proto | 120 ++ examples/node/route_guide/route_guide_client.js | 231 +++ examples/node/route_guide/route_guide_db.json | 601 +++++++ examples/node/route_guide/route_guide_server.js | 249 +++ .../AuthSample.xcodeproj/project.pbxproj | 366 ++++ .../project.xcworkspace/contents.xcworkspacedata | 7 + .../auth_sample/AuthTestService.podspec | 35 + .../auth_sample/MakeRPCViewController.h | 40 + .../auth_sample/MakeRPCViewController.m | 100 ++ .../objective-c/auth_sample/Misc/AppDelegate.h | 38 + .../objective-c/auth_sample/Misc/AppDelegate.m | 61 + .../auth_sample/Misc/Base.lproj/Main.storyboard | 154 ++ .../auth_sample/Misc/GoogleService-Info.plist | 10 + .../AppIcon.appiconset/Contents.json | 68 + .../Images.xcassets/first.imageset/Contents.json | 12 + .../Misc/Images.xcassets/first.imageset/first.pdf | Bin 0 -> 2465 bytes .../Images.xcassets/second.imageset/Contents.json | 12 + .../Images.xcassets/second.imageset/second.pdf | Bin 0 -> 2423 bytes examples/objective-c/auth_sample/Misc/Info.plist | 80 + examples/objective-c/auth_sample/Misc/main.m | 41 + examples/objective-c/auth_sample/Podfile | 10 + examples/objective-c/auth_sample/README.md | 189 ++ .../auth_sample/SelectUserViewController.h | 42 + .../auth_sample/SelectUserViewController.m | 86 + examples/objective-c/helloworld/HelloWorld.podspec | 35 + .../HelloWorld.xcodeproj/project.pbxproj | 349 ++++ .../project.xcworkspace/contents.xcworkspacedata | 7 + .../helloworld/HelloWorld/AppDelegate.h | 38 + .../helloworld/HelloWorld/AppDelegate.m | 37 + .../HelloWorld/Base.lproj/Main.storyboard | 25 + .../AppIcon.appiconset/Contents.json | 68 + .../objective-c/helloworld/HelloWorld/Info.plist | 47 + .../helloworld/HelloWorld/ViewController.m | 40 + examples/objective-c/helloworld/Podfile | 7 + examples/objective-c/helloworld/README.md | 56 + examples/objective-c/helloworld/main.m | 51 + .../objective-c/route_guide/Misc/AppDelegate.h | 38 + .../objective-c/route_guide/Misc/AppDelegate.m | 37 + .../route_guide/Misc/Base.lproj/Main.storyboard | 193 ++ .../AppIcon.appiconset/Contents.json | 68 + .../Images.xcassets/first.imageset/Contents.json | 12 + .../Misc/Images.xcassets/first.imageset/first.pdf | Bin 0 -> 2465 bytes .../Images.xcassets/second.imageset/Contents.json | 12 + .../Images.xcassets/second.imageset/second.pdf | Bin 0 -> 2423 bytes examples/objective-c/route_guide/Misc/Info.plist | 57 + examples/objective-c/route_guide/Misc/main.m | 41 + examples/objective-c/route_guide/Podfile | 7 + examples/objective-c/route_guide/README.md | 360 ++++ .../objective-c/route_guide/RouteGuide.podspec | 35 + .../RouteGuideClient.xcodeproj/project.pbxproj | 366 ++++ .../project.xcworkspace/contents.xcworkspacedata | 7 + examples/objective-c/route_guide/ViewControllers.m | 228 +++ .../objective-c/route_guide/route_guide_db.json | 121 ++ examples/php/.gitignore | 2 + examples/php/README.md | 64 + examples/php/composer.json | 17 + examples/php/greeter_client.php | 49 + examples/php/helloworld.php | 160 ++ examples/php/helloworld.proto | 50 + examples/php/route_guide/README.md | 262 +++ examples/php/route_guide/route_guide.php | 731 ++++++++ examples/php/route_guide/route_guide.proto | 120 ++ examples/php/route_guide/route_guide_client.php | 205 +++ examples/php/route_guide/run_route_guide_client.sh | 36 + examples/php/run_greeter_client.sh | 35 + examples/protos/README.md | 8 + examples/protos/auth_sample.proto | 57 + examples/protos/hellostreamingworld.proto | 54 + examples/protos/helloworld.proto | 51 + examples/protos/route_guide.proto | 124 ++ examples/python/helloworld/.gitignore | 1 + examples/python/helloworld/README.md | 116 ++ examples/python/helloworld/greeter_client.py | 44 + examples/python/helloworld/greeter_server.py | 56 + examples/python/helloworld/run_client.sh | 8 + examples/python/helloworld/run_codegen.sh | 4 + examples/python/helloworld/run_server.sh | 9 + examples/python/route_guide/.gitignore | 1 + examples/python/route_guide/README.md | 303 ++++ examples/python/route_guide/route_guide_client.py | 130 ++ examples/python/route_guide/route_guide_db.json | 601 +++++++ examples/python/route_guide/route_guide_pb2.py | 370 ++++ .../python/route_guide/route_guide_resources.py | 53 + examples/python/route_guide/route_guide_server.py | 134 ++ examples/python/route_guide/run_client.sh | 8 + examples/python/route_guide/run_codegen.sh | 4 + examples/python/route_guide/run_server.sh | 8 + examples/ruby/.gitignore | 15 + examples/ruby/Gemfile | 6 + examples/ruby/README.md | 61 + examples/ruby/greeter_client.rb | 50 + examples/ruby/greeter_server.rb | 60 + examples/ruby/grpc-demo.gemspec | 23 + examples/ruby/lib/helloworld.rb | 18 + examples/ruby/lib/helloworld_services.rb | 24 + examples/ruby/lib/route_guide.rb | 37 + examples/ruby/lib/route_guide_services.rb | 27 + examples/ruby/route_guide/README.md | 285 +++ examples/ruby/route_guide/route_guide_client.rb | 165 ++ examples/ruby/route_guide/route_guide_server.rb | 211 +++ grpc-common/LICENSE | 28 - grpc-common/PATENTS | 22 - grpc-common/PROTOCOL-HTTP2.md | 192 -- grpc-common/README.md | 449 ----- grpc-common/cpp/README.md | 65 - grpc-common/cpp/cpptutorial.md | 365 ---- grpc-common/cpp/helloworld/Makefile | 119 -- grpc-common/cpp/helloworld/README.md | 260 --- grpc-common/cpp/helloworld/greeter_async_client.cc | 98 - grpc-common/cpp/helloworld/greeter_async_server.cc | 136 -- grpc-common/cpp/helloworld/greeter_client.cc | 85 - grpc-common/cpp/helloworld/greeter_server.cc | 78 - grpc-common/cpp/route_guide/Makefile | 113 -- grpc-common/cpp/route_guide/helper.cc | 178 -- grpc-common/cpp/route_guide/helper.h | 50 - grpc-common/cpp/route_guide/route_guide_client.cc | 252 --- grpc-common/cpp/route_guide/route_guide_db.json | 601 ------- grpc-common/cpp/route_guide/route_guide_server.cc | 202 --- grpc-common/csharp/.gitignore | 5 - grpc-common/csharp/.nuget/packages.config | 4 - grpc-common/csharp/Greeter.sln | 42 - grpc-common/csharp/Greeter/.gitignore | 2 - grpc-common/csharp/Greeter/Greeter.csproj | 81 - grpc-common/csharp/Greeter/Helloworld.cs | 617 ------- grpc-common/csharp/Greeter/HelloworldGrpc.cs | 78 - .../csharp/Greeter/Properties/AssemblyInfo.cs | 22 - grpc-common/csharp/Greeter/packages.config | 11 - grpc-common/csharp/Greeter/protos/helloworld.proto | 52 - grpc-common/csharp/GreeterClient/.gitignore | 2 - .../csharp/GreeterClient/GreeterClient.csproj | 84 - grpc-common/csharp/GreeterClient/Program.cs | 25 - .../GreeterClient/Properties/AssemblyInfo.cs | 22 - grpc-common/csharp/GreeterClient/packages.config | 11 - grpc-common/csharp/GreeterServer/.gitignore | 2 - .../csharp/GreeterServer/GreeterServer.csproj | 84 - grpc-common/csharp/GreeterServer/Program.cs | 37 - .../GreeterServer/Properties/AssemblyInfo.cs | 22 - grpc-common/csharp/GreeterServer/packages.config | 11 - grpc-common/csharp/README.md | 72 - grpc-common/csharp/route_guide/.gitignore | 5 - .../csharp/route_guide/.nuget/packages.config | 4 - grpc-common/csharp/route_guide/README.md | 409 ----- grpc-common/csharp/route_guide/RouteGuide.sln | 39 - .../RouteGuide/Properties/AssemblyInfo.cs | 36 - .../csharp/route_guide/RouteGuide/RouteGuide.cs | 1873 -------------------- .../route_guide/RouteGuide/RouteGuide.csproj | 101 -- .../route_guide/RouteGuide/RouteGuideGrpc.cs | 123 -- .../route_guide/RouteGuide/RouteGuideUtil.cs | 67 - .../csharp/route_guide/RouteGuide/packages.config | 12 - .../RouteGuide/protos/route_guide.proto | 123 -- .../route_guide/RouteGuide/route_guide_db.json | 601 ------- .../csharp/route_guide/RouteGuideClient/App.config | 6 - .../csharp/route_guide/RouteGuideClient/Program.cs | 223 --- .../RouteGuideClient/Properties/AssemblyInfo.cs | 36 - .../RouteGuideClient/RouteGuideClient.csproj | 100 -- .../route_guide/RouteGuideClient/packages.config | 11 - .../csharp/route_guide/RouteGuideServer/App.config | 6 - .../csharp/route_guide/RouteGuideServer/Program.cs | 30 - .../RouteGuideServer/Properties/AssemblyInfo.cs | 36 - .../route_guide/RouteGuideServer/RouteGuideImpl.cs | 184 -- .../RouteGuideServer/RouteGuideServer.csproj | 101 -- .../route_guide/RouteGuideServer/packages.config | 11 - grpc-common/go/README.md | 53 - grpc-common/go/gotutorial.md | 431 ----- grpc-common/go/greeter_client/main.go | 69 - grpc-common/go/greeter_server/main.go | 65 - grpc-common/go/helloworld/helloworld.pb.go | 109 -- grpc-common/grpc-auth-support.md | 289 --- grpc-common/java/android/.gitignore | 21 - grpc-common/java/android/README.md | 41 - grpc-common/java/android/app/.gitignore | 1 - grpc-common/java/android/app/build.gradle | 34 - grpc-common/java/android/app/proguard-rules.pro | 17 - .../java/android/app/src/main/AndroidManifest.xml | 22 - .../io/grpc/helloworldexample/GreeterGrpc.java | 179 -- .../java/io/grpc/helloworldexample/Helloworld.java | 175 -- .../grpc/helloworldexample/HelloworldActivity.java | 90 - .../src/main/res/layout/activity_helloworld.xml | 54 - .../app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 3418 -> 0 bytes .../app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 2206 -> 0 bytes .../app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 4842 -> 0 bytes .../app/src/main/res/mipmap-xxhdpi/ic_launcher.png | Bin 7718 -> 0 bytes .../android/app/src/main/res/values/strings.xml | 3 - grpc-common/java/android/build.gradle | 20 - .../java/android/gradle/wrapper/gradle-wrapper.jar | Bin 49896 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 - grpc-common/java/android/gradlew | 164 -- grpc-common/java/android/gradlew.bat | 90 - grpc-common/java/android/settings.gradle | 1 - grpc-common/java/javatutorial.md | 493 ------ grpc-common/node/.gitignore | 3 - grpc-common/node/README.md | 60 - grpc-common/node/greeter_client.js | 52 - grpc-common/node/greeter_server.js | 63 - grpc-common/node/helloworld.proto | 50 - grpc-common/node/package.json | 10 - grpc-common/node/route_guide/README.md | 362 ---- grpc-common/node/route_guide/route_guide.proto | 120 -- grpc-common/node/route_guide/route_guide_client.js | 231 --- grpc-common/node/route_guide/route_guide_db.json | 601 ------- grpc-common/node/route_guide/route_guide_server.js | 249 --- .../AuthSample.xcodeproj/project.pbxproj | 366 ---- .../project.xcworkspace/contents.xcworkspacedata | 7 - .../auth_sample/AuthTestService.podspec | 35 - .../auth_sample/MakeRPCViewController.h | 40 - .../auth_sample/MakeRPCViewController.m | 100 -- .../objective-c/auth_sample/Misc/AppDelegate.h | 38 - .../objective-c/auth_sample/Misc/AppDelegate.m | 61 - .../auth_sample/Misc/Base.lproj/Main.storyboard | 154 -- .../auth_sample/Misc/GoogleService-Info.plist | 10 - .../AppIcon.appiconset/Contents.json | 68 - .../Images.xcassets/first.imageset/Contents.json | 12 - .../Misc/Images.xcassets/first.imageset/first.pdf | Bin 2465 -> 0 bytes .../Images.xcassets/second.imageset/Contents.json | 12 - .../Images.xcassets/second.imageset/second.pdf | Bin 2423 -> 0 bytes .../objective-c/auth_sample/Misc/Info.plist | 80 - grpc-common/objective-c/auth_sample/Misc/main.m | 41 - grpc-common/objective-c/auth_sample/Podfile | 10 - grpc-common/objective-c/auth_sample/README.md | 189 -- .../auth_sample/SelectUserViewController.h | 42 - .../auth_sample/SelectUserViewController.m | 86 - .../objective-c/helloworld/HelloWorld.podspec | 35 - .../HelloWorld.xcodeproj/project.pbxproj | 349 ---- .../project.xcworkspace/contents.xcworkspacedata | 7 - .../helloworld/HelloWorld/AppDelegate.h | 38 - .../helloworld/HelloWorld/AppDelegate.m | 37 - .../HelloWorld/Base.lproj/Main.storyboard | 25 - .../AppIcon.appiconset/Contents.json | 68 - .../objective-c/helloworld/HelloWorld/Info.plist | 47 - .../helloworld/HelloWorld/ViewController.m | 40 - grpc-common/objective-c/helloworld/Podfile | 7 - grpc-common/objective-c/helloworld/README.md | 56 - grpc-common/objective-c/helloworld/main.m | 51 - .../objective-c/route_guide/Misc/AppDelegate.h | 38 - .../objective-c/route_guide/Misc/AppDelegate.m | 37 - .../route_guide/Misc/Base.lproj/Main.storyboard | 193 -- .../AppIcon.appiconset/Contents.json | 68 - .../Images.xcassets/first.imageset/Contents.json | 12 - .../Misc/Images.xcassets/first.imageset/first.pdf | Bin 2465 -> 0 bytes .../Images.xcassets/second.imageset/Contents.json | 12 - .../Images.xcassets/second.imageset/second.pdf | Bin 2423 -> 0 bytes .../objective-c/route_guide/Misc/Info.plist | 57 - grpc-common/objective-c/route_guide/Misc/main.m | 41 - grpc-common/objective-c/route_guide/Podfile | 7 - grpc-common/objective-c/route_guide/README.md | 360 ---- .../objective-c/route_guide/RouteGuide.podspec | 35 - .../RouteGuideClient.xcodeproj/project.pbxproj | 366 ---- .../project.xcworkspace/contents.xcworkspacedata | 7 - .../objective-c/route_guide/ViewControllers.m | 228 --- .../objective-c/route_guide/route_guide_db.json | 121 -- grpc-common/php/.gitignore | 2 - grpc-common/php/README.md | 64 - grpc-common/php/composer.json | 17 - grpc-common/php/greeter_client.php | 49 - grpc-common/php/helloworld.php | 160 -- grpc-common/php/helloworld.proto | 50 - grpc-common/php/route_guide/README.md | 262 --- grpc-common/php/route_guide/route_guide.php | 731 -------- grpc-common/php/route_guide/route_guide.proto | 120 -- grpc-common/php/route_guide/route_guide_client.php | 205 --- .../php/route_guide/run_route_guide_client.sh | 36 - grpc-common/php/run_greeter_client.sh | 35 - grpc-common/protos/README.md | 8 - grpc-common/protos/auth_sample.proto | 57 - grpc-common/protos/hellostreamingworld.proto | 54 - grpc-common/protos/helloworld.proto | 51 - grpc-common/protos/route_guide.proto | 124 -- grpc-common/python/helloworld/.gitignore | 1 - grpc-common/python/helloworld/README.md | 116 -- grpc-common/python/helloworld/greeter_client.py | 44 - grpc-common/python/helloworld/greeter_server.py | 56 - grpc-common/python/helloworld/run_client.sh | 8 - grpc-common/python/helloworld/run_codegen.sh | 4 - grpc-common/python/helloworld/run_server.sh | 9 - grpc-common/python/route_guide/.gitignore | 1 - grpc-common/python/route_guide/README.md | 303 ---- .../python/route_guide/route_guide_client.py | 130 -- grpc-common/python/route_guide/route_guide_db.json | 601 ------- grpc-common/python/route_guide/route_guide_pb2.py | 370 ---- .../python/route_guide/route_guide_resources.py | 53 - .../python/route_guide/route_guide_server.py | 134 -- grpc-common/python/route_guide/run_client.sh | 8 - grpc-common/python/route_guide/run_codegen.sh | 4 - grpc-common/python/route_guide/run_server.sh | 8 - grpc-common/ruby/.gitignore | 15 - grpc-common/ruby/Gemfile | 6 - grpc-common/ruby/README.md | 61 - grpc-common/ruby/greeter_client.rb | 50 - grpc-common/ruby/greeter_server.rb | 60 - grpc-common/ruby/grpc-demo.gemspec | 23 - grpc-common/ruby/lib/helloworld.rb | 18 - grpc-common/ruby/lib/helloworld_services.rb | 24 - grpc-common/ruby/lib/route_guide.rb | 37 - grpc-common/ruby/lib/route_guide_services.rb | 27 - grpc-common/ruby/route_guide/README.md | 285 --- grpc-common/ruby/route_guide/route_guide_client.rb | 165 -- grpc-common/ruby/route_guide/route_guide_server.rb | 211 --- 365 files changed, 19306 insertions(+), 21494 deletions(-) create mode 100644 doc/PROTOCOL-HTTP2.md create mode 100644 doc/grpc-auth-support.md create mode 100644 examples/README.md create mode 100644 examples/cpp/README.md create mode 100644 examples/cpp/cpptutorial.md create mode 100644 examples/cpp/helloworld/Makefile create mode 100644 examples/cpp/helloworld/README.md create mode 100644 examples/cpp/helloworld/greeter_async_client.cc create mode 100644 examples/cpp/helloworld/greeter_async_server.cc create mode 100644 examples/cpp/helloworld/greeter_client.cc create mode 100644 examples/cpp/helloworld/greeter_server.cc create mode 100644 examples/cpp/route_guide/Makefile create mode 100644 examples/cpp/route_guide/helper.cc create mode 100644 examples/cpp/route_guide/helper.h create mode 100644 examples/cpp/route_guide/route_guide_client.cc create mode 100644 examples/cpp/route_guide/route_guide_db.json create mode 100644 examples/cpp/route_guide/route_guide_server.cc create mode 100644 examples/csharp/.gitignore create mode 100644 examples/csharp/.nuget/packages.config create mode 100644 examples/csharp/Greeter.sln create mode 100644 examples/csharp/Greeter/.gitignore create mode 100644 examples/csharp/Greeter/Greeter.csproj create mode 100644 examples/csharp/Greeter/Helloworld.cs create mode 100644 examples/csharp/Greeter/HelloworldGrpc.cs create mode 100644 examples/csharp/Greeter/Properties/AssemblyInfo.cs create mode 100644 examples/csharp/Greeter/packages.config create mode 100644 examples/csharp/Greeter/protos/helloworld.proto create mode 100644 examples/csharp/GreeterClient/.gitignore create mode 100644 examples/csharp/GreeterClient/GreeterClient.csproj create mode 100644 examples/csharp/GreeterClient/Program.cs create mode 100644 examples/csharp/GreeterClient/Properties/AssemblyInfo.cs create mode 100644 examples/csharp/GreeterClient/packages.config create mode 100644 examples/csharp/GreeterServer/.gitignore create mode 100644 examples/csharp/GreeterServer/GreeterServer.csproj create mode 100644 examples/csharp/GreeterServer/Program.cs create mode 100644 examples/csharp/GreeterServer/Properties/AssemblyInfo.cs create mode 100644 examples/csharp/GreeterServer/packages.config create mode 100644 examples/csharp/README.md create mode 100644 examples/csharp/route_guide/.gitignore create mode 100644 examples/csharp/route_guide/.nuget/packages.config create mode 100644 examples/csharp/route_guide/README.md create mode 100644 examples/csharp/route_guide/RouteGuide.sln create mode 100644 examples/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs create mode 100644 examples/csharp/route_guide/RouteGuide/RouteGuide.cs create mode 100644 examples/csharp/route_guide/RouteGuide/RouteGuide.csproj create mode 100644 examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs create mode 100644 examples/csharp/route_guide/RouteGuide/RouteGuideUtil.cs create mode 100644 examples/csharp/route_guide/RouteGuide/packages.config create mode 100644 examples/csharp/route_guide/RouteGuide/protos/route_guide.proto create mode 100644 examples/csharp/route_guide/RouteGuide/route_guide_db.json create mode 100644 examples/csharp/route_guide/RouteGuideClient/App.config create mode 100644 examples/csharp/route_guide/RouteGuideClient/Program.cs create mode 100644 examples/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs create mode 100644 examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj create mode 100644 examples/csharp/route_guide/RouteGuideClient/packages.config create mode 100644 examples/csharp/route_guide/RouteGuideServer/App.config create mode 100644 examples/csharp/route_guide/RouteGuideServer/Program.cs create mode 100644 examples/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs create mode 100644 examples/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs create mode 100644 examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj create mode 100644 examples/csharp/route_guide/RouteGuideServer/packages.config create mode 100644 examples/node/.gitignore create mode 100644 examples/node/README.md create mode 100644 examples/node/greeter_client.js create mode 100644 examples/node/greeter_server.js create mode 100644 examples/node/helloworld.proto create mode 100644 examples/node/package.json create mode 100644 examples/node/route_guide/README.md create mode 100644 examples/node/route_guide/route_guide.proto create mode 100644 examples/node/route_guide/route_guide_client.js create mode 100644 examples/node/route_guide/route_guide_db.json create mode 100644 examples/node/route_guide/route_guide_server.js create mode 100644 examples/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj create mode 100644 examples/objective-c/auth_sample/AuthSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 examples/objective-c/auth_sample/AuthTestService.podspec create mode 100644 examples/objective-c/auth_sample/MakeRPCViewController.h create mode 100644 examples/objective-c/auth_sample/MakeRPCViewController.m create mode 100644 examples/objective-c/auth_sample/Misc/AppDelegate.h create mode 100644 examples/objective-c/auth_sample/Misc/AppDelegate.m create mode 100644 examples/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard create mode 100644 examples/objective-c/auth_sample/Misc/GoogleService-Info.plist create mode 100644 examples/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json create mode 100644 examples/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json create mode 100644 examples/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf create mode 100644 examples/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json create mode 100644 examples/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf create mode 100644 examples/objective-c/auth_sample/Misc/Info.plist create mode 100644 examples/objective-c/auth_sample/Misc/main.m create mode 100644 examples/objective-c/auth_sample/Podfile create mode 100644 examples/objective-c/auth_sample/README.md create mode 100644 examples/objective-c/auth_sample/SelectUserViewController.h create mode 100644 examples/objective-c/auth_sample/SelectUserViewController.m create mode 100644 examples/objective-c/helloworld/HelloWorld.podspec create mode 100644 examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj create mode 100644 examples/objective-c/helloworld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 examples/objective-c/helloworld/HelloWorld/AppDelegate.h create mode 100644 examples/objective-c/helloworld/HelloWorld/AppDelegate.m create mode 100644 examples/objective-c/helloworld/HelloWorld/Base.lproj/Main.storyboard create mode 100644 examples/objective-c/helloworld/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json create mode 100644 examples/objective-c/helloworld/HelloWorld/Info.plist create mode 100644 examples/objective-c/helloworld/HelloWorld/ViewController.m create mode 100644 examples/objective-c/helloworld/Podfile create mode 100644 examples/objective-c/helloworld/README.md create mode 100644 examples/objective-c/helloworld/main.m create mode 100644 examples/objective-c/route_guide/Misc/AppDelegate.h create mode 100644 examples/objective-c/route_guide/Misc/AppDelegate.m create mode 100644 examples/objective-c/route_guide/Misc/Base.lproj/Main.storyboard create mode 100644 examples/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json create mode 100644 examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json create mode 100644 examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf create mode 100644 examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json create mode 100644 examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf create mode 100644 examples/objective-c/route_guide/Misc/Info.plist create mode 100644 examples/objective-c/route_guide/Misc/main.m create mode 100644 examples/objective-c/route_guide/Podfile create mode 100644 examples/objective-c/route_guide/README.md create mode 100644 examples/objective-c/route_guide/RouteGuide.podspec create mode 100644 examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj create mode 100644 examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 examples/objective-c/route_guide/ViewControllers.m create mode 100644 examples/objective-c/route_guide/route_guide_db.json create mode 100644 examples/php/.gitignore create mode 100644 examples/php/README.md create mode 100644 examples/php/composer.json create mode 100644 examples/php/greeter_client.php create mode 100644 examples/php/helloworld.php create mode 100644 examples/php/helloworld.proto create mode 100644 examples/php/route_guide/README.md create mode 100644 examples/php/route_guide/route_guide.php create mode 100644 examples/php/route_guide/route_guide.proto create mode 100644 examples/php/route_guide/route_guide_client.php create mode 100755 examples/php/route_guide/run_route_guide_client.sh create mode 100755 examples/php/run_greeter_client.sh create mode 100644 examples/protos/README.md create mode 100644 examples/protos/auth_sample.proto create mode 100644 examples/protos/hellostreamingworld.proto create mode 100644 examples/protos/helloworld.proto create mode 100644 examples/protos/route_guide.proto create mode 100644 examples/python/helloworld/.gitignore create mode 100644 examples/python/helloworld/README.md create mode 100755 examples/python/helloworld/greeter_client.py create mode 100644 examples/python/helloworld/greeter_server.py create mode 100755 examples/python/helloworld/run_client.sh create mode 100755 examples/python/helloworld/run_codegen.sh create mode 100755 examples/python/helloworld/run_server.sh create mode 100644 examples/python/route_guide/.gitignore create mode 100644 examples/python/route_guide/README.md create mode 100755 examples/python/route_guide/route_guide_client.py create mode 100644 examples/python/route_guide/route_guide_db.json create mode 100644 examples/python/route_guide/route_guide_pb2.py create mode 100755 examples/python/route_guide/route_guide_resources.py create mode 100644 examples/python/route_guide/route_guide_server.py create mode 100755 examples/python/route_guide/run_client.sh create mode 100755 examples/python/route_guide/run_codegen.sh create mode 100755 examples/python/route_guide/run_server.sh create mode 100644 examples/ruby/.gitignore create mode 100644 examples/ruby/Gemfile create mode 100644 examples/ruby/README.md create mode 100755 examples/ruby/greeter_client.rb create mode 100755 examples/ruby/greeter_server.rb create mode 100644 examples/ruby/grpc-demo.gemspec create mode 100644 examples/ruby/lib/helloworld.rb create mode 100644 examples/ruby/lib/helloworld_services.rb create mode 100644 examples/ruby/lib/route_guide.rb create mode 100644 examples/ruby/lib/route_guide_services.rb create mode 100644 examples/ruby/route_guide/README.md create mode 100755 examples/ruby/route_guide/route_guide_client.rb create mode 100755 examples/ruby/route_guide/route_guide_server.rb delete mode 100644 grpc-common/LICENSE delete mode 100644 grpc-common/PATENTS delete mode 100644 grpc-common/PROTOCOL-HTTP2.md delete mode 100644 grpc-common/README.md delete mode 100644 grpc-common/cpp/README.md delete mode 100644 grpc-common/cpp/cpptutorial.md delete mode 100644 grpc-common/cpp/helloworld/Makefile delete mode 100644 grpc-common/cpp/helloworld/README.md delete mode 100644 grpc-common/cpp/helloworld/greeter_async_client.cc delete mode 100644 grpc-common/cpp/helloworld/greeter_async_server.cc delete mode 100644 grpc-common/cpp/helloworld/greeter_client.cc delete mode 100644 grpc-common/cpp/helloworld/greeter_server.cc delete mode 100644 grpc-common/cpp/route_guide/Makefile delete mode 100644 grpc-common/cpp/route_guide/helper.cc delete mode 100644 grpc-common/cpp/route_guide/helper.h delete mode 100644 grpc-common/cpp/route_guide/route_guide_client.cc delete mode 100644 grpc-common/cpp/route_guide/route_guide_db.json delete mode 100644 grpc-common/cpp/route_guide/route_guide_server.cc delete mode 100644 grpc-common/csharp/.gitignore delete mode 100644 grpc-common/csharp/.nuget/packages.config delete mode 100644 grpc-common/csharp/Greeter.sln delete mode 100644 grpc-common/csharp/Greeter/.gitignore delete mode 100644 grpc-common/csharp/Greeter/Greeter.csproj delete mode 100644 grpc-common/csharp/Greeter/Helloworld.cs delete mode 100644 grpc-common/csharp/Greeter/HelloworldGrpc.cs delete mode 100644 grpc-common/csharp/Greeter/Properties/AssemblyInfo.cs delete mode 100644 grpc-common/csharp/Greeter/packages.config delete mode 100644 grpc-common/csharp/Greeter/protos/helloworld.proto delete mode 100644 grpc-common/csharp/GreeterClient/.gitignore delete mode 100644 grpc-common/csharp/GreeterClient/GreeterClient.csproj delete mode 100644 grpc-common/csharp/GreeterClient/Program.cs delete mode 100644 grpc-common/csharp/GreeterClient/Properties/AssemblyInfo.cs delete mode 100644 grpc-common/csharp/GreeterClient/packages.config delete mode 100644 grpc-common/csharp/GreeterServer/.gitignore delete mode 100644 grpc-common/csharp/GreeterServer/GreeterServer.csproj delete mode 100644 grpc-common/csharp/GreeterServer/Program.cs delete mode 100644 grpc-common/csharp/GreeterServer/Properties/AssemblyInfo.cs delete mode 100644 grpc-common/csharp/GreeterServer/packages.config delete mode 100644 grpc-common/csharp/README.md delete mode 100644 grpc-common/csharp/route_guide/.gitignore delete mode 100644 grpc-common/csharp/route_guide/.nuget/packages.config delete mode 100644 grpc-common/csharp/route_guide/README.md delete mode 100644 grpc-common/csharp/route_guide/RouteGuide.sln delete mode 100644 grpc-common/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs delete mode 100644 grpc-common/csharp/route_guide/RouteGuide/RouteGuide.cs delete mode 100644 grpc-common/csharp/route_guide/RouteGuide/RouteGuide.csproj delete mode 100644 grpc-common/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs delete mode 100644 grpc-common/csharp/route_guide/RouteGuide/RouteGuideUtil.cs delete mode 100644 grpc-common/csharp/route_guide/RouteGuide/packages.config delete mode 100644 grpc-common/csharp/route_guide/RouteGuide/protos/route_guide.proto delete mode 100644 grpc-common/csharp/route_guide/RouteGuide/route_guide_db.json delete mode 100644 grpc-common/csharp/route_guide/RouteGuideClient/App.config delete mode 100644 grpc-common/csharp/route_guide/RouteGuideClient/Program.cs delete mode 100644 grpc-common/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs delete mode 100644 grpc-common/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj delete mode 100644 grpc-common/csharp/route_guide/RouteGuideClient/packages.config delete mode 100644 grpc-common/csharp/route_guide/RouteGuideServer/App.config delete mode 100644 grpc-common/csharp/route_guide/RouteGuideServer/Program.cs delete mode 100644 grpc-common/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs delete mode 100644 grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs delete mode 100644 grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj delete mode 100644 grpc-common/csharp/route_guide/RouteGuideServer/packages.config delete mode 100644 grpc-common/go/README.md delete mode 100644 grpc-common/go/gotutorial.md delete mode 100644 grpc-common/go/greeter_client/main.go delete mode 100644 grpc-common/go/greeter_server/main.go delete mode 100644 grpc-common/go/helloworld/helloworld.pb.go delete mode 100644 grpc-common/grpc-auth-support.md delete mode 100644 grpc-common/java/android/.gitignore delete mode 100644 grpc-common/java/android/README.md delete mode 100644 grpc-common/java/android/app/.gitignore delete mode 100644 grpc-common/java/android/app/build.gradle delete mode 100644 grpc-common/java/android/app/proguard-rules.pro delete mode 100644 grpc-common/java/android/app/src/main/AndroidManifest.xml delete mode 100644 grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/GreeterGrpc.java delete mode 100644 grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/Helloworld.java delete mode 100644 grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java delete mode 100644 grpc-common/java/android/app/src/main/res/layout/activity_helloworld.xml delete mode 100644 grpc-common/java/android/app/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 grpc-common/java/android/app/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 grpc-common/java/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 grpc-common/java/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 grpc-common/java/android/app/src/main/res/values/strings.xml delete mode 100644 grpc-common/java/android/build.gradle delete mode 100644 grpc-common/java/android/gradle/wrapper/gradle-wrapper.jar delete mode 100644 grpc-common/java/android/gradle/wrapper/gradle-wrapper.properties delete mode 100755 grpc-common/java/android/gradlew delete mode 100644 grpc-common/java/android/gradlew.bat delete mode 100644 grpc-common/java/android/settings.gradle delete mode 100644 grpc-common/java/javatutorial.md delete mode 100644 grpc-common/node/.gitignore delete mode 100644 grpc-common/node/README.md delete mode 100644 grpc-common/node/greeter_client.js delete mode 100644 grpc-common/node/greeter_server.js delete mode 100644 grpc-common/node/helloworld.proto delete mode 100644 grpc-common/node/package.json delete mode 100644 grpc-common/node/route_guide/README.md delete mode 100644 grpc-common/node/route_guide/route_guide.proto delete mode 100644 grpc-common/node/route_guide/route_guide_client.js delete mode 100644 grpc-common/node/route_guide/route_guide_db.json delete mode 100644 grpc-common/node/route_guide/route_guide_server.js delete mode 100644 grpc-common/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj delete mode 100644 grpc-common/objective-c/auth_sample/AuthSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 grpc-common/objective-c/auth_sample/AuthTestService.podspec delete mode 100644 grpc-common/objective-c/auth_sample/MakeRPCViewController.h delete mode 100644 grpc-common/objective-c/auth_sample/MakeRPCViewController.m delete mode 100644 grpc-common/objective-c/auth_sample/Misc/AppDelegate.h delete mode 100644 grpc-common/objective-c/auth_sample/Misc/AppDelegate.m delete mode 100644 grpc-common/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard delete mode 100644 grpc-common/objective-c/auth_sample/Misc/GoogleService-Info.plist delete mode 100644 grpc-common/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 grpc-common/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json delete mode 100644 grpc-common/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf delete mode 100644 grpc-common/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json delete mode 100644 grpc-common/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf delete mode 100644 grpc-common/objective-c/auth_sample/Misc/Info.plist delete mode 100644 grpc-common/objective-c/auth_sample/Misc/main.m delete mode 100644 grpc-common/objective-c/auth_sample/Podfile delete mode 100644 grpc-common/objective-c/auth_sample/README.md delete mode 100644 grpc-common/objective-c/auth_sample/SelectUserViewController.h delete mode 100644 grpc-common/objective-c/auth_sample/SelectUserViewController.m delete mode 100644 grpc-common/objective-c/helloworld/HelloWorld.podspec delete mode 100644 grpc-common/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj delete mode 100644 grpc-common/objective-c/helloworld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 grpc-common/objective-c/helloworld/HelloWorld/AppDelegate.h delete mode 100644 grpc-common/objective-c/helloworld/HelloWorld/AppDelegate.m delete mode 100644 grpc-common/objective-c/helloworld/HelloWorld/Base.lproj/Main.storyboard delete mode 100644 grpc-common/objective-c/helloworld/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 grpc-common/objective-c/helloworld/HelloWorld/Info.plist delete mode 100644 grpc-common/objective-c/helloworld/HelloWorld/ViewController.m delete mode 100644 grpc-common/objective-c/helloworld/Podfile delete mode 100644 grpc-common/objective-c/helloworld/README.md delete mode 100644 grpc-common/objective-c/helloworld/main.m delete mode 100644 grpc-common/objective-c/route_guide/Misc/AppDelegate.h delete mode 100644 grpc-common/objective-c/route_guide/Misc/AppDelegate.m delete mode 100644 grpc-common/objective-c/route_guide/Misc/Base.lproj/Main.storyboard delete mode 100644 grpc-common/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 grpc-common/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json delete mode 100644 grpc-common/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf delete mode 100644 grpc-common/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json delete mode 100644 grpc-common/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf delete mode 100644 grpc-common/objective-c/route_guide/Misc/Info.plist delete mode 100644 grpc-common/objective-c/route_guide/Misc/main.m delete mode 100644 grpc-common/objective-c/route_guide/Podfile delete mode 100644 grpc-common/objective-c/route_guide/README.md delete mode 100644 grpc-common/objective-c/route_guide/RouteGuide.podspec delete mode 100644 grpc-common/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj delete mode 100644 grpc-common/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 grpc-common/objective-c/route_guide/ViewControllers.m delete mode 100644 grpc-common/objective-c/route_guide/route_guide_db.json delete mode 100644 grpc-common/php/.gitignore delete mode 100644 grpc-common/php/README.md delete mode 100644 grpc-common/php/composer.json delete mode 100644 grpc-common/php/greeter_client.php delete mode 100644 grpc-common/php/helloworld.php delete mode 100644 grpc-common/php/helloworld.proto delete mode 100644 grpc-common/php/route_guide/README.md delete mode 100644 grpc-common/php/route_guide/route_guide.php delete mode 100644 grpc-common/php/route_guide/route_guide.proto delete mode 100644 grpc-common/php/route_guide/route_guide_client.php delete mode 100755 grpc-common/php/route_guide/run_route_guide_client.sh delete mode 100755 grpc-common/php/run_greeter_client.sh delete mode 100644 grpc-common/protos/README.md delete mode 100644 grpc-common/protos/auth_sample.proto delete mode 100644 grpc-common/protos/hellostreamingworld.proto delete mode 100644 grpc-common/protos/helloworld.proto delete mode 100644 grpc-common/protos/route_guide.proto delete mode 100644 grpc-common/python/helloworld/.gitignore delete mode 100644 grpc-common/python/helloworld/README.md delete mode 100755 grpc-common/python/helloworld/greeter_client.py delete mode 100644 grpc-common/python/helloworld/greeter_server.py delete mode 100755 grpc-common/python/helloworld/run_client.sh delete mode 100755 grpc-common/python/helloworld/run_codegen.sh delete mode 100755 grpc-common/python/helloworld/run_server.sh delete mode 100644 grpc-common/python/route_guide/.gitignore delete mode 100644 grpc-common/python/route_guide/README.md delete mode 100755 grpc-common/python/route_guide/route_guide_client.py delete mode 100644 grpc-common/python/route_guide/route_guide_db.json delete mode 100644 grpc-common/python/route_guide/route_guide_pb2.py delete mode 100755 grpc-common/python/route_guide/route_guide_resources.py delete mode 100644 grpc-common/python/route_guide/route_guide_server.py delete mode 100755 grpc-common/python/route_guide/run_client.sh delete mode 100755 grpc-common/python/route_guide/run_codegen.sh delete mode 100755 grpc-common/python/route_guide/run_server.sh delete mode 100644 grpc-common/ruby/.gitignore delete mode 100644 grpc-common/ruby/Gemfile delete mode 100644 grpc-common/ruby/README.md delete mode 100755 grpc-common/ruby/greeter_client.rb delete mode 100755 grpc-common/ruby/greeter_server.rb delete mode 100644 grpc-common/ruby/grpc-demo.gemspec delete mode 100644 grpc-common/ruby/lib/helloworld.rb delete mode 100644 grpc-common/ruby/lib/helloworld_services.rb delete mode 100644 grpc-common/ruby/lib/route_guide.rb delete mode 100644 grpc-common/ruby/lib/route_guide_services.rb delete mode 100644 grpc-common/ruby/route_guide/README.md delete mode 100755 grpc-common/ruby/route_guide/route_guide_client.rb delete mode 100755 grpc-common/ruby/route_guide/route_guide_server.rb diff --git a/doc/PROTOCOL-HTTP2.md b/doc/PROTOCOL-HTTP2.md new file mode 100644 index 0000000000..d3fbb60d60 --- /dev/null +++ b/doc/PROTOCOL-HTTP2.md @@ -0,0 +1,192 @@ +# gRPC over HTTP2 + +## Introduction +This document serves as a detailed description for an implementation of gRPC carried over HTTP2 draft 17 framing. It assumes familiarity with the HTTP2 specification. + +## Protocol +Production rules are using ABNF syntax. + +### Outline + +The following is the general sequence of message atoms in a GRPC request & response message stream + +* Request → Request-Headers *Delimited-Message EOS +* Response → (Response-Headers *Delimited-Message Trailers) / Trailers-Only + + +### Requests + +* Request → Request-Headers *Delimited-Message EOS + +Request-Headers are delivered as HTTP2 headers in HEADERS + CONTINUATION frames. + +* **Request-Headers** → Call-Definition *Custom-Metadata +* **Call-Definition** → Method Scheme Path TE [Authority] [Timeout] [Content-Type] [Message-Type] [Message-Encoding] [Message-Accept-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_})] +* **Content-Coding** → “gzip” / “deflate” / “snappy” / {_custom_} +* **Message-Encoding** → “grpc-encoding” Content-Coding +* **Message-Accept-Encoding** → “grpc-accept-encoding” Content-Coding *("," Content-Coding) +* **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] [Message-Accept-Encoding] Content-Type *Custom-Metadata +* **Trailers-Only** → HTTP-Status Content-Type Trailers +* **Trailers** → Status [Status-Message] *Custom-Metadata +* **HTTP-Status** → “:status 200” +* **Status** → “grpc-status” +* **Status-Message** → “grpc-message” + +**Response-Headers** & **Trailers-Only** are each delivered in a single HTTP2 HEADERS frame block. Most responses are expected to have both headers and trailers but **Trailers-Only** is permitted for calls that produce an immediate error. Status must be sent in **Trailers** even if the status code is OK. + +For responses end-of-stream is indicated by the presence of the END_STREAM flag on the last received HEADERS frame that carries **Trailers**. + +Implementations should expect broken deployments to send non-200 HTTP status codes in responses as well as a variety of non-GRPC content-types and to omit **Status** & **Status-Message**. Implementations must synthesize a **Status** & **Status-Message** to propagate to the application layer when this occurs. + +####Example + +Sample unary-call showing HTTP2 framing sequence + +**Request** + +``` +HEADERS (flags = END_HEADERS) +:method = POST +:scheme = http +:path = /google.pubsub.v2.PublisherService/CreateTopic +:authority = pubsub.googleapis.com +grpc-timeout = 1S +content-type = application/grpc+proto +grpc-encoding = gzip +authorization = Bearer y235.wef315yfh138vh31hv93hv8h3v + +DATA (flags = END_STREAM) + +``` +**Response** +``` +HEADERS (flags = END_HEADERS) +:status = 200 +grpc-encoding = gzip + +DATA + + +HEADERS (flags = END_STREAM, END_HEADERS) +grpc-status = 0 # OK +trace-proto-bin = jher831yy13JHy3hc +``` +####User Agents + +While the protocol does not require a user-agent to function it is recommended that clients provide a structured user-agent string that provides a basic description of the calling library, version & platform to facilitate issue diagnosis in heterogeneous environments. The following structure is recommended to library developers +``` +User-Agent → “grpc-” Language ?(“-” Variant) “/” Version ?( “ (“ *(AdditionalProperty “;”) “)” ) +``` +E.g. + +``` +grpc-java/1.2.3 +grpc-ruby/1.2.3 +grpc-ruby-jruby/1.3.4 +grpc-java-android/0.9.1 (gingerbread/1.2.4; nexus5; tmobile) +``` +####HTTP2 Transport Mapping + +#####Stream Identification +All GRPC calls need to specify an internal ID. We will use HTTP2 stream-ids as call identifiers in this scheme. NOTE: These id’s are contextual to an open HTTP2 session and will not be unique within a given process that is handling more than one HTTP2 session nor can they be used as GUIDs. + +#####Data Frames +DATA frame boundaries have no relation to **Delimited-Message** boundaries and implementations should make no assumptions about their alignment. + +#####Errors + +When an application or runtime error occurs during an RPC a **Status** and **Status-Message** are delivered in **Trailers**. + +In some cases it is possible that the framing of the message stream has become corrupt and the RPC runtime will choose to use an **RST_STREAM** frame to indicate this state to its peer. RPC runtime implementations should interpret RST_STREAM as immediate full-closure of the stream and should propagate an error up to the calling application layer. + +The following mapping from RST_STREAM error codes to GRPC error codes is applied. + +HTTP2 Code|GRPC Code +----------|----------- +NO_ERROR(0)|INTERNAL - An explicit GRPC status of OK should have been sent but this might be used to aggressively lameduck in some scenarios. +PROTOCOL_ERROR(1)|INTERNAL +INTERNAL_ERROR(2)|INTERNAL +FLOW_CONTROL_ERROR(3)|INTERNAL +SETTINGS_TIMEOUT(4)|INTERNAL +STREAM_CLOSED|No mapping as there is no open stream to propagate to. Implementations should log. +FRAME_SIZE_ERROR|INTERNAL +REFUSED_STREAM|UNAVAILABLE - Indicates that no processing occurred and the request can be retried, possibly elsewhere. +CANCEL(8)|Mapped to call cancellation when sent by a client.Mapped to CANCELLED when sent by a server. Note that servers should only use this mechanism when they need to cancel a call but the payload byte sequence is incomplete. +COMPRESSION_ERROR|INTERNAL +CONNECT_ERROR|INTERNAL +ENHANCE_YOUR_CALM|RESOURCE_EXHAUSTED ...with additional error detail provided by runtime to indicate that the exhausted resource is bandwidth. +INADEQUATE_SECURITY| PERMISSION_DENIED … with additional detail indicating that permission was denied as protocol is not secure enough for call. + + +#####Security + +The HTTP2 specification mandates the use of TLS 1.2 or higher when TLS is used with HTTP2. It also places some additional constraints on the allowed ciphers in deployments to avoid known-problems as well as requiring SNI support. It is also expected that HTTP2 will be used in conjunction with proprietary transport security mechanisms about which the specification can make no meaningful recommendations. + +#####Connection Management +######GOAWAY Frame +Sent by servers to clients to indicate that they will no longer accept any new streams on the associated connections. This frame includes the id of the last successfully accepted stream by the server. Clients should consider any stream initiated after the last successfully accepted stream as UNAVAILABLE and retry the call elsewhere. Clients are free to continue working with the already accepted streams until they complete or the connection is terminated. + +Servers should send GOAWAY before terminating a connection to reliably inform clients which work has been accepted by the server and is being executed. + +######PING Frame +Both clients and servers can send a PING frame that the peer must respond to by precisely echoing what they received. This is used to assert that the connection is still live as well as providing a means to estimate end-to-end latency. If a server initiated PING does not receive a response within the deadline expected by the runtime all outstanding calls on the server will be closed with a CANCELLED status. An expired client initiated PING will cause all calls to be closed with an UNAVAILABLE status. Note that the frequency of PINGs is highly dependent on the network environment, implementations are free to adjust PING frequency based on network and application requirements. + +######Connection failure +If a detectable connection failure occurs on the client all calls will be closed with an UNAVAILABLE status. For servers open calls will be closed with a CANCELLED status. + + +### Appendix A - GRPC for Protobuf + +The service interfaces declared by protobuf are easily mapped onto GRPC by code generation extensions to protoc. The following defines the mapping to be used + + +* **Path** → / Service-Name / {_method name_} +* **Service-Name** → ?( {_proto package name_} "." ) {_service name_} +* **Message-Type** → {_fully qualified proto message name_} +* **Content-Type** → "application/grpc+proto" + + diff --git a/doc/grpc-auth-support.md b/doc/grpc-auth-support.md new file mode 100644 index 0000000000..b9ef299332 --- /dev/null +++ b/doc/grpc-auth-support.md @@ -0,0 +1,289 @@ +#gRPC Authentication support + +gRPC is designed to plug-in a number of authentication mechanisms. This document +provides a quick overview of the various auth mechanisms supported, discusses +the API with some examples, and concludes with a discussion of extensibility. +More documentation and examples are coming soon! + +## Supported auth mechanisms + +###SSL/TLS +gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the +server, and encrypt all the data exchanged between the client and the server. +Optional mechanisms are available for clients to provide certificates to +accomplish mutual authentication. + +###OAuth 2.0 +gRPC provides a generic mechanism (described below) to attach metadata to +requests and responses. This mechanism can be used to attach OAuth 2.0 Access +Tokens to RPCs being made at a client. Additional support for acquiring Access +Tokens while accessing Google APIs through gRPC is provided for certain auth +flows, demonstrated through code examples below. + +## API +To reduce complexity and minimize API clutter, gRPC works with a unified concept +of a Credentials object. Users construct gRPC credentials using corresponding +bootstrap credentials (e.g., SSL client certs or Service Account Keys), and use +the credentials while creating a gRPC channel to any server. Depending on the +type of credential supplied, the channel uses the credentials during the initial +SSL/TLS handshake with the server, or uses the credential to generate and +attach Access Tokens to each request being made on the channel. + +###SSL/TLS for server authentication and encryption +This is the simplest authentication scenario, where a client just wants to +authenticate the server and encrypt all data. + +```cpp +SslCredentialsOptions ssl_opts; // Options to override SSL params, empty by default +// Create the credentials object by providing service account key in constructor +std::unique_ptr creds = CredentialsFactory::SslCredentials(ssl_opts); +// Create a channel using the credentials created in the previous step +std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); +// Create a stub on the channel +std::unique_ptr stub(Greeter::NewStub(channel)); +// Make actual RPC calls on the stub. +grpc::Status s = stub->sayHello(&context, *request, response); +``` + +For advanced use cases such as modifying the root CA or using client certs, +the corresponding options can be set in the SslCredentialsOptions parameter +passed to the factory method. + + +###Authenticating with Google + +gRPC applications can use a simple API to create a credential that works in various deployment scenarios. + +```cpp +std::unique_ptr creds = CredentialsFactory::GoogleDefaultCredentials(); +// Create a channel, stub and make RPC calls (same as in the previous example) +std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); +std::unique_ptr stub(Greeter::NewStub(channel)); +grpc::Status s = stub->sayHello(&context, *request, response); +``` + +This credential works for applications using Service Accounts as well as for +applications running in [Google Compute Engine (GCE)](https://cloud.google.com/compute/). In the former case, the +service account’s private keys are loaded from the file named in the environment +variable `GOOGLE_APPLICATION_CREDENTIALS`. The +keys are used to generate bearer tokens that are attached to each outgoing RPC +on the corresponding channel. + +For applications running in GCE, a default service account and corresponding +OAuth scopes can be configured during VM setup. At run-time, this credential +handles communication with the authentication systems to obtain OAuth2 access +tokens and attaches them to each outgoing RPC on the corresponding channel. +Extending gRPC to support other authentication mechanisms +The gRPC protocol is designed with a general mechanism for sending metadata +associated with RPC. Clients can send metadata at the beginning of an RPC and +servers can send back metadata at the beginning and end of the RPC. This +provides a natural mechanism to support OAuth2 and other authentication +mechanisms that need attach bearer tokens to individual request. + +In the simplest case, there is a single line of code required on the client +to add a specific token as metadata to an RPC and a corresponding access on +the server to retrieve this piece of metadata. The generation of the token +on the client side and its verification at the server can be done separately. + +A deeper integration can be achieved by plugging in a gRPC credentials implementation for any custom authentication mechanism that needs to attach per-request tokens. gRPC internals also allow switching out SSL/TLS with other encryption mechanisms. + +## Examples + +These authentication mechanisms will be available in all gRPC's supported languages. +The following sections demonstrate how authentication and authorization features described above appear in each language: more languages are coming soon. + +###SSL/TLS for server authentication and encryption (Ruby) +```ruby +# Base case - No encryption +stub = Helloworld::Greeter::Stub.new('localhost:50051') +... + +# With server authentication SSL/TLS +creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file +stub = Helloworld::Greeter::Stub.new('localhost:50051', creds: creds) +``` + +###SSL/TLS for server authentication and encryption (C#) +```csharp +// Base case - No encryption +var channel = new Channel("localhost:50051"); +var client = new Greeter.GreeterClient(channel); +... + +// With server authentication SSL/TLS +var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file +var channel = new Channel("localhost:50051", credentials); +var client = new Greeter.GreeterClient(channel); +``` + +###SSL/TLS for server authentication and encryption (Objective-C) + +The default for Objective-C is to use SSL/TLS, as that's the most common use case when accessing +remote APIs. + +```objective-c +// Base case - With server authentication SSL/TLS +HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"localhost:50051"]; +// Same as using @"https://localhost:50051". +... + +// No encryption +HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"http://localhost:50051"]; +// Specifying the HTTP scheme explicitly forces no encryption. +``` + +###SSL/TLS for server authentication and encryption (Python) +```python +# Base case - No encryption +stub = early_adopter_create_GreeterService_stub('localhost', 50051) +... + +# With server authentication SSL/TLS +stub = early_adopter_create_GreeterService_stub( + 'localhost', 50051, secure=True, root_certificates=open('ca.pem').read()) +... +``` +n.b.: the beta API will look different + +###Authenticating with Google (Ruby) +```ruby +# Base case - No encryption/authorization +stub = Helloworld::Greeter::Stub.new('localhost:50051') +... + +# Authenticating with Google +require 'googleauth' # from http://www.rubydoc.info/gems/googleauth/0.1.0 +... +creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file +scope = 'https://www.googleapis.com/auth/grpc-testing' +authorization = Google::Auth.get_application_default(scope) +stub = Helloworld::Greeter::Stub.new('localhost:50051', + creds: creds, + update_metadata: authorization.updater_proc) +``` + +###Authenticating with Google (Node.js) + +```node +// Base case - No encryption/authorization +var stub = new helloworld.Greeter('localhost:50051'); +... +// Authenticating with Google +var GoogleAuth = require('google-auth-library'); // from https://www.npmjs.com/package/google-auth-library +... +var creds = grpc.Credentials.createSsl(load_certs); // load_certs typically loads a CA roots file +var scope = 'https://www.googleapis.com/auth/grpc-testing'; +(new GoogleAuth()).getApplicationDefault(function(err, auth) { + if (auth.createScopeRequired()) { + auth = auth.createScoped(scope); + } + var stub = new helloworld.Greeter('localhost:50051', + {credentials: creds}, + grpc.getGoogleAuthDelegate(auth)); +}); +``` + +###Authenticating with Google (C#) +```csharp +// Base case - No encryption/authorization +var channel = new Channel("localhost:50051"); +var client = new Greeter.GreeterClient(channel); +... + +// Authenticating with Google +using Grpc.Auth; // from Grpc.Auth NuGet package +... +var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file +var channel = new Channel("localhost:50051", credentials); + +string scope = "https://www.googleapis.com/auth/grpc-testing"; +var authorization = GoogleCredential.GetApplicationDefault(); +if (authorization.IsCreateScopedRequired) +{ + authorization = credential.CreateScoped(new[] { scope }); +} +var client = new Greeter.GreeterClient(channel, + new StubConfiguration(OAuth2InterceptorFactory.Create(credential))); +``` + +###Authenticating with Google (PHP) +```php +// Base case - No encryption/authorization +$client = new helloworld\GreeterClient( + new Grpc\BaseStub('localhost:50051', [])); +... + +// Authenticating with Google +// the environment variable "GOOGLE_APPLICATION_CREDENTIALS" needs to be set +$scope = "https://www.googleapis.com/auth/grpc-testing"; +$auth = Google\Auth\ApplicationDefaultCredentials::getCredentials($scope); +$opts = [ + 'credentials' => Grpc\Credentials::createSsl(file_get_contents('ca.pem')); + 'update_metadata' => $auth->getUpdateMetadataFunc(), +]; + +$client = new helloworld\GreeterClient( + new Grpc\BaseStub('localhost:50051', $opts)); + +``` + +###Authenticating with Google (Objective-C) + +This example uses the [Google iOS Sign-In library](https://developers.google.com/identity/sign-in/ios/), +but it's easily extrapolated to any other OAuth2 library. + +```objective-c +// Base case - No authentication +[client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { + ... +}]; + +... + +// Authenticating with Google + +// When signing the user in, ask her for the relevant scopes. +GIDSignIn.sharedInstance.scopes = @[@"https://www.googleapis.com/auth/grpc-testing"]; + +... + +#import + +// Create a not-yet-started RPC. We want to set the request headers on this object before starting +// it. +ProtoRPC *call = + [client RPCToSayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { + ... + }]; + +// Set the access token to be used. +NSString *accessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken; +call.requestMetadata[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken]}]; + +// Start the RPC. +[call start]; +``` + +You can see a working example app, with a more detailed explanation, [here](https://github.com/grpc/grpc-common/tree/master/objective-c/auth_sample). + +### Authenticating with Google (Python) +```python +# Base case - No encryption +stub = early_adopter_create_GreeterService_stub('localhost', 50051) +... + +# With server authentication SSL/TLS +import oauth2client.client +credentials = oauth2client.GoogleCredentials.get_application_default() +scope = 'https://www.googleapis.com/auth/grpc-testing' +scoped_credentials = credentials.create_scoped([scope]) +access_token = scoped_credentials.get_access_token().access_token +metadata_transformer = ( + lambda x: [('Authorization', 'Bearer {}'.format(access_token))]) + +stub = early_adopter_create_GreeterService_stub( + 'localhost', 50051, secure=True, root_certificates=open('ca.pem').read(), + metadata_transformer=metadata_transformer) +... +``` +n.b.: the beta API will look different diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000000..5939db3ab5 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,449 @@ + +# Getting started + +Welcome to the developer documentation for gRPC, a language-neutral, +platform-neutral remote procedure call (RPC) system developed at Google. + +This document introduces you to gRPC with a quick overview and a simple +Hello World example. You'll find more tutorials and reference docs in this repository - more documentation is coming soon! + + +## Quick start +You can find quick start guides for each language, including installation instructions, examples, and tutorials here: +* [C++](https://github.com/grpc/grpc-common/tree/master/cpp) +* [Java](https://github.com/grpc/grpc-common/tree/master/java) +* [Go](https://github.com/grpc/grpc-common/tree/master/go) +* [Ruby](https://github.com/grpc/grpc-common/tree/master/ruby) +* [Node.js](https://github.com/grpc/grpc-common/tree/master/node) +* [Android Java](https://github.com/grpc/grpc-common/tree/master/java/android) +* [Python](https://github.com/grpc/grpc-common/tree/master/python/helloworld) +* [C#](https://github.com/grpc/grpc-common/tree/master/csharp) +* [Objective-C](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide) + +## What's in this repository? + +The `grpc-common` repository contains documentation, resources, and examples +for all gRPC users. You can find examples and instructions specific to your +favourite language in the relevant subdirectory. + +You can find out about the gRPC source code repositories in +[`grpc`](https://github.com/grpc/grpc). Each repository provides instructions +for building the appropriate libraries for your language. + + +## What is gRPC? + +In gRPC a *client* application can directly call +methods on a *server* application on a different machine as if it was a +local object, making it easier for you to create distributed applications and +services. As in many RPC systems, gRPC is based around the idea of defining +a *service*, specifying the methods that can be called remotely with their +parameters and return types. On the server side, the server implements this +interface and runs a gRPC server to handle client calls. On the client side, +the client has a *stub* that provides exactly the same methods as the server. + + + +gRPC clients and servers can run and talk to each other in a variety of +environments - from servers inside Google to your own desktop - and can +be written in any of gRPC's [supported languages](#quickstart). So, for +example, you can easily create a gRPC server in Java with clients in Go, +Python, or Ruby. In addition, the latest Google APIs will have gRPC versions +of their interfaces, letting you easily build Google functionality into +your applications. + + +### Working with protocol buffers + +By default gRPC uses *protocol buffers*, Google’s +mature open source mechanism for serializing structured data (although it +can be used with other data formats such as JSON). As you'll +see in our example below, you define gRPC services using *proto files*, +with method parameters and return types specified as protocol buffer message +types. You +can find out lots more about protocol buffers in the [Protocol Buffers +documentation](https://developers.google.com/protocol-buffers/docs/overview). + +#### Protocol buffer versions + +While protocol buffers have been available for open source users for some +time, our examples use a new flavour of protocol buffers called proto3, +which has a slightly simplified syntax, some useful new features, and supports +lots more languages. This is currently available as an alpha release in +Java, C++, Java_nano (Android Java), Python, and Ruby from [the protocol buffers Github +repo](https://github.com/google/protobuf/releases), as well as a Go language +generator from [the golang/protobuf Github repo](https://github.com/golang/protobuf), with more languages in development. You can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3), and see +the major differences from the current default version in the [release notes](https://github.com/google/protobuf/releases). More proto3 documentation is coming soon. + +In general, while you *can* use proto2 (the current default protocol buffers version), we recommend that you use proto3 with gRPC as it lets you use the full range of gRPC-supported languages, as well as avoiding compatibility +issues with proto2 clients talking to proto3 servers and vice versa. + + +## Hello gRPC! + +Now that you know a bit more about gRPC, the easiest way to see how it +works is to look at a simple example. Our Hello World walks you through the +construction of a simple gRPC client-server application, showing you how to: + +- Create a protocol buffers schema that defines a simple RPC service with +a single +Hello World method. +- Create a Java server that implements this interface. +- Create a Java client that accesses the Java server. +- Create a Go client that accesses +the same Java server. + +The complete code for the example is available in the `grpc-common` GitHub +repository. We use the Git versioning system for source code management: +however, you don't need to know anything about Git to follow along other +than how to install and run a few git commands. + +This is an introductory example rather than a comprehensive tutorial, so +don't worry if you're not a Go or +Java developer - the concepts are similar for all languages, and you can +find more implementations of our Hello World example in other languages (and full tutorials where available) in +the [language-specific folders](#quickstart) in this repository. Complete tutorials and +reference documentation for all gRPC languages are coming soon. + + +### Setup + +This section explains how to set up your local machine to work with +the example code. If you just want to read the example, you can go straight +to the [next step](#servicedef). + +#### Install Git + +You can download and install Git from http://git-scm.com/download. Once +installed you should have access to the git command line tool. The main +commands that you will need to use are: + +- git clone ... : clone a remote repository onto your local machine +- git checkout ... : check out a particular branch or a tagged version of +the code to hack on + +#### Install gRPC + +To build and install gRPC plugins and related tools: +- For Java, see the [Java quick start](https://github.com/grpc/grpc-java). +- For Go, see the [Go quick start](https://github.com/grpc/grpc-go). + +#### Get the source code + +The example code for our Java example lives in the `grpc-java` +GitHub repository. Clone this repository to your local machine by running the +following command: + + +``` +git clone https://github.com/grpc/grpc-java.git +``` + +Change your current directory to grpc-java/examples + +``` +cd grpc-java/examples +``` + + + + +### Defining a service + +The first step in creating our example is to define a *service*: an RPC +service specifies the methods that can be called remotely with their parameters +and return types. As you saw in the +[overview](#protocolbuffers) above, gRPC does this using [protocol +buffers](https://developers.google.com/protocol-buffers/docs/overview). We +use the protocol buffers interface definition language (IDL) to define our +service methods, and define the parameters and return +types as protocol buffer message types. Both the client and the +server use interface code generated from the service definition. + +Here's our example service definition, defined using protocol buffers IDL in +[helloworld.proto](https://github.com/grpc/grpc-java/tree/master/examples/src/main/proto). The `Greeter` +service has one method, `SayHello`, that lets the server receive a single +`HelloRequest` +message from the remote client containing the user's name, then send back +a greeting in a single `HelloReply`. This is the simplest type of RPC you +can specify in gRPC - you can find out about other types in the tutorial for your chosen language. + +```proto +syntax = "proto3"; + +option java_package = "io.grpc.examples"; + +package helloworld; + +// The greeter service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} + +``` + + +### Generating gRPC code + +Once we've defined our service, we use the protocol buffer compiler +`protoc` to generate the special client and server code we need to create +our application - right now we're going to generate Java code, though you +can generate gRPC code in any gRPC-supported language (as you'll see later +in this example). The generated code contains both stub code for clients to +use and an abstract interface for servers to implement, both with the method +defined in our `Greeter` service. + +(If you didn't install the gRPC plugins and protoc on your system and are just reading along with +the example, you can skip this step and move +onto the next one where we examine the generated code.) + +For simplicity, we've provided a [Gradle build file](https://github.com/grpc/grpc-java/blob/master/examples/build.gradle) with our Java examples that runs `protoc` for you with the appropriate plugin, input, and output: + +```shell +../gradlew build +``` + +This generates the following classes from our .proto, which contain all the generated code +we need to create our example: + +- `Helloworld.java`, which +has all the protocol buffer code to populate, serialize, and retrieve our +`HelloRequest` and `HelloReply` message types +- `GreeterGrpc.java`, which contains (along with some other useful code): + - an interface for `Greeter` servers to implement + + ```java + public static interface Greeter { + public void sayHello(io.grpc.examples.Helloworld.HelloRequest request, + io.grpc.stub.StreamObserver responseObserver); + } + ``` + + - _stub_ classes that clients can use to talk to a `Greeter` server. As you can see, they also implement the `Greeter` interface. + + ```java + public static class GreeterStub extends + io.grpc.stub.AbstractStub + implements Greeter { + ... + } + ``` + + +### Writing a server + +Now let's write some code! First we'll create a server application to implement +our service. Note that we're not going to go into a lot of detail about how +to create a server in this section. More detailed information will be in the +tutorial for your chosen language: check if there's one available yet in the relevant [quick start](#quickstart). + +Our server application has two classes: + +- a main server class that hosts the service implementation and allows access over the +network: [HelloWorldServer.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java). + + +- a simple service implementation class [GreeterImpl.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java#L51). + + +#### Service implementation + +[GreeterImpl.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java#L51) +actually implements our `Greeter` service's required behaviour. + +As you can see, the class `GreeterImpl` implements the interface +`GreeterGrpc.Greeter` that we [generated](#generating) from our proto +[IDL](https://github.com/grpc/grpc-java/tree/master/examples/src/main/proto) by implementing the method `sayHello`: + +```java + @Override + public void sayHello(HelloRequest req, StreamObserver responseObserver) { + HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build(); + responseObserver.onValue(reply); + responseObserver.onCompleted(); + } +``` +- `sayHello` takes two parameters: + - `HelloRequest`: the request + - `StreamObserver`: a response observer, which is + a special interface for the server to call with its response + +To return our response to the client and complete the call: + +1. We construct and populate a `HelloReply` response object with our exciting +message, as specified in our interface definition. +2. We return the `HelloReply` to the client and then specify that we've finished dealing with the RPC. + + +#### Server implementation + +[HelloWorldServer.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java) +shows the other main feature required to provide a gRPC service; making the service +implementation available from the network. + +```java + /* The port on which the server should run */ + private int port = 50051; + private ServerImpl server; + + private void start() throws Exception { + server = NettyServerBuilder.forPort(port) + .addService(GreeterGrpc.bindService(new GreeterImpl())) + .build().start(); + logger.info("Server started, listening on " + port); + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + // Use stderr here since the logger may have been reset by its JVM shutdown hook. + System.err.println("*** shutting down gRPC server since JVM is shutting down"); + HelloWorldServer.this.stop(); + System.err.println("*** server shut down"); + } + }); + } + +``` + +Here we create an appropriate gRPC server, binding the `Greeter` service +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. + + +### Writing a client + +Client-side gRPC is pretty simple. In this step, we'll use the generated code +to write a simple client that can access the `Greeter` server we created +in the [previous section](#server). You can see the complete client code in +[HelloWorldClient.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldClient.java). + +Again, we're not going to go into much detail about how to implement a client; +we'll leave that for the tutorial. + +#### Connecting to the service + +First let's look at how we connect to the `Greeter` server. First we need +to create a gRPC channel, specifying the hostname and port of the server we +want to connect to. Then we use the channel to construct the stub instance. + + +```java + private final ChannelImpl channel; + private final GreeterGrpc.GreeterBlockingStub blockingStub; + + public HelloWorldClient(String host, int port) { + channel = + NettyChannelBuilder.forAddress(host, port).negotiationType(NegotiationType.PLAINTEXT) + .build(); + blockingStub = GreeterGrpc.newBlockingStub(channel); + } + +``` + +In this case, we create a blocking stub. This means that the RPC call waits +for the server to respond, and will either return a response or raise an +exception. gRPC Java has other kinds of stubs that make non-blocking calls +to the server, where the response is returned asynchronously. + +#### Calling an RPC + +Now we can contact the service and obtain a greeting: + +1. We construct and fill in a `HelloRequest` to send to the service. +2. We call the stub's `hello()` RPC with our request and get a `HelloReply` +back, from which we can get our greeting. + + +```java + HelloRequest req = HelloRequest.newBuilder().setName(name).build(); + HelloReply reply = blockingStub.sayHello(req); + +``` + + +### Try it out! + +Our [Gradle build file](https://github.com/grpc/grpc-java/blob/master/examples/build.gradle) simplifies building and running the examples. + +You can build and run the server from the `grpc-java` root folder with: + +```sh +$ ./gradlew :grpc-examples:helloWorldServer +``` + +and in another terminal window confirm that it receives a message. + +```sh +$ ./gradlew :grpc-examples:helloWorldClient +``` + +### 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 looked at Java code +generated from and implementing our `Greeter` service definition. However, +as you'll see if you look at the language-specific subdirectories +in this repository, we've also generated and implemented `Greeter` +in some of gRPC's other supported languages. Each service +and client uses interface code generated from the same proto +that we used for the Java example. + +So, for example, if we visit the [`go` example +directory](https://github.com/grpc/grpc-common/tree/master/go) and look at the +[`greeter_client`](https://github.com/grpc/grpc-common/blob/master/go/greeter_client/main.go), +we can see that like the Java client, it connects to a `Greeter` service +at `localhost:50051` and uses a stub to call the `SayHello` method with a +`HelloRequest`: + +```go +const ( + address = "localhost:50051" + defaultName = "world" +) + +func main() { + // Set up a connection to the server. + conn, err := grpc.Dial(address) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + defer conn.Close() + c := pb.NewGreeterClient(conn) + + // Contact the server and print out its response. + name := defaultName + if len(os.Args) > 1 { + name = os.Args[1] + } + r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: + name}) + if err != nil { + log.Fatalf("could not greet: %v", err) + } + log.Printf("Greeting: %s", r.Message) +} +``` + + +If we run the Java server from earlier in another terminal window, we can +run the Go client and connect to it just like the Java client, even though +it's written in a different language. + +``` +$ greeter_client +``` +## Read more! + +- You can find links to language-specific tutorials, examples, and other docs in each language's [quick start](#quickstart). +- [gRPC Authentication Support](https://github.com/grpc/grpc-common/blob/master/grpc-auth-support.md) introduces authentication support in gRPC with supported mechanisms and examples. diff --git a/examples/cpp/README.md b/examples/cpp/README.md new file mode 100644 index 0000000000..e0a09ff8b8 --- /dev/null +++ b/examples/cpp/README.md @@ -0,0 +1,65 @@ +#gRPC in 3 minutes (C++) + +## Installation + +To install gRPC on your system, follow the instructions here: +[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). + +## Hello C++ gRPC! + +Here's how to build and run the C++ implementation of the [Hello World](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto) example used in [Getting started](https://github.com/grpc/grpc-common). + +The example code for this and our other examples lives in the `grpc-common` +GitHub repository. Clone this repository to your local machine by running the +following command: + + +```sh +$ git clone https://github.com/grpc/grpc-common.git +``` + +Change your current directory to grpc-common/cpp/helloworld + +```sh +$ cd grpc-common/cpp/helloworld/ +``` + + +### Generating gRPC code + +To generate the client and server side interfaces: + +```sh +$ make helloworld.grpc.pb.cc helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + +```sh +$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto +``` + +### Client and server implementations + +The client implementation is at [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). + +The server implementation is at [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). + +### Try it! +Build client and server: +```sh +$ make +``` +Run the server, which will listen on port 50051: +```sh +$ ./greeter_server +``` +Run the client (in a different terminal): +```sh +$ ./greeter_client +``` +If things go smoothly, you will see the "Greeter received: Hello world" in the client side output. + +## Tutorial + +You can find a more detailed tutorial in [gRPC Basics: C++](https://github.com/grpc/grpc-common/blob/master/cpp/cpptutorial.md) diff --git a/examples/cpp/cpptutorial.md b/examples/cpp/cpptutorial.md new file mode 100644 index 0000000000..c19b472744 --- /dev/null +++ b/examples/cpp/cpptutorial.md @@ -0,0 +1,365 @@ +#gRPC Basics: C++ + +This tutorial provides a basic C++ programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate server and client code using the protocol buffer compiler. +- Use the C++ gRPC API to write a simple client and server for your service. + +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. + +This isn't a comprehensive guide to using gRPC in C++: more reference documentation is coming soon. + +## Why use gRPC? + +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/cpp/route_guide](https://github.com/grpc/grpc-common/tree/master/cpp/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/cpp/route_guide`: +```shell +$ cd grpc-common/cpp/route_guide +``` + +You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the C++ quick start guide](https://github.com/grpc/grpc-common/tree/master/cpp). + + +## Defining the service + +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +``` +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +``` + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. +``` + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} +``` + +- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a client-side streaming method by placing the `stream` keyword before the *request* type. +``` + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +``` + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +``` +// 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; +} +``` + + +## Generating client and server code + +Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. + +For simplicity, we've provided a [makefile](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): + +```shell +$ make route_guide.grpc.pb.cc route_guide.pb.cc +``` + +which actually runs: + +```shell +$ protoc -I ../../protos --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ../../protos/route_guide.proto +$ protoc -I ../../protos --cpp_out=. ../../protos/route_guide.proto +``` + +Running this command generates the following files in your current directory: +- `route_guide.pb.h`, the header which declares your generated message classes +- `route_guide.pb.cc`, which contains the implementation of your message classes +- `route_guide.grpc.pb.h`, the header which declares your generated service classes +- `route_guide.grpc.pb.cc`, which contains the implementation of your service classes + +These contain: +- All the protocol buffer code to populate, serialize, and retrieve our request and response message types +- A class called `RouteGuide` that contains + - a remote interface type (or *stub*) for clients to call with the methods defined in the `RouteGuide` service. + - two abstract interfaces for servers to implement, also with the methods defined in the `RouteGuide` service. + + + +## Creating the server + +First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). + +There are two parts to making our `RouteGuide` service do its job: +- Implementing the service interface generated from our service definition: doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and return the service responses. + +You can find our example `RouteGuide` server in [grpc-common/cpp/route_guide/route_guide_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_server.cc). Let's take a closer look at how it works. + +### Implementing RouteGuide + +As you can see, our server has a `RouteGuideImpl` class that implements the generated `RouteGuide::Service` interface: + +```cpp +class RouteGuideImpl final : public RouteGuide::Service { +... +} +``` +In this case we're implementing the *synchronous* version of `RouteGuide`, which provides our default gRPC server behaviour. It's also possible to implement an asynchronous interface, `RouteGuide::AsyncService`, which allows you to further customize your server's threading behaviour, though we won't look at this in this tutorial. + +`RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. + +```cpp + Status GetFeature(ServerContext* context, const Point* point, + Feature* feature) override { + feature->set_name(GetFeatureName(*point, feature_list_)); + feature->mutable_location()->CopyFrom(*point); + return Status::OK; + } +``` + +The method is passed a context object for the RPC, the client's `Point` protocol buffer request, and a `Feature` protocol buffer to fill in with the response information. In the method we populate the `Feature` with the appropriate information, and then `return` with an `OK` status to tell gRPC that we've finished dealing with the RPC and that the `Feature` can be returned to the client. + +Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. + +```cpp + Status ListFeatures(ServerContext* context, const Rectangle* rectangle, + ServerWriter* writer) override { + auto lo = rectangle->lo(); + auto hi = rectangle->hi(); + long left = std::min(lo.longitude(), hi.longitude()); + long right = std::max(lo.longitude(), hi.longitude()); + long top = std::max(lo.latitude(), hi.latitude()); + long bottom = std::min(lo.latitude(), hi.latitude()); + for (const Feature& f : feature_list_) { + if (f.location().longitude() >= left && + f.location().longitude() <= right && + f.location().latitude() >= bottom && + f.location().latitude() <= top) { + writer->Write(f); + } + } + return Status::OK; + } +``` + +As you can see, instead of getting simple request and response objects in our method parameters, this time we get a request object (the `Rectangle` in which our client wants to find `Feature`s) and a special `ServerWriter` object. In the method, we populate as many `Feature` objects as we need to return, writing them to the `ServerWriter` using its `Write()` method. Finally, as in our simple RPC, we `return Status::OK` to tell gRPC that we've finished writing responses. + +If you look at the client-side streaming method `RecordRoute` you'll see it's quite similar, except this time we get a `ServerReader` instead of a request object and a single response. We use the `ServerReader`s `Read()` method to repeatedly read in our client's requests to a request object (in this case a `Point`) until there are no more messages: the server needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. + +```cpp +while (stream->Read(&point)) { + ...//process client input +} +``` +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. + +```cpp + Status RouteChat(ServerContext* context, + ServerReaderWriter* stream) override { + std::vector received_notes; + RouteNote note; + while (stream->Read(¬e)) { + for (const RouteNote& n : received_notes) { + if (n.location().latitude() == note.location().latitude() && + n.location().longitude() == note.location().longitude()) { + stream->Write(n); + } + } + received_notes.push_back(note); + } + + return Status::OK; + } +``` + +This time we get a `ServerReaderWriter` that can be used to read *and* write messages. The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + +### Starting the server + +Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: + +```cpp +void RunServer(const std::string& db_path) { + std::string server_address("0.0.0.0:50051"); + RouteGuideImpl service(db_path); + + ServerBuilder builder; + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + builder.RegisterService(&service); + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + server->Wait(); +} +``` +As you can see, we build and start our server using a `ServerBuilder`. To do this, we: + +1. Create an instance of our service implementation class `RouteGuideImpl`. +2. Create an instance of the factory `ServerBuilder` class. +3. Specify the address and port we want to use to listen for client requests using the builder's `AddListeningPort()` method. +4. Register our service implementation with the builder. +5. Call `BuildAndStart()` on the builder to create and start an RPC server for our service. +5. Call `Wait()` on the server to do a blocking wait until process is killed or `Shutdown()` is called. + + +## Creating the client + +In this section, we'll look at creating a C++ client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/cpp/route_guide/route_guide_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_client.cc). + +### Creating a stub + +To call service methods, we first need to create a *stub*. + +First we need to create a gRPC *channel* for our stub, specifying the server address and port we want to connect to and any special channel arguments - in our case we'll use the default `ChannelArguments` and no SSL: + +```cpp +grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), ChannelArguments()); +``` + +Now we can use the channel to create our stub using the `NewStub` method provided in the `RouteGuide` class we generated from our .proto. + +```cpp + public: + RouteGuideClient(std::shared_ptr channel, const std::string& db) + : stub_(RouteGuide::NewStub(channel)) { + ... + } +``` + +### Calling service methods + +Now let's look at how we call our service methods. Note that in this tutorial we're calling the *blocking/synchronous* versions of each method: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception. + +#### Simple RPC + +Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. + +```cpp + Point point; + Feature feature; + point = MakePoint(409146138, -746188906); + GetOneFeature(point, &feature); + +... + + bool GetOneFeature(const Point& point, Feature* feature) { + ClientContext context; + Status status = stub_->GetFeature(&context, point, feature); + ... + } +``` + +As you can see, we create and populate a request protocol buffer object (in our case `Point`), and create a response protocol buffer object for the server to fill in. We also create a `ClientContext` object for our call - you can optionally set RPC configuration values on this object, such as deadlines, though for now we'll use the default settings. Note that you cannot reuse this object between calls. Finally, we call the method on the stub, passing it the context, request, and response. If the method returns `OK`, then we can read the response information from the server from our response object. + +```cpp + std::cout << "Found feature called " << feature->name() << " at " + << feature->location().latitude()/kCoordFactor_ << ", " + << feature->location().longitude()/kCoordFactor_ << std::endl; +``` + +#### Streaming RPCs + +Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: + +```cpp + std::unique_ptr > reader( + stub_->ListFeatures(&context, rect)); + while (reader->Read(&feature)) { + std::cout << "Found feature called " + << feature.name() << " at " + << feature.location().latitude()/kCoordFactor_ << ", " + << feature.location().longitude()/kCoordFactor_ << std::endl; + } + Status status = reader->Finish(); +``` + +Instead of passing the method a context, request, and response, we pass it a context and request and get a `ClientReader` object back. The client can use the `ClientReader` to read the server's responses. We use the `ClientReader`s `Read()` method to repeatedly read in the server's responses to a response protocol buffer object (in this case a `Feature`) until there are no more messages: the client needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. Finally, we call `Finish()` on the stream to complete the call and get our RPC status. + +The client-side streaming method `RecordRoute` is similar, except there we pass the method a context and response object and get back a `ClientWriter`. + +```cpp + std::unique_ptr > writer( + stub_->RecordRoute(&context, &stats)); + for (int i = 0; i < kPoints; i++) { + const Feature& f = feature_list_[feature_distribution(generator)]; + std::cout << "Visiting point " + << f.location().latitude()/kCoordFactor_ << ", " + << f.location().longitude()/kCoordFactor_ << std::endl; + if (!writer->Write(f.location())) { + // Broken stream. + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds( + delay_distribution(generator))); + } + writer->WritesDone(); + Status status = writer->Finish(); + if (status.IsOk()) { + std::cout << "Finished trip with " << stats.point_count() << " points\n" + << "Passed " << stats.feature_count() << " features\n" + << "Travelled " << stats.distance() << " meters\n" + << "It took " << stats.elapsed_time() << " seconds" + << std::endl; + } else { + std::cout << "RecordRoute rpc failed." << std::endl; + } +``` + +Once we've finished writing our client's requests to the stream using `Write()`, we need to call `WritesDone()` on the stream to let gRPC know that we've finished writing, then `Finish()` to complete the call and get our RPC status. If the status is `OK`, our response object that we initially passed to `RecordRoute()` will be populated with the server's response. + +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. In this case, we just pass a context to the method and get back a `ClientReaderWriter`, which we can use to both write and read messages. + +```cpp + std::shared_ptr > stream( + stub_->RouteChat(&context)); +``` + +The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + +## Try it out! + +Build client and server: +```shell +$ make +``` +Run the server, which will listen on port 50051: +```shell +$ ./route_guide_server +``` +Run the client (in a different terminal): +```shell +$ ./route_guide_client +``` + diff --git a/examples/cpp/helloworld/Makefile b/examples/cpp/helloworld/Makefile new file mode 100644 index 0000000000..f2093afa05 --- /dev/null +++ b/examples/cpp/helloworld/Makefile @@ -0,0 +1,119 @@ +# +# 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++_unsecure -lgrpc -lgpr -lprotobuf -lpthread -ldl +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` + +PROTOS_PATH = ../../protos + +vpath %.proto $(PROTOS_PATH) + +all: system-check greeter_client greeter_server greeter_async_client greeter_async_server + +greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o + $(CXX) $^ $(LDFLAGS) -o $@ + +greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o + $(CXX) $^ $(LDFLAGS) -o $@ + +greeter_async_client: helloworld.pb.o helloworld.grpc.pb.o greeter_async_client.o + $(CXX) $^ $(LDFLAGS) -o $@ + +greeter_async_server: helloworld.pb.o helloworld.grpc.pb.o greeter_async_server.o + $(CXX) $^ $(LDFLAGS) -o $@ + +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + +clean: + rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server greeter_async_client greeter_async_server + + +# The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + +PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + +SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif + +system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-alpha-1" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif diff --git a/examples/cpp/helloworld/README.md b/examples/cpp/helloworld/README.md new file mode 100644 index 0000000000..c406051e80 --- /dev/null +++ b/examples/cpp/helloworld/README.md @@ -0,0 +1,260 @@ +# gRPC C++ Hello World Tutorial + +### Install gRPC +Make sure you have installed gRPC on your system. Follow the instructions here: +[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). + +### Get the tutorial source code + +The example code for this and our other examples lives in the `grpc-common` +GitHub repository. Clone this repository to your local machine by running the +following command: + + +```sh +$ git clone https://github.com/grpc/grpc-common.git +``` + +Change your current directory to grpc-common/cpp/helloworld + +```sh +$ cd grpc-common/cpp/helloworld/ +``` + +### Defining a service + +The first step in creating our example is to define a *service*: an RPC +service specifies the methods that can be called remotely with their parameters +and return types. As you saw in the +[overview](#protocolbuffers) above, gRPC does this using [protocol +buffers](https://developers.google.com/protocol-buffers/docs/overview). We +use the protocol buffers interface definition language (IDL) to define our +service methods, and define the parameters and return +types as protocol buffer message types. Both the client and the +server use interface code generated from the service definition. + +Here's our example service definition, defined using protocol buffers IDL in +[helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). The `Greeting` +service has one method, `hello`, that lets the server receive a single +`HelloRequest` +message from the remote client containing the user's name, then send back +a greeting in a single `HelloReply`. This is the simplest type of RPC you +can specify in gRPC - we'll look at some other types later in this document. + +``` +syntax = "proto3"; + +option java_package = "ex.grpc"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} + +``` + + +### Generating gRPC code + +Once we've defined our service, we use the protocol buffer compiler +`protoc` to generate the special client and server code we need to create +our application. The generated code contains both stub code for clients to +use and an abstract interface for servers to implement, both with the method +defined in our `Greeting` service. + +To generate the client and server side interfaces: + +```sh +$ make helloworld.grpc.pb.cc helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + +```sh +$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto +``` + +### Writing a client + +- Create a channel. A channel is a logical connection to an endpoint. A gRPC + channel can be created with the target address, credentials to use and + arguments as follows + + ``` + auto channel = CreateChannel("localhost:50051", InsecureCredentials(), ChannelArguments()); + ``` + +- Create a stub. A stub implements the rpc methods of a service and in the + generated code, a method is provided to created a stub with a channel: + + ``` + auto stub = helloworld::Greeter::NewStub(channel); + ``` + +- Make a unary rpc, with `ClientContext` and request/response proto messages. + + ``` + ClientContext context; + HelloRequest request; + request.set_name("hello"); + HelloReply reply; + Status status = stub->SayHello(&context, request, &reply); + ``` + +- Check returned status and response. + + ``` + if (status.ok()) { + // check reply.message() + } else { + // rpc failed. + } + ``` + +For a working example, refer to [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). + +### Writing a server + +- Implement the service interface + + ``` + 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; + } + }; + + ``` + +- Build a server exporting the service + + ``` + GreeterServiceImpl service; + ServerBuilder builder; + builder.AddListeningPort("0.0.0.0:50051", grpc::InsecureServerCredentials()); + builder.RegisterService(&service); + std::unique_ptr server(builder.BuildAndStart()); + ``` + +For a working example, refer to [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). + +### Writing asynchronous client and server + +gRPC uses `CompletionQueue` API for asynchronous operations. The basic work flow +is +- bind a `CompletionQueue` to a rpc call +- do something like a read or write, present with a unique `void*` tag +- call `CompletionQueue::Next` to wait for operations to complete. If a tag + appears, it indicates that the corresponding operation is complete. + +#### Async client + +The channel and stub creation code is the same as the sync client. + +- Initiate the rpc and create a handle for the rpc. Bind the rpc to a + `CompletionQueue`. + + ``` + CompletionQueue cq; + auto rpc = stub->AsyncSayHello(&context, request, &cq); + ``` + +- Ask for reply and final status, with a unique tag + + ``` + Status status; + rpc->Finish(&reply, &status, (void*)1); + ``` + +- Wait for the completion queue to return the next tag. The reply and status are + ready once the tag passed into the corresponding `Finish()` call is returned. + + ``` + void* got_tag; + bool ok = false; + cq.Next(&got_tag, &ok); + if (ok && got_tag == (void*)1) { + // check reply and status + } + ``` + +For a working example, refer to [greeter_async_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_async_client.cc). + +#### Async server + +The server implementation requests a rpc call with a tag and then wait for the +completion queue to return the tag. The basic flow is + +- Build a server exporting the async service + + ``` + helloworld::Greeter::AsyncService service; + ServerBuilder builder; + builder.AddListeningPort("0.0.0.0:50051", InsecureServerCredentials()); + builder.RegisterAsyncService(&service); + auto cq = builder.AddCompletionQueue(); + auto server = builder.BuildAndStart(); + ``` + +- Request one rpc + + ``` + ServerContext context; + HelloRequest request; + ServerAsyncResponseWriter responder; + service.RequestSayHello(&context, &request, &responder, &cq, &cq, (void*)1); + ``` + +- Wait for the completion queue to return the tag. The context, request and + responder are ready once the tag is retrieved. + + ``` + HelloReply reply; + Status status; + void* got_tag; + bool ok = false; + cq.Next(&got_tag, &ok); + if (ok && got_tag == (void*)1) { + // set reply and status + responder.Finish(reply, status, (void*)2); + } + ``` + +- Wait for the completion queue to return the tag. The rpc is finished when the + tag is back. + + ``` + void* got_tag; + bool ok = false; + cq.Next(&got_tag, &ok); + if (ok && got_tag == (void*)2) { + // clean up + } + ``` + +To handle multiple rpcs, the async server creates an object `CallData` to +maintain the state of each rpc and use the address of it as the unique tag. For +simplicity the server only uses one completion queue for all events, and runs a +main loop in `HandleRpcs` to query the queue. + +For a working example, refer to [greeter_async_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_async_server.cc). + + + + diff --git a/examples/cpp/helloworld/greeter_async_client.cc b/examples/cpp/helloworld/greeter_async_client.cc new file mode 100644 index 0000000000..d99f89b135 --- /dev/null +++ b/examples/cpp/helloworld/greeter_async_client.cc @@ -0,0 +1,98 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "helloworld.grpc.pb.h" + +using grpc::Channel; +using grpc::ChannelArguments; +using grpc::ClientAsyncResponseReader; +using grpc::ClientContext; +using grpc::CompletionQueue; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterClient { + public: + explicit GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + std::string SayHello(const std::string& user) { + HelloRequest request; + request.set_name(user); + HelloReply reply; + ClientContext context; + CompletionQueue cq; + Status status; + + std::unique_ptr > rpc( + stub_->AsyncSayHello(&context, request, &cq)); + rpc->Finish(&reply, &status, (void*)1); + void* got_tag; + bool ok = false; + cq.Next(&got_tag, &ok); + GPR_ASSERT(ok); + GPR_ASSERT(got_tag == (void*)1); + + if (status.ok()) { + return reply.message(); + } else { + return "Rpc failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + GreeterClient greeter(grpc::CreateChannel( + "localhost:50051", grpc::InsecureCredentials(), ChannelArguments())); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter received: " << reply << std::endl; + + return 0; +} diff --git a/examples/cpp/helloworld/greeter_async_server.cc b/examples/cpp/helloworld/greeter_async_server.cc new file mode 100644 index 0000000000..b8a0dbf0e2 --- /dev/null +++ b/examples/cpp/helloworld/greeter_async_server.cc @@ -0,0 +1,136 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "helloworld.grpc.pb.h" + +using grpc::Server; +using grpc::ServerAsyncResponseWriter; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::ServerCompletionQueue; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class ServerImpl final { + public: + ~ServerImpl() { + server_->Shutdown(); + cq_->Shutdown(); + } + + // There is no shutdown handling in this code. + void Run() { + std::string server_address("0.0.0.0:50051"); + + ServerBuilder builder; + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + builder.RegisterAsyncService(&service_); + cq_ = builder.AddCompletionQueue(); + server_ = builder.BuildAndStart(); + std::cout << "Server listening on " << server_address << std::endl; + + HandleRpcs(); + } + + private: + class CallData { + public: + CallData(Greeter::AsyncService* service, ServerCompletionQueue* cq) + : service_(service), cq_(cq), responder_(&ctx_), status_(CREATE) { + Proceed(); + } + + void Proceed() { + if (status_ == CREATE) { + service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_, + this); + status_ = PROCESS; + } else if (status_ == PROCESS) { + new CallData(service_, cq_); + std::string prefix("Hello "); + reply_.set_message(prefix + request_.name()); + responder_.Finish(reply_, Status::OK, this); + status_ = FINISH; + } else { + delete this; + } + } + + private: + Greeter::AsyncService* service_; + ServerCompletionQueue* cq_; + ServerContext ctx_; + HelloRequest request_; + HelloReply reply_; + ServerAsyncResponseWriter responder_; + enum CallStatus { CREATE, PROCESS, FINISH }; + CallStatus status_; + }; + + // This can be run in multiple threads if needed. + void HandleRpcs() { + new CallData(&service_, cq_.get()); + void* tag; + bool ok; + while (true) { + cq_->Next(&tag, &ok); + GPR_ASSERT(ok); + static_cast(tag)->Proceed(); + } + } + + std::unique_ptr cq_; + Greeter::AsyncService service_; + std::unique_ptr server_; +}; + +int main(int argc, char** argv) { + ServerImpl server; + server.Run(); + + return 0; +} diff --git a/examples/cpp/helloworld/greeter_client.cc b/examples/cpp/helloworld/greeter_client.cc new file mode 100644 index 0000000000..dd0358ac95 --- /dev/null +++ b/examples/cpp/helloworld/greeter_client.cc @@ -0,0 +1,85 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include "helloworld.grpc.pb.h" + +using grpc::Channel; +using grpc::ChannelArguments; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterClient { + public: + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + std::string SayHello(const std::string& user) { + HelloRequest request; + request.set_name(user); + HelloReply reply; + ClientContext context; + + Status status = stub_->SayHello(&context, request, &reply); + if (status.ok()) { + return reply.message(); + } else { + return "Rpc failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + GreeterClient greeter( + grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), + ChannelArguments())); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter received: " << reply << std::endl; + + return 0; +} diff --git a/examples/cpp/helloworld/greeter_server.cc b/examples/cpp/helloworld/greeter_server.cc new file mode 100644 index 0000000000..c1efdf563c --- /dev/null +++ b/examples/cpp/helloworld/greeter_server.cc @@ -0,0 +1,78 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include "helloworld.grpc.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.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + builder.RegisterService(&service); + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} diff --git a/examples/cpp/route_guide/Makefile b/examples/cpp/route_guide/Makefile new file mode 100644 index 0000000000..b906177af3 --- /dev/null +++ b/examples/cpp/route_guide/Makefile @@ -0,0 +1,113 @@ +# +# 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++_unsecure -lgrpc -lgpr -lprotobuf -lpthread -ldl +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` + +PROTOS_PATH = ../../protos + +vpath %.proto $(PROTOS_PATH) + +all: system-check route_guide_client route_guide_server + +route_guide_client: route_guide.pb.o route_guide.grpc.pb.o route_guide_client.o helper.o + $(CXX) $^ $(LDFLAGS) -o $@ + +route_guide_server: route_guide.pb.o route_guide.grpc.pb.o route_guide_server.o helper.o + $(CXX) $^ $(LDFLAGS) -o $@ + +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + +clean: + rm -f *.o *.pb.cc *.pb.h route_guide_client route_guide_server + + +# The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + +PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + +SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif + +system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-alpha-1" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif diff --git a/examples/cpp/route_guide/helper.cc b/examples/cpp/route_guide/helper.cc new file mode 100644 index 0000000000..c2415afdf7 --- /dev/null +++ b/examples/cpp/route_guide/helper.cc @@ -0,0 +1,178 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "route_guide.grpc.pb.h" + +namespace examples { + +std::string GetDbFileContent(int argc, char** argv) { + std::string db_path; + std::string arg_str("--db_path"); + if (argc > 1) { + std::string argv_1 = argv[1]; + size_t start_position = argv_1.find(arg_str); + if (start_position != std::string::npos) { + start_position += arg_str.size(); + if (argv_1[start_position] == ' ' || + argv_1[start_position] == '=') { + db_path = argv_1.substr(start_position + 1); + } + } + } else { + db_path = "route_guide_db.json"; + } + std::ifstream db_file(db_path); + if (!db_file.is_open()) { + std::cout << "Failed to open " << db_path << std::endl; + return ""; + } + std::stringstream db; + db << db_file.rdbuf(); + return db.str(); +} + +// A simple parser for the json db file. It requires the db file to have the +// exact form of [{"location": { "latitude": 123, "longitude": 456}, "name": +// "the name can be empty" }, { ... } ... The spaces will be stripped. +class Parser { + public: + explicit Parser(const std::string& db) : db_(db) { + // Remove all spaces. + db_.erase( + std::remove_if(db_.begin(), db_.end(), isspace), + db_.end()); + if (!Match("[")) { + SetFailedAndReturnFalse(); + } + } + + bool Finished() { + return current_ >= db_.size(); + } + + bool TryParseOne(Feature* feature) { + if (failed_ || Finished() || !Match("{")) { + return SetFailedAndReturnFalse(); + } + if (!Match(location_) || !Match("{") || !Match(latitude_)) { + return SetFailedAndReturnFalse(); + } + long temp = 0; + ReadLong(&temp); + feature->mutable_location()->set_latitude(temp); + if (!Match(",") || !Match(longitude_)) { + return SetFailedAndReturnFalse(); + } + ReadLong(&temp); + feature->mutable_location()->set_longitude(temp); + if (!Match("},") || !Match(name_) || !Match("\"")) { + return SetFailedAndReturnFalse(); + } + size_t name_start = current_; + while (current_ != db_.size() && db_[current_++] != '"') { + } + if (current_ == db_.size()) { + return SetFailedAndReturnFalse(); + } + feature->set_name(db_.substr(name_start, current_-name_start-1)); + if (!Match("},")) { + if (db_[current_ - 1] == ']' && current_ == db_.size()) { + return true; + } + return SetFailedAndReturnFalse(); + } + return true; + } + + private: + + bool SetFailedAndReturnFalse() { + failed_ = true; + return false; + } + + bool Match(const std::string& prefix) { + bool eq = db_.substr(current_, prefix.size()) == prefix; + current_ += prefix.size(); + return eq; + } + + void ReadLong(long* l) { + size_t start = current_; + while (current_ != db_.size() && db_[current_] != ',' && db_[current_] != '}') { + current_++; + } + // It will throw an exception if fails. + *l = std::stol(db_.substr(start, current_ - start)); + } + + bool failed_ = false; + std::string db_; + size_t current_ = 0; + const std::string location_ = "\"location\":"; + const std::string latitude_ = "\"latitude\":"; + const std::string longitude_ = "\"longitude\":"; + const std::string name_ = "\"name\":"; +}; + +void ParseDb(const std::string& db, std::vector* feature_list) { + feature_list->clear(); + std::string db_content(db); + db_content.erase( + std::remove_if(db_content.begin(), db_content.end(), isspace), + db_content.end()); + + Parser parser(db_content); + Feature feature; + while (!parser.Finished()) { + feature_list->push_back(Feature()); + if (!parser.TryParseOne(&feature_list->back())) { + std::cout << "Error parsing the db file"; + feature_list->clear(); + break; + } + } + std::cout << "DB parsed, loaded " << feature_list->size() + << " features." << std::endl; +} + + +} // namespace examples + diff --git a/examples/cpp/route_guide/helper.h b/examples/cpp/route_guide/helper.h new file mode 100644 index 0000000000..65c93c1d34 --- /dev/null +++ b/examples/cpp/route_guide/helper.h @@ -0,0 +1,50 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_ +#define GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_ + +#include +#include + +namespace examples { +class Feature; + +std::string GetDbFileContent(int argc, char** argv); + +void ParseDb(const std::string& db, std::vector* feature_list); + +} // namespace examples + +#endif // GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_ + diff --git a/examples/cpp/route_guide/route_guide_client.cc b/examples/cpp/route_guide/route_guide_client.cc new file mode 100644 index 0000000000..814def27f3 --- /dev/null +++ b/examples/cpp/route_guide/route_guide_client.cc @@ -0,0 +1,252 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "helper.h" +#include "route_guide.grpc.pb.h" + +using grpc::Channel; +using grpc::ChannelArguments; +using grpc::ClientContext; +using grpc::ClientReader; +using grpc::ClientReaderWriter; +using grpc::ClientWriter; +using grpc::Status; +using examples::Point; +using examples::Feature; +using examples::Rectangle; +using examples::RouteSummary; +using examples::RouteNote; +using examples::RouteGuide; + +Point MakePoint(long latitude, long longitude) { + Point p; + p.set_latitude(latitude); + p.set_longitude(longitude); + return p; +} + +Feature MakeFeature(const std::string& name, + long latitude, long longitude) { + Feature f; + f.set_name(name); + f.mutable_location()->CopyFrom(MakePoint(latitude, longitude)); + return f; +} + +RouteNote MakeRouteNote(const std::string& message, + long latitude, long longitude) { + RouteNote n; + n.set_message(message); + n.mutable_location()->CopyFrom(MakePoint(latitude, longitude)); + return n; +} + +class RouteGuideClient { + public: + RouteGuideClient(std::shared_ptr channel, const std::string& db) + : stub_(RouteGuide::NewStub(channel)) { + examples::ParseDb(db, &feature_list_); + } + + void GetFeature() { + Point point; + Feature feature; + point = MakePoint(409146138, -746188906); + GetOneFeature(point, &feature); + point = MakePoint(0, 0); + GetOneFeature(point, &feature); + } + + void ListFeatures() { + examples::Rectangle rect; + Feature feature; + ClientContext context; + + rect.mutable_lo()->set_latitude(400000000); + rect.mutable_lo()->set_longitude(-750000000); + rect.mutable_hi()->set_latitude(420000000); + rect.mutable_hi()->set_longitude(-730000000); + std::cout << "Looking for features between 40, -75 and 42, -73" + << std::endl; + + std::unique_ptr > reader( + stub_->ListFeatures(&context, rect)); + while (reader->Read(&feature)) { + std::cout << "Found feature called " + << feature.name() << " at " + << feature.location().latitude()/kCoordFactor_ << ", " + << feature.location().longitude()/kCoordFactor_ << std::endl; + } + Status status = reader->Finish(); + if (status.ok()) { + std::cout << "ListFeatures rpc succeeded." << std::endl; + } else { + std::cout << "ListFeatures rpc failed." << std::endl; + } + } + + void RecordRoute() { + Point point; + RouteSummary stats; + ClientContext context; + const int kPoints = 10; + unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); + + std::default_random_engine generator(seed); + std::uniform_int_distribution feature_distribution( + 0, feature_list_.size() - 1); + std::uniform_int_distribution delay_distribution( + 500, 1500); + + std::unique_ptr > writer( + stub_->RecordRoute(&context, &stats)); + for (int i = 0; i < kPoints; i++) { + const Feature& f = feature_list_[feature_distribution(generator)]; + std::cout << "Visiting point " + << f.location().latitude()/kCoordFactor_ << ", " + << f.location().longitude()/kCoordFactor_ << std::endl; + if (!writer->Write(f.location())) { + // Broken stream. + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds( + delay_distribution(generator))); + } + writer->WritesDone(); + Status status = writer->Finish(); + if (status.ok()) { + std::cout << "Finished trip with " << stats.point_count() << " points\n" + << "Passed " << stats.feature_count() << " features\n" + << "Travelled " << stats.distance() << " meters\n" + << "It took " << stats.elapsed_time() << " seconds" + << std::endl; + } else { + std::cout << "RecordRoute rpc failed." << std::endl; + } + } + + void RouteChat() { + ClientContext context; + + std::shared_ptr > stream( + stub_->RouteChat(&context)); + + std::thread writer([stream]() { + std::vector notes{ + MakeRouteNote("First message", 0, 0), + MakeRouteNote("Second message", 0, 1), + MakeRouteNote("Third message", 1, 0), + MakeRouteNote("Fourth message", 0, 0)}; + for (const RouteNote& note : notes) { + std::cout << "Sending message " << note.message() + << " at " << note.location().latitude() << ", " + << note.location().longitude() << std::endl; + stream->Write(note); + } + stream->WritesDone(); + }); + + RouteNote server_note; + while (stream->Read(&server_note)) { + std::cout << "Got message " << server_note.message() + << " at " << server_note.location().latitude() << ", " + << server_note.location().longitude() << std::endl; + } + writer.join(); + Status status = stream->Finish(); + if (!status.ok()) { + std::cout << "RouteChat rpc failed." << std::endl; + } + } + + private: + + bool GetOneFeature(const Point& point, Feature* feature) { + ClientContext context; + Status status = stub_->GetFeature(&context, point, feature); + if (!status.ok()) { + std::cout << "GetFeature rpc failed." << std::endl; + return false; + } + if (!feature->has_location()) { + std::cout << "Server returns incomplete feature." << std::endl; + return false; + } + if (feature->name().empty()) { + std::cout << "Found no feature at " + << feature->location().latitude()/kCoordFactor_ << ", " + << feature->location().longitude()/kCoordFactor_ << std::endl; + } else { + std::cout << "Found feature called " << feature->name() << " at " + << feature->location().latitude()/kCoordFactor_ << ", " + << feature->location().longitude()/kCoordFactor_ << std::endl; + } + return true; + } + + const float kCoordFactor_ = 10000000.0; + std::unique_ptr stub_; + std::vector feature_list_; +}; + +int main(int argc, char** argv) { + // Expect only arg: --db_path=path/to/route_guide_db.json. + std::string db = examples::GetDbFileContent(argc, argv); + RouteGuideClient guide( + grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), + ChannelArguments()), + db); + + std::cout << "-------------- GetFeature --------------" << std::endl; + guide.GetFeature(); + std::cout << "-------------- ListFeatures --------------" << std::endl; + guide.ListFeatures(); + std::cout << "-------------- RecordRoute --------------" << std::endl; + guide.RecordRoute(); + std::cout << "-------------- RouteChat --------------" << std::endl; + guide.RouteChat(); + + return 0; +} diff --git a/examples/cpp/route_guide/route_guide_db.json b/examples/cpp/route_guide/route_guide_db.json new file mode 100644 index 0000000000..9d6a980ab7 --- /dev/null +++ b/examples/cpp/route_guide/route_guide_db.json @@ -0,0 +1,601 @@ +[{ + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" +}, { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" +}, { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" +}, { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" +}, { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" +}, { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" +}, { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" +}, { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" +}, { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" +}, { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" +}, { + "location": { + "latitude": 415736605, + "longitude": -742847522 + }, + "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" +}, { + "location": { + "latitude": 413843930, + "longitude": -740501726 + }, + "name": "162 Merrill Road, Highland Mills, NY 10930, USA" +}, { + "location": { + "latitude": 410873075, + "longitude": -744459023 + }, + "name": "Clinton Road, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 412346009, + "longitude": -744026814 + }, + "name": "16 Old Brook Lane, Warwick, NY 10990, USA" +}, { + "location": { + "latitude": 402948455, + "longitude": -747903913 + }, + "name": "3 Drake Lane, Pennington, NJ 08534, USA" +}, { + "location": { + "latitude": 406337092, + "longitude": -740122226 + }, + "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" +}, { + "location": { + "latitude": 406421967, + "longitude": -747727624 + }, + "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" +}, { + "location": { + "latitude": 416318082, + "longitude": -749677716 + }, + "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" +}, { + "location": { + "latitude": 415301720, + "longitude": -748416257 + }, + "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" +}, { + "location": { + "latitude": 402647019, + "longitude": -747071791 + }, + "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" +}, { + "location": { + "latitude": 412567807, + "longitude": -741058078 + }, + "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" +}, { + "location": { + "latitude": 416855156, + "longitude": -744420597 + }, + "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" +}, { + "location": { + "latitude": 404663628, + "longitude": -744820157 + }, + "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" +}, { + "location": { + "latitude": 407113723, + "longitude": -749746483 + }, + "name": "" +}, { + "location": { + "latitude": 402133926, + "longitude": -743613249 + }, + "name": "" +}, { + "location": { + "latitude": 400273442, + "longitude": -741220915 + }, + "name": "" +}, { + "location": { + "latitude": 411236786, + "longitude": -744070769 + }, + "name": "" +}, { + "location": { + "latitude": 411633782, + "longitude": -746784970 + }, + "name": "211-225 Plains Road, Augusta, NJ 07822, USA" +}, { + "location": { + "latitude": 415830701, + "longitude": -742952812 + }, + "name": "" +}, { + "location": { + "latitude": 413447164, + "longitude": -748712898 + }, + "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" +}, { + "location": { + "latitude": 405047245, + "longitude": -749800722 + }, + "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" +}, { + "location": { + "latitude": 418858923, + "longitude": -746156790 + }, + "name": "" +}, { + "location": { + "latitude": 417951888, + "longitude": -748484944 + }, + "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" +}, { + "location": { + "latitude": 407033786, + "longitude": -743977337 + }, + "name": "26 East 3rd Street, New Providence, NJ 07974, USA" +}, { + "location": { + "latitude": 417548014, + "longitude": -740075041 + }, + "name": "" +}, { + "location": { + "latitude": 410395868, + "longitude": -744972325 + }, + "name": "" +}, { + "location": { + "latitude": 404615353, + "longitude": -745129803 + }, + "name": "" +}, { + "location": { + "latitude": 406589790, + "longitude": -743560121 + }, + "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" +}, { + "location": { + "latitude": 414653148, + "longitude": -740477477 + }, + "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" +}, { + "location": { + "latitude": 405957808, + "longitude": -743255336 + }, + "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" +}, { + "location": { + "latitude": 411733589, + "longitude": -741648093 + }, + "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" +}, { + "location": { + "latitude": 412676291, + "longitude": -742606606 + }, + "name": "1270 Lakes Road, Monroe, NY 10950, USA" +}, { + "location": { + "latitude": 409224445, + "longitude": -748286738 + }, + "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" +}, { + "location": { + "latitude": 406523420, + "longitude": -742135517 + }, + "name": "652 Garden Street, Elizabeth, NJ 07202, USA" +}, { + "location": { + "latitude": 401827388, + "longitude": -740294537 + }, + "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" +}, { + "location": { + "latitude": 410564152, + "longitude": -743685054 + }, + "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 408472324, + "longitude": -740726046 + }, + "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" +}, { + "location": { + "latitude": 412452168, + "longitude": -740214052 + }, + "name": "5 White Oak Lane, Stony Point, NY 10980, USA" +}, { + "location": { + "latitude": 409146138, + "longitude": -746188906 + }, + "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" +}, { + "location": { + "latitude": 404701380, + "longitude": -744781745 + }, + "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 409642566, + "longitude": -746017679 + }, + "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" +}, { + "location": { + "latitude": 408031728, + "longitude": -748645385 + }, + "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" +}, { + "location": { + "latitude": 413700272, + "longitude": -742135189 + }, + "name": "367 Prospect Road, Chester, NY 10918, USA" +}, { + "location": { + "latitude": 404310607, + "longitude": -740282632 + }, + "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" +}, { + "location": { + "latitude": 409319800, + "longitude": -746201391 + }, + "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" +}, { + "location": { + "latitude": 406685311, + "longitude": -742108603 + }, + "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" +}, { + "location": { + "latitude": 419018117, + "longitude": -749142781 + }, + "name": "43 Dreher Road, Roscoe, NY 12776, USA" +}, { + "location": { + "latitude": 412856162, + "longitude": -745148837 + }, + "name": "Swan Street, Pine Island, NY 10969, USA" +}, { + "location": { + "latitude": 416560744, + "longitude": -746721964 + }, + "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" +}, { + "location": { + "latitude": 405314270, + "longitude": -749836354 + }, + "name": "" +}, { + "location": { + "latitude": 414219548, + "longitude": -743327440 + }, + "name": "" +}, { + "location": { + "latitude": 415534177, + "longitude": -742900616 + }, + "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" +}, { + "location": { + "latitude": 406898530, + "longitude": -749127080 + }, + "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" +}, { + "location": { + "latitude": 407586880, + "longitude": -741670168 + }, + "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" +}, { + "location": { + "latitude": 400106455, + "longitude": -742870190 + }, + "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" +}, { + "location": { + "latitude": 400066188, + "longitude": -746793294 + }, + "name": "" +}, { + "location": { + "latitude": 418803880, + "longitude": -744102673 + }, + "name": "40 Mountain Road, Napanoch, NY 12458, USA" +}, { + "location": { + "latitude": 414204288, + "longitude": -747895140 + }, + "name": "" +}, { + "location": { + "latitude": 414777405, + "longitude": -740615601 + }, + "name": "" +}, { + "location": { + "latitude": 415464475, + "longitude": -747175374 + }, + "name": "48 North Road, Forestburgh, NY 12777, USA" +}, { + "location": { + "latitude": 404062378, + "longitude": -746376177 + }, + "name": "" +}, { + "location": { + "latitude": 405688272, + "longitude": -749285130 + }, + "name": "" +}, { + "location": { + "latitude": 400342070, + "longitude": -748788996 + }, + "name": "" +}, { + "location": { + "latitude": 401809022, + "longitude": -744157964 + }, + "name": "" +}, { + "location": { + "latitude": 404226644, + "longitude": -740517141 + }, + "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" +}, { + "location": { + "latitude": 410322033, + "longitude": -747871659 + }, + "name": "" +}, { + "location": { + "latitude": 407100674, + "longitude": -747742727 + }, + "name": "" +}, { + "location": { + "latitude": 418811433, + "longitude": -741718005 + }, + "name": "213 Bush Road, Stone Ridge, NY 12484, USA" +}, { + "location": { + "latitude": 415034302, + "longitude": -743850945 + }, + "name": "" +}, { + "location": { + "latitude": 411349992, + "longitude": -743694161 + }, + "name": "" +}, { + "location": { + "latitude": 404839914, + "longitude": -744759616 + }, + "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 414638017, + "longitude": -745957854 + }, + "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" +}, { + "location": { + "latitude": 412127800, + "longitude": -740173578 + }, + "name": "" +}, { + "location": { + "latitude": 401263460, + "longitude": -747964303 + }, + "name": "" +}, { + "location": { + "latitude": 412843391, + "longitude": -749086026 + }, + "name": "" +}, { + "location": { + "latitude": 418512773, + "longitude": -743067823 + }, + "name": "" +}, { + "location": { + "latitude": 404318328, + "longitude": -740835638 + }, + "name": "42-102 Main Street, Belford, NJ 07718, USA" +}, { + "location": { + "latitude": 419020746, + "longitude": -741172328 + }, + "name": "" +}, { + "location": { + "latitude": 404080723, + "longitude": -746119569 + }, + "name": "" +}, { + "location": { + "latitude": 401012643, + "longitude": -744035134 + }, + "name": "" +}, { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" +}, { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" +}, { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" +}, { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" +}, { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" +}, { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" +}, { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" +}, { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" +}, { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" +}, { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" +}] diff --git a/examples/cpp/route_guide/route_guide_server.cc b/examples/cpp/route_guide/route_guide_server.cc new file mode 100644 index 0000000000..b37539299a --- /dev/null +++ b/examples/cpp/route_guide/route_guide_server.cc @@ -0,0 +1,202 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "helper.h" +#include "route_guide.grpc.pb.h" + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::ServerReader; +using grpc::ServerReaderWriter; +using grpc::ServerWriter; +using grpc::Status; +using examples::Point; +using examples::Feature; +using examples::Rectangle; +using examples::RouteSummary; +using examples::RouteNote; +using examples::RouteGuide; +using std::chrono::system_clock; + + +float ConvertToRadians(float num) { + return num * 3.1415926 /180; +} + +float GetDistance(const Point& start, const Point& end) { + const float kCoordFactor = 10000000.0; + float lat_1 = start.latitude() / kCoordFactor; + float lat_2 = end.latitude() / kCoordFactor; + float lon_1 = start.longitude() / kCoordFactor; + float lon_2 = end.longitude() / kCoordFactor; + float lat_rad_1 = ConvertToRadians(lat_1); + float lat_rad_2 = ConvertToRadians(lat_2); + float delta_lat_rad = ConvertToRadians(lat_2-lat_1); + float delta_lon_rad = ConvertToRadians(lon_2-lon_1); + + float a = pow(sin(delta_lat_rad/2), 2) + cos(lat_rad_1) * cos(lat_rad_2) * + pow(sin(delta_lon_rad/2), 2); + float c = 2 * atan2(sqrt(a), sqrt(1-a)); + int R = 6371000; // metres + + return R * c; +} + +std::string GetFeatureName(const Point& point, + const std::vector& feature_list) { + for (const Feature& f : feature_list) { + if (f.location().latitude() == point.latitude() && + f.location().longitude() == point.longitude()) { + return f.name(); + } + } + return ""; +} + +class RouteGuideImpl final : public RouteGuide::Service { + public: + explicit RouteGuideImpl(const std::string& db) { + examples::ParseDb(db, &feature_list_); + } + + Status GetFeature(ServerContext* context, const Point* point, + Feature* feature) override { + feature->set_name(GetFeatureName(*point, feature_list_)); + feature->mutable_location()->CopyFrom(*point); + return Status::OK; + } + + Status ListFeatures(ServerContext* context, + const examples::Rectangle* rectangle, + ServerWriter* writer) override { + auto lo = rectangle->lo(); + auto hi = rectangle->hi(); + long left = (std::min)(lo.longitude(), hi.longitude()); + long right = (std::max)(lo.longitude(), hi.longitude()); + long top = (std::max)(lo.latitude(), hi.latitude()); + long bottom = (std::min)(lo.latitude(), hi.latitude()); + for (const Feature& f : feature_list_) { + if (f.location().longitude() >= left && + f.location().longitude() <= right && + f.location().latitude() >= bottom && + f.location().latitude() <= top) { + writer->Write(f); + } + } + return Status::OK; + } + + Status RecordRoute(ServerContext* context, ServerReader* reader, + RouteSummary* summary) override { + Point point; + int point_count = 0; + int feature_count = 0; + float distance = 0.0; + Point previous; + + system_clock::time_point start_time = system_clock::now(); + while (reader->Read(&point)) { + point_count++; + if (!GetFeatureName(point, feature_list_).empty()) { + feature_count++; + } + if (point_count != 1) { + distance += GetDistance(previous, point); + } + previous = point; + } + system_clock::time_point end_time = system_clock::now(); + summary->set_point_count(point_count); + summary->set_feature_count(feature_count); + summary->set_distance(static_cast(distance)); + auto secs = std::chrono::duration_cast( + end_time - start_time); + summary->set_elapsed_time(secs.count()); + + return Status::OK; + } + + Status RouteChat(ServerContext* context, + ServerReaderWriter* stream) override { + std::vector received_notes; + RouteNote note; + while (stream->Read(¬e)) { + for (const RouteNote& n : received_notes) { + if (n.location().latitude() == note.location().latitude() && + n.location().longitude() == note.location().longitude()) { + stream->Write(n); + } + } + received_notes.push_back(note); + } + + return Status::OK; + } + + private: + + std::vector feature_list_; +}; + +void RunServer(const std::string& db_path) { + std::string server_address("0.0.0.0:50051"); + RouteGuideImpl service(db_path); + + ServerBuilder builder; + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + builder.RegisterService(&service); + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + server->Wait(); +} + +int main(int argc, char** argv) { + // Expect only arg: --db_path=path/to/route_guide_db.json. + std::string db = examples::GetDbFileContent(argc, argv); + RunServer(db); + + return 0; +} diff --git a/examples/csharp/.gitignore b/examples/csharp/.gitignore new file mode 100644 index 0000000000..585000ea2d --- /dev/null +++ b/examples/csharp/.gitignore @@ -0,0 +1,5 @@ +bin/ +obj/ +packages/ +*.suo +*.userprefs diff --git a/examples/csharp/.nuget/packages.config b/examples/csharp/.nuget/packages.config new file mode 100644 index 0000000000..b14373069f --- /dev/null +++ b/examples/csharp/.nuget/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/examples/csharp/Greeter.sln b/examples/csharp/Greeter.sln new file mode 100644 index 0000000000..9430e94de9 --- /dev/null +++ b/examples/csharp/Greeter.sln @@ -0,0 +1,42 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Greeter", "Greeter\Greeter.csproj", "{724DFC8C-4B57-4C3F-811C-0463BE2A2829}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterServer", "GreeterServer\GreeterServer.csproj", "{A7706C84-92D2-4B7A-B779-76B64D2950EC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterClient", "GreeterClient\GreeterClient.csproj", "{ACCF4597-3748-4117-8633-1CB767F8CCC3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{FF1EBE95-F20D-4C27-8A61-D0125F3C8152}" + ProjectSection(SolutionItems) = preProject + .nuget\packages.config = .nuget\packages.config + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Debug|Any CPU.Build.0 = Debug|Any CPU + {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Release|Any CPU.ActiveCfg = Release|Any CPU + {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Release|Any CPU.Build.0 = Release|Any CPU + {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Release|Any CPU.Build.0 = Release|Any CPU + {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = Greeter\Greeter.csproj + EndGlobalSection +EndGlobal diff --git a/examples/csharp/Greeter/.gitignore b/examples/csharp/Greeter/.gitignore new file mode 100644 index 0000000000..1746e3269e --- /dev/null +++ b/examples/csharp/Greeter/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/examples/csharp/Greeter/Greeter.csproj b/examples/csharp/Greeter/Greeter.csproj new file mode 100644 index 0000000000..b8f965dbd2 --- /dev/null +++ b/examples/csharp/Greeter/Greeter.csproj @@ -0,0 +1,81 @@ + + + + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {724DFC8C-4B57-4C3F-811C-0463BE2A2829} + Library + Greeter + Greeter + v4.5 + 927432a0 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + full + true + bin\Release + prompt + 4 + false + + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll + + + False + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll + + + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/Greeter/Helloworld.cs b/examples/csharp/Greeter/Helloworld.cs new file mode 100644 index 0000000000..923a4271e9 --- /dev/null +++ b/examples/csharp/Greeter/Helloworld.cs @@ -0,0 +1,617 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.ProtocolBuffers; +using pbc = global::Google.ProtocolBuffers.Collections; +using pbd = global::Google.ProtocolBuffers.Descriptors; +using scg = global::System.Collections.Generic; +namespace helloworld { + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public static partial class Helloworld { + + #region Extension registration + public static void RegisterAllExtensions(pb::ExtensionRegistry registry) { + } + #endregion + #region Static variables + internal static pbd::MessageDescriptor internal__static_helloworld_HelloRequest__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_helloworld_HelloRequest__FieldAccessorTable; + internal static pbd::MessageDescriptor internal__static_helloworld_HelloReply__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_helloworld_HelloReply__FieldAccessorTable; + #endregion + #region Descriptor + public static pbd::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbd::FileDescriptor descriptor; + + static Helloworld() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz", + "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo", + "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl", + "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEISChBpby5ncnBjLmV4", + "YW1wbGVz")); + pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) { + descriptor = root; + internal__static_helloworld_HelloRequest__Descriptor = Descriptor.MessageTypes[0]; + internal__static_helloworld_HelloRequest__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_helloworld_HelloRequest__Descriptor, + new string[] { "Name", }); + internal__static_helloworld_HelloReply__Descriptor = Descriptor.MessageTypes[1]; + internal__static_helloworld_HelloReply__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_helloworld_HelloReply__Descriptor, + new string[] { "Message", }); + pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance(); + RegisterAllExtensions(registry); + return registry; + }; + pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData, + new pbd::FileDescriptor[] { + }, assigner); + } + #endregion + + } + #region Messages + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class HelloRequest : pb::GeneratedMessage { + private HelloRequest() { } + private static readonly HelloRequest defaultInstance = new HelloRequest().MakeReadOnly(); + private static readonly string[] _helloRequestFieldNames = new string[] { "name" }; + private static readonly uint[] _helloRequestFieldTags = new uint[] { 10 }; + public static HelloRequest DefaultInstance { + get { return defaultInstance; } + } + + public override HelloRequest DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override HelloRequest ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::helloworld.Helloworld.internal__static_helloworld_HelloRequest__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::helloworld.Helloworld.internal__static_helloworld_HelloRequest__FieldAccessorTable; } + } + + public const int NameFieldNumber = 1; + private bool hasName; + private string name_ = ""; + public bool HasName { + get { return hasName; } + } + public string Name { + get { return name_; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _helloRequestFieldNames; + if (hasName) { + output.WriteString(1, field_names[0], Name); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasName) { + size += pb::CodedOutputStream.ComputeStringSize(1, Name); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static HelloRequest ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static HelloRequest ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static HelloRequest ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static HelloRequest ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static HelloRequest ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static HelloRequest ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static HelloRequest ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static HelloRequest ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static HelloRequest ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static HelloRequest ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private HelloRequest MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(HelloRequest prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(HelloRequest cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private HelloRequest result; + + private HelloRequest PrepareBuilder() { + if (resultIsReadOnly) { + HelloRequest original = result; + result = new HelloRequest(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override HelloRequest MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::helloworld.HelloRequest.Descriptor; } + } + + public override HelloRequest DefaultInstanceForType { + get { return global::helloworld.HelloRequest.DefaultInstance; } + } + + public override HelloRequest BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is HelloRequest) { + return MergeFrom((HelloRequest) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(HelloRequest other) { + if (other == global::helloworld.HelloRequest.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasName) { + Name = other.Name; + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_helloRequestFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _helloRequestFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 10: { + result.hasName = input.ReadString(ref result.name_); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasName { + get { return result.hasName; } + } + public string Name { + get { return result.Name; } + set { SetName(value); } + } + public Builder SetName(string value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasName = true; + result.name_ = value; + return this; + } + public Builder ClearName() { + PrepareBuilder(); + result.hasName = false; + result.name_ = ""; + return this; + } + } + static HelloRequest() { + object.ReferenceEquals(global::helloworld.Helloworld.Descriptor, null); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class HelloReply : pb::GeneratedMessage { + private HelloReply() { } + private static readonly HelloReply defaultInstance = new HelloReply().MakeReadOnly(); + private static readonly string[] _helloReplyFieldNames = new string[] { "message" }; + private static readonly uint[] _helloReplyFieldTags = new uint[] { 10 }; + public static HelloReply DefaultInstance { + get { return defaultInstance; } + } + + public override HelloReply DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override HelloReply ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::helloworld.Helloworld.internal__static_helloworld_HelloReply__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::helloworld.Helloworld.internal__static_helloworld_HelloReply__FieldAccessorTable; } + } + + public const int MessageFieldNumber = 1; + private bool hasMessage; + private string message_ = ""; + public bool HasMessage { + get { return hasMessage; } + } + public string Message { + get { return message_; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _helloReplyFieldNames; + if (hasMessage) { + output.WriteString(1, field_names[0], Message); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasMessage) { + size += pb::CodedOutputStream.ComputeStringSize(1, Message); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static HelloReply ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static HelloReply ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static HelloReply ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static HelloReply ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static HelloReply ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static HelloReply ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static HelloReply ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static HelloReply ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static HelloReply ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static HelloReply ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private HelloReply MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(HelloReply prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(HelloReply cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private HelloReply result; + + private HelloReply PrepareBuilder() { + if (resultIsReadOnly) { + HelloReply original = result; + result = new HelloReply(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override HelloReply MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::helloworld.HelloReply.Descriptor; } + } + + public override HelloReply DefaultInstanceForType { + get { return global::helloworld.HelloReply.DefaultInstance; } + } + + public override HelloReply BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is HelloReply) { + return MergeFrom((HelloReply) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(HelloReply other) { + if (other == global::helloworld.HelloReply.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasMessage) { + Message = other.Message; + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_helloReplyFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _helloReplyFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 10: { + result.hasMessage = input.ReadString(ref result.message_); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasMessage { + get { return result.hasMessage; } + } + public string Message { + get { return result.Message; } + set { SetMessage(value); } + } + public Builder SetMessage(string value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasMessage = true; + result.message_ = value; + return this; + } + public Builder ClearMessage() { + PrepareBuilder(); + result.hasMessage = false; + result.message_ = ""; + return this; + } + } + static HelloReply() { + object.ReferenceEquals(global::helloworld.Helloworld.Descriptor, null); + } + } + + #endregion + +} + +#endregion Designer generated code diff --git a/examples/csharp/Greeter/HelloworldGrpc.cs b/examples/csharp/Greeter/HelloworldGrpc.cs new file mode 100644 index 0000000000..1ca9d2899b --- /dev/null +++ b/examples/csharp/Greeter/HelloworldGrpc.cs @@ -0,0 +1,78 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto +#region Designer generated code + +using System; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; + +namespace helloworld { + public static class Greeter + { + static readonly string __ServiceName = "helloworld.Greeter"; + + static readonly Marshaller __Marshaller_HelloRequest = Marshallers.Create((arg) => arg.ToByteArray(), global::helloworld.HelloRequest.ParseFrom); + static readonly Marshaller __Marshaller_HelloReply = Marshallers.Create((arg) => arg.ToByteArray(), global::helloworld.HelloReply.ParseFrom); + + static readonly Method __Method_SayHello = new Method( + MethodType.Unary, + "SayHello", + __Marshaller_HelloRequest, + __Marshaller_HelloReply); + + // client-side stub interface + public interface IGreeterClient + { + global::helloworld.HelloReply SayHello(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)); + Task SayHelloAsync(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)); + } + + // server-side interface + public interface IGreeter + { + Task SayHello(ServerCallContext context, global::helloworld.HelloRequest request); + } + + // client stub + public class GreeterClient : AbstractStub, IGreeterClient + { + public GreeterClient(Channel channel) : this(channel, StubConfiguration.Default) + { + } + public GreeterClient(Channel channel, StubConfiguration config) : base(channel, config) + { + } + public global::helloworld.HelloReply SayHello(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_SayHello); + return Calls.BlockingUnaryCall(call, request, token); + } + public Task SayHelloAsync(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_SayHello); + return Calls.AsyncUnaryCall(call, request, token); + } + } + + // creates service definition that can be registered with a server + public static ServerServiceDefinition BindService(IGreeter serviceImpl) + { + return ServerServiceDefinition.CreateBuilder(__ServiceName) + .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build(); + } + + // creates a new client stub + public static IGreeterClient NewStub(Channel channel) + { + return new GreeterClient(channel); + } + + // creates a new client stub + public static IGreeterClient NewStub(Channel channel, StubConfiguration config) + { + return new GreeterClient(channel, config); + } + } +} +#endregion diff --git a/examples/csharp/Greeter/Properties/AssemblyInfo.cs b/examples/csharp/Greeter/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..b9d0dc264d --- /dev/null +++ b/examples/csharp/Greeter/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle("Greeter")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("jtattermusch")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/examples/csharp/Greeter/packages.config b/examples/csharp/Greeter/packages.config new file mode 100644 index 0000000000..5922553bc3 --- /dev/null +++ b/examples/csharp/Greeter/packages.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/Greeter/protos/helloworld.proto b/examples/csharp/Greeter/protos/helloworld.proto new file mode 100644 index 0000000000..e02ebd94e7 --- /dev/null +++ b/examples/csharp/Greeter/protos/helloworld.proto @@ -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. + +// TODO(jtattermusch): as of now, C# protobufs don't officially support +// proto3. +syntax = "proto2"; + +option java_package = "io.grpc.examples"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + optional string name = 1; +} + +// The response message containing the greetings +message HelloReply { + optional string message = 1; +} diff --git a/examples/csharp/GreeterClient/.gitignore b/examples/csharp/GreeterClient/.gitignore new file mode 100644 index 0000000000..1746e3269e --- /dev/null +++ b/examples/csharp/GreeterClient/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/examples/csharp/GreeterClient/GreeterClient.csproj b/examples/csharp/GreeterClient/GreeterClient.csproj new file mode 100644 index 0000000000..59b768af01 --- /dev/null +++ b/examples/csharp/GreeterClient/GreeterClient.csproj @@ -0,0 +1,84 @@ + + + + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {ACCF4597-3748-4117-8633-1CB767F8CCC3} + Exe + GreeterClient + GreeterClient + v4.5 + 985ca8be + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + true + + + full + true + bin\Release + prompt + 4 + true + + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll + + + False + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll + + + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll + + + + + + + + + + {724DFC8C-4B57-4C3F-811C-0463BE2A2829} + Greeter + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/GreeterClient/Program.cs b/examples/csharp/GreeterClient/Program.cs new file mode 100644 index 0000000000..61c29762b1 --- /dev/null +++ b/examples/csharp/GreeterClient/Program.cs @@ -0,0 +1,25 @@ +using System; +using Grpc.Core; +using helloworld; + +namespace GreeterClient +{ + class ClientMainClass + { + public static void Main(string[] args) + { + GrpcEnvironment.Initialize(); + + using (Channel channel = new Channel("127.0.0.1:50051")) + { + var client = Greeter.NewStub(channel); + String user = "you"; + + var reply = client.SayHello(new HelloRequest.Builder { Name = user }.Build()); + Console.WriteLine("Greeting: " + reply.Message); + } + + GrpcEnvironment.Shutdown(); + } + } +} diff --git a/examples/csharp/GreeterClient/Properties/AssemblyInfo.cs b/examples/csharp/GreeterClient/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..1422e952d8 --- /dev/null +++ b/examples/csharp/GreeterClient/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle("GreeterClient")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("jtattermusch")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/examples/csharp/GreeterClient/packages.config b/examples/csharp/GreeterClient/packages.config new file mode 100644 index 0000000000..5922553bc3 --- /dev/null +++ b/examples/csharp/GreeterClient/packages.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/GreeterServer/.gitignore b/examples/csharp/GreeterServer/.gitignore new file mode 100644 index 0000000000..1746e3269e --- /dev/null +++ b/examples/csharp/GreeterServer/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/examples/csharp/GreeterServer/GreeterServer.csproj b/examples/csharp/GreeterServer/GreeterServer.csproj new file mode 100644 index 0000000000..cd50d6cd52 --- /dev/null +++ b/examples/csharp/GreeterServer/GreeterServer.csproj @@ -0,0 +1,84 @@ + + + + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {A7706C84-92D2-4B7A-B779-76B64D2950EC} + Exe + GreeterServer + GreeterServer + v4.5 + a1eeb1d8 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + true + + + full + true + bin\Release + prompt + 4 + true + + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll + + + False + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll + + + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll + + + + + + + + + + {724DFC8C-4B57-4C3F-811C-0463BE2A2829} + Greeter + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/GreeterServer/Program.cs b/examples/csharp/GreeterServer/Program.cs new file mode 100644 index 0000000000..9482797c3b --- /dev/null +++ b/examples/csharp/GreeterServer/Program.cs @@ -0,0 +1,37 @@ +using System; +using System.Threading.Tasks; +using Grpc.Core; +using helloworld; + +namespace GreeterServer +{ + class GreeterImpl : Greeter.IGreeter + { + // Server side handler of the SayHello RPC + public Task SayHello(ServerCallContext context, HelloRequest request) + { + var reply = new HelloReply.Builder { Message = "Hello " + request.Name }.Build(); + return Task.FromResult(reply); + } + } + + class ServerMainClass + { + public static void Main(string[] args) + { + GrpcEnvironment.Initialize(); + + Server server = new Server(); + server.AddServiceDefinition(Greeter.BindService(new GreeterImpl())); + int port = server.AddListeningPort("localhost", 50051); + server.Start(); + + Console.WriteLine("Greeter server listening on port " + port); + Console.WriteLine("Press any key to stop the server..."); + Console.ReadKey(); + + server.ShutdownAsync().Wait(); + GrpcEnvironment.Shutdown(); + } + } +} diff --git a/examples/csharp/GreeterServer/Properties/AssemblyInfo.cs b/examples/csharp/GreeterServer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..f8a8d521d8 --- /dev/null +++ b/examples/csharp/GreeterServer/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle("GreeterServer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("jtattermusch")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/examples/csharp/GreeterServer/packages.config b/examples/csharp/GreeterServer/packages.config new file mode 100644 index 0000000000..5922553bc3 --- /dev/null +++ b/examples/csharp/GreeterServer/packages.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/README.md b/examples/csharp/README.md new file mode 100644 index 0000000000..77d1aaf2e6 --- /dev/null +++ b/examples/csharp/README.md @@ -0,0 +1,72 @@ +gRPC in 3 minutes (C#) +======================== + +BACKGROUND +------------- +For this sample, we've already generated the server and client stubs from `helloworld.proto`. +Example projects depend on NuGet packages `Grpc` and `Google.ProtocolBuffers` which have been already added to the project for you. + +PREREQUISITES +------------- +**Windows** +- .NET 4.5+ +- VS 2013 (with NuGet plugin installed) + +**Linux (Mono)** +- Mono +- Monodevelop 5.9 with NuGet Add-in installed (older versions might work) + +**MacOS (Mono)** +- Xamarin Studio (with NuGet plugin installed) + +BUILD +------- + +**Windows** +- Clone this repository. + +- Open solution `Greeter.sln` with Visual Studio + +- Build the solution (this will automatically download NuGet dependencies) + +**Linux (Mono)** +- Clone this repository. + +- Install gRPC C Core using instructions in https://github.com/grpc/homebrew-grpc + +- gRPC C# depends on native shared library `libgrpc_csharp_ext.so`. To make it visible + to Mono runtime, follow instructions in [Using gRPC C# on Linux](https://github.com/grpc/grpc/tree/master/src/csharp#usage-linux-mono) + +- Open solution `Greeter.sln` in MonoDevelop (you need to manually restore dependencies by using `mono nuget.exe restore` if you don't have NuGet add-in) + +- Build the solution. + +**MacOS (Mono)** +- See [Using gRPC C# on MacOS](https://github.com/grpc/grpc/tree/master/src/csharp#usage-macos-mono) for more info + on MacOS support. + +Try it! +------- + +- Run the server + + ``` + > cd GreeterServer/bin/Debug + > GreeterServer.exe + ``` + +- Run the client + + ``` + > cd GreeterClient/bin/Debug + > GreeterClient.exe + ``` + +You can also run the server and client directly from Visual Studio. + +On Linux or Mac, use `mono GreeterServer.exe` and `mono GreeterClient.exe` to run the server and client. + +Tutorial +-------- + +You can find a more detailed tutorial in [gRPC Basics: C#](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/README.md) diff --git a/examples/csharp/route_guide/.gitignore b/examples/csharp/route_guide/.gitignore new file mode 100644 index 0000000000..585000ea2d --- /dev/null +++ b/examples/csharp/route_guide/.gitignore @@ -0,0 +1,5 @@ +bin/ +obj/ +packages/ +*.suo +*.userprefs diff --git a/examples/csharp/route_guide/.nuget/packages.config b/examples/csharp/route_guide/.nuget/packages.config new file mode 100644 index 0000000000..b14373069f --- /dev/null +++ b/examples/csharp/route_guide/.nuget/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/examples/csharp/route_guide/README.md b/examples/csharp/route_guide/README.md new file mode 100644 index 0000000000..35c6024bcf --- /dev/null +++ b/examples/csharp/route_guide/README.md @@ -0,0 +1,409 @@ +#gRPC Basics: C# # + +This tutorial provides a basic C# programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate server and client code using the protocol buffer compiler. +- Use the C# gRPC API to write a simple client and server for your service. + +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial only uses the proto2 version of the protocol buffers language, as proto3 support for C# is not ready yet (see [protobuf C# README](https://github.com/google/protobuf/tree/master/csharp#proto2--proto3)). + +This isn't a comprehensive guide to using gRPC in C#: more reference documentation is coming soon. + +## Why use gRPC? + +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/csharp/route_guide](https://github.com/grpc/grpc-common/tree/master/csharp/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/google/grpc-common.git +``` + +All the files for this tutorial are in the directory `grpc-common/csharp/route_guide`. +Open the solution `grpc-common/csharp/route_guide/RouteGuide.sln` from Visual Studio (or Monodevelop on Linux). + +On Windows, you should not need to do anything besides opening the solution. All the needed dependencies will be restored +for you automatically by the `Grpc` NuGet package upon building the solution. + +On Linux (or MacOS), you will first need to install protobuf and gRPC C Core using Linuxbrew (or Homebrew) tool in order to be +able to generate the server and client interface code and run the examples. Follow the instructions for [Linux](https://github.com/grpc/grpc/tree/master/src/csharp#usage-linux-mono) or [MacOS](https://github.com/grpc/grpc/tree/master/src/csharp#usage-macos-mono). + +## Defining the service + +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/csharp/route_guide/RouteGuide/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/sharp/route_guide/RouteGuide/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +```protobuf +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +```protobuf + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. +```protobuf + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} +``` + +- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. +```protobuf + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +```protobuf + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +```protobuf +// 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; +} +``` + + +## Generating client and server code + +Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C# plugin. + +If you want to run this yourself, make sure you've installed protoc and gRPC C# plugin. The instructions vary based on your OS: +- For Windows, the `Grpc.Tools` NuGet package contains the binaries you will need to generate the code. +- For Linux, make sure you've [installed gRPC C Core using Linuxbrew](https://github.com/grpc/grpc/tree/master/src/csharp#usage-linux-mono) +- For MacOS, make sure you've [installed gRPC C Core using Homebrew](https://github.com/grpc/grpc/tree/master/src/csharp#usage-macos-mono) + +Once that's done, the following command can be used to generate the C# code. + +To generate the code on Windows, we use `protoc.exe` and `grpc_csharp_plugin.exe` binaries that are shipped with the `Grpc.Tools` NuGet package under the `tools` directory. +Normally you would need to add the `Grpc.Tools` package to the solution yourself, but in this tutorial it has been already done for you. Following command should be run from the `csharp/route_guide` directory: +``` +> packages\Grpc.Tools.0.5.1\tools\protoc -I RouteGuide/protos --csharp_out=RouteGuide --grpc_out=RouteGuide --plugin=protoc-gen-grpc=packages\Grpc.Tools.0.5.1\tools\grpc_csharp_plugin.exe RouteGuide/protos/route_guide.proto +``` + +On Linux/MacOS, we rely on `protoc` and `grpc_csharp_plugin` being installed by Linuxbrew/Homebrew. Run this command from the route_guide directory: +```shell +$ protoc -I RouteGuide/protos --csharp_out=RouteGuide --grpc_out=RouteGuide --plugin=protoc-gen-grpc=`which grpc_csharp_plugin` RouteGuide/protos/route_guide.proto +``` + +Running one of the previous commands regenerates the following files in the RouteGuide directory: +- `RouteGuide/RouteGuide.cs` defines a namespace `examples` + - This contains all the protocol buffer code to populate, serialize, and retrieve our request and response message types +- `RouteGuide/RouteGuideGrpc.cs`, provides stub and service classes + - an interface `RouteGuide.IRouteGuide` to inherit from when defining RouteGuide service implementations + - a class `RouteGuide.RouteGuideClient` that can be used to access remote RouteGuide instances + + + +## Creating the server + +First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). + +There are two parts to making our `RouteGuide` service do its job: +- Implementing the service interface generated from our service definition: doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and return the service responses. + +You can find our example `RouteGuide` server in [grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/RouteGuideServer/RouteGuideServerImpl.cs). Let's take a closer look at how it works. + +### Implementing RouteGuide + +As you can see, our server has a `RouteGuideImpl` class that implements the generated `RouteGuide.IRouteGuide`: + +```csharp +// RouteGuideImpl provides an implementation of the RouteGuide service. +public class RouteGuideImpl : RouteGuide.IRouteGuide +``` + +#### Simple RPC + +`RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. + +```csharp + public Task GetFeature(Grpc.Core.ServerCallContext context, Point request) + { + return Task.FromResult(CheckFeature(request)); + } +``` + +The method is passed a context for the RPC (which is empty in the alpha release), the client's `Point` protocol buffer request, and returns a `Feature` protocol buffer. In the method we create the `Feature` with the appropriate information, and then return it. To allow asynchronous +implementation, the method returns `Task` rather than just `Feature`. You are free to perform your computations synchronously and return +the result once you've finished, just as we do in the example. + +#### Server-side streaming RPC + +Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature` protocol buffers to our client. + +```csharp + // in RouteGuideImpl + public async Task ListFeatures(Grpc.Core.ServerCallContext context, Rectangle request, + Grpc.Core.IServerStreamWriter responseStream) + { + int left = Math.Min(request.Lo.Longitude, request.Hi.Longitude); + int right = Math.Max(request.Lo.Longitude, request.Hi.Longitude); + int top = Math.Max(request.Lo.Latitude, request.Hi.Latitude); + int bottom = Math.Min(request.Lo.Latitude, request.Hi.Latitude); + + foreach (var feature in features) + { + if (!RouteGuideUtil.Exists(feature)) + { + continue; + } + + int lat = feature.Location.Latitude; + int lon = feature.Location.Longitude; + if (lon >= left && lon <= right && lat >= bottom && lat <= top) + { + await responseStream.WriteAsync(feature); + } + } + } +``` + +As you can see, here the request object is a `Rectangle` in which our client wants to find `Feature`s, but instead of returning a simple response we need to write responses to an asynchronous stream `IServerStreamWriter` using async method `WriteAsync`. + +#### Client-side streaming RPC + +Similarly, the client-side streaming method `RecordRoute` uses an [IAsyncEnumerator](https://github.com/Reactive-Extensions/Rx.NET/blob/master/Ix.NET/Source/System.Interactive.Async/IAsyncEnumerator.cs), to read the stream of requests using the async method `MoveNext` and the `Current` property. + +```csharp + public async Task RecordRoute(Grpc.Core.ServerCallContext context, + Grpc.Core.IAsyncStreamReader requestStream) + { + int pointCount = 0; + int featureCount = 0; + int distance = 0; + Point previous = null; + var stopwatch = new Stopwatch(); + stopwatch.Start(); + + while (await requestStream.MoveNext()) + { + var point = requestStream.Current; + pointCount++; + if (RouteGuideUtil.Exists(CheckFeature(point))) + { + featureCount++; + } + if (previous != null) + { + distance += (int) CalcDistance(previous, point); + } + previous = point; + } + + stopwatch.Stop(); + return RouteSummary.CreateBuilder().SetPointCount(pointCount) + .SetFeatureCount(featureCount).SetDistance(distance) + .SetElapsedTime((int) (stopwatch.ElapsedMilliseconds / 1000)).Build(); + } +``` + +#### Bidirectional streaming RPC + +Finally, let's look at our bidirectional streaming RPC `RouteChat`. + +```csharp + public async Task RouteChat(Grpc.Core.ServerCallContext context, + Grpc.Core.IAsyncStreamReader requestStream, Grpc.Core.IServerStreamWriter responseStream) + { + while (await requestStream.MoveNext()) + { + var note = requestStream.Current; + List notes = GetOrCreateNotes(note.Location); + + List prevNotes; + lock (notes) + { + prevNotes = new List(notes); + } + + foreach (var prevNote in prevNotes) + { + await responseStream.WriteAsync(prevNote); + } + + lock (notes) + { + notes.Add(note); + } + } + } +``` + +Here the method receives both `requestStream` and `responseStream` arguments. Reading the requests is done the same way as in the client-side streaming method `RecordRoute`. Writing the responses is done the same way as in the server-side streaming method `ListFeatures`. + +### Starting the server + +Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: + +```csharp +var features = RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile); +GrpcEnvironment.Initialize(); + +Server server = new Server(); +server.AddServiceDefinition(RouteGuide.BindService(new RouteGuideImpl(features))); +int port = server.AddListeningPort("localhost", 50052); +server.Start(); + +Console.WriteLine("RouteGuide server listening on port " + port); +Console.WriteLine("Press any key to stop the server..."); +Console.ReadKey(); + +server.ShutdownAsync().Wait(); +GrpcEnvironment.Shutdown(); +``` +As you can see, we build and start our server using `Grpc.Core.Server` class. To do this, we: + +1. Create an instance of `Grpc.Core.Server`. +1. Create an instance of our service implementation class `RouteGuideImpl`. +3. Register our service implementation with the server using the `AddServiceDefinition` method and the generated method `RouteGuide.BindService`. +2. Specify the address and port we want to use to listen for client requests using the `AddListeningPort` method. +4. Call `Start` on the server instance to start an RPC server for our service. + + +## Creating the client + +In this section, we'll look at creating a C# client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/csharp/route_guide/RouteGuideClient/Program.cs](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/RouteGuideClient/Program.cs). + +### Creating a stub + +To call service methods, we first need to create a *stub*. + +First, we need to create a gRPC client channel that will connect to gRPC server. Then, we use the `RouteGuide.NewStub` method of the `RouteGuide` class generated from our .proto. + +```csharp +GrpcEnvironment.Initialize(); + +using (Channel channel = new Channel("127.0.0.1:50052")) +{ + var client = RouteGuide.NewStub(channel); + + // YOUR CODE GOES HERE +} + +GrpcEnvironment.Shutdown(); +``` + +### Calling service methods + +Now let's look at how we call our service methods. gRPC C# provides asynchronous versions of each of the supported method types. For convenience, +gRPC C# also provides a synchronous method stub, but only for simple (single request/single response) RPCs. + +#### Simple RPC + +Calling the simple RPC `GetFeature` in a synchronous way is nearly as straightforward as calling a local method. + +```csharp +Point request = Point.CreateBuilder().SetLatitude(409146138).SetLongitude(-746188906).Build(); +Feature feature = client.GetFeature(request); +``` + +As you can see, we create and populate a request protocol buffer object (in our case `Point`), and call the desired method on the client object, passing it the request. If the RPC finishes with success, the response protocol buffer (in our case `Feature`) will be returned. Otherwise, an exception of type `RpcException` will be thrown, indicating the status code of the problem. + +Alternatively, if you are in async context, you can call an asynchronous version of the method (and use `await` keyword to await the result): +```csharp +Point request = Point.CreateBuilder().SetLatitude(409146138).SetLongitude(-746188906).Build(); +Feature feature = await client.GetFeatureAsync(request); +``` + +#### Streaming RPCs + +Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. The difference with respect to simple call is that the client methods return an instance of a call object, that provides access to request/response streams and/or asynchronous result (depending on the streaming type you are using). + +Here's where we call the server-side streaming method `ListFeatures`, which has property `ReponseStream` of type `IAsyncEnumerator` + +```csharp +using (var call = client.ListFeatures(request)) +{ + while (await call.ResponseStream.MoveNext()) + { + Feature feature = call.ResponseStream.Current; + Console.WriteLine("Received " + feature.ToString()); + } +} +``` + +The client-side streaming method `RecordRoute` is similar, except we use the property `RequestStream` to write the requests one by one using `WriteAsync` and eventually signal that no more request will be send using `CompleteAsync`. The method result can be obtained through the property +`Result`. +```csharp +using (var call = client.RecordRoute()) +{ + foreach (var point in points) + { + await call.RequestStream.WriteAsync(point); + } + await call.RequestStream.CompleteAsync(); + + RouteSummary summary = await call.Result; +} +``` + +Finally, let's look at our bidirectional streaming RPC `RouteChat`. In this case, we write the request to `RequestStream` and receive the responses from `ResponseStream`. As you can see from the example, the streams are independent of each other. + +```csharp + using (var call = client.RouteChat()) + { + var responseReaderTask = Task.Run(async () => + { + while (await call.ResponseStream.MoveNext()) + { + var note = call.ResponseStream.Current; + Console.WriteLine("Received " + note); + } + }); + + foreach (RouteNote request in requests) + { + await call.RequestStream.WriteAsync(request); + } + await call.RequestStream.CompleteAsync(); + await responseReaderTask; +} +``` + +## Try it out! + +Build client and server: + +Open the solution `grpc-common/csharp/route_guide/RouteGuide.sln` from Visual Studio (or Monodevelop on Linux) and hit "Build". + +Run the server, which will listen on port 50052: +``` +> cd RouteGuideServer/bin/Debug +> RouteGuideServer.exe +``` + +Run the client (in a different terminal): +``` +> cd RouteGuideClient/bin/Debug +> RouteGuideClient.exe +``` + +You can also run the server and client directly from Visual Studio. + +On Linux or Mac, use `mono RouteGuideServer.exe` and `mono RouteGuideClient.exe` to run the server and client. diff --git a/examples/csharp/route_guide/RouteGuide.sln b/examples/csharp/route_guide/RouteGuide.sln new file mode 100644 index 0000000000..0b79fdc5ca --- /dev/null +++ b/examples/csharp/route_guide/RouteGuide.sln @@ -0,0 +1,39 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuide", "RouteGuide\RouteGuide.csproj", "{49954D9C-5F17-4662-96B2-73BE833DD81A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideClient", "RouteGuideClient\RouteGuideClient.csproj", "{D47BE663-4DE3-4206-B7A8-EA3FA066DADC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideServer", "RouteGuideServer\RouteGuideServer.csproj", "{4B7C7794-BE24-4477-ACE7-18259EB73D27}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2F6B184B-A576-4F21-AF2E-27E73D1FC96E}" + ProjectSection(SolutionItems) = preProject + .nuget\packages.config = .nuget\packages.config + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {49954D9C-5F17-4662-96B2-73BE833DD81A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {49954D9C-5F17-4662-96B2-73BE833DD81A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {49954D9C-5F17-4662-96B2-73BE833DD81A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {49954D9C-5F17-4662-96B2-73BE833DD81A}.Release|Any CPU.Build.0 = Release|Any CPU + {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Release|Any CPU.Build.0 = Release|Any CPU + {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/examples/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs b/examples/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..9c3441e42f --- /dev/null +++ b/examples/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RouteGuide")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RouteGuide")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ef6b85bc-ac27-46de-8714-a658236cc6fb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuide.cs b/examples/csharp/route_guide/RouteGuide/RouteGuide.cs new file mode 100644 index 0000000000..80508bcd3f --- /dev/null +++ b/examples/csharp/route_guide/RouteGuide/RouteGuide.cs @@ -0,0 +1,1873 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: route_guide.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.ProtocolBuffers; +using pbc = global::Google.ProtocolBuffers.Collections; +using pbd = global::Google.ProtocolBuffers.Descriptors; +using scg = global::System.Collections.Generic; +namespace examples { + + namespace Proto { + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public static partial class RouteGuide { + + #region Extension registration + public static void RegisterAllExtensions(pb::ExtensionRegistry registry) { + } + #endregion + #region Static variables + internal static pbd::MessageDescriptor internal__static_examples_Point__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_Point__FieldAccessorTable; + internal static pbd::MessageDescriptor internal__static_examples_Rectangle__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_Rectangle__FieldAccessorTable; + internal static pbd::MessageDescriptor internal__static_examples_Feature__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_Feature__FieldAccessorTable; + internal static pbd::MessageDescriptor internal__static_examples_RouteNote__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_RouteNote__FieldAccessorTable; + internal static pbd::MessageDescriptor internal__static_examples_RouteSummary__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_RouteSummary__FieldAccessorTable; + #endregion + #region Descriptor + public static pbd::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbd::FileDescriptor descriptor; + + static RouteGuide() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChFyb3V0ZV9ndWlkZS5wcm90bxIIZXhhbXBsZXMiLAoFUG9pbnQSEAoIbGF0", + "aXR1ZGUYASABKAUSEQoJbG9uZ2l0dWRlGAIgASgFIkUKCVJlY3RhbmdsZRIb", + "CgJsbxgBIAEoCzIPLmV4YW1wbGVzLlBvaW50EhsKAmhpGAIgASgLMg8uZXhh", + "bXBsZXMuUG9pbnQiOgoHRmVhdHVyZRIMCgRuYW1lGAEgASgJEiEKCGxvY2F0", + "aW9uGAIgASgLMg8uZXhhbXBsZXMuUG9pbnQiPwoJUm91dGVOb3RlEiEKCGxv", + "Y2F0aW9uGAEgASgLMg8uZXhhbXBsZXMuUG9pbnQSDwoHbWVzc2FnZRgCIAEo", + "CSJiCgxSb3V0ZVN1bW1hcnkSEwoLcG9pbnRfY291bnQYASABKAUSFQoNZmVh", + "dHVyZV9jb3VudBgCIAEoBRIQCghkaXN0YW5jZRgDIAEoBRIUCgxlbGFwc2Vk", + "X3RpbWUYBCABKAUy9QEKClJvdXRlR3VpZGUSMgoKR2V0RmVhdHVyZRIPLmV4", + "YW1wbGVzLlBvaW50GhEuZXhhbXBsZXMuRmVhdHVyZSIAEjoKDExpc3RGZWF0", + "dXJlcxITLmV4YW1wbGVzLlJlY3RhbmdsZRoRLmV4YW1wbGVzLkZlYXR1cmUi", + "ADABEjoKC1JlY29yZFJvdXRlEg8uZXhhbXBsZXMuUG9pbnQaFi5leGFtcGxl", + "cy5Sb3V0ZVN1bW1hcnkiACgBEjsKCVJvdXRlQ2hhdBITLmV4YW1wbGVzLlJv", + "dXRlTm90ZRoTLmV4YW1wbGVzLlJvdXRlTm90ZSIAKAEwAQ==")); + pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) { + descriptor = root; + internal__static_examples_Point__Descriptor = Descriptor.MessageTypes[0]; + internal__static_examples_Point__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_examples_Point__Descriptor, + new string[] { "Latitude", "Longitude", }); + internal__static_examples_Rectangle__Descriptor = Descriptor.MessageTypes[1]; + internal__static_examples_Rectangle__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_examples_Rectangle__Descriptor, + new string[] { "Lo", "Hi", }); + internal__static_examples_Feature__Descriptor = Descriptor.MessageTypes[2]; + internal__static_examples_Feature__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_examples_Feature__Descriptor, + new string[] { "Name", "Location", }); + internal__static_examples_RouteNote__Descriptor = Descriptor.MessageTypes[3]; + internal__static_examples_RouteNote__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_examples_RouteNote__Descriptor, + new string[] { "Location", "Message", }); + internal__static_examples_RouteSummary__Descriptor = Descriptor.MessageTypes[4]; + internal__static_examples_RouteSummary__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_examples_RouteSummary__Descriptor, + new string[] { "PointCount", "FeatureCount", "Distance", "ElapsedTime", }); + pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance(); + RegisterAllExtensions(registry); + return registry; + }; + pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData, + new pbd::FileDescriptor[] { + }, assigner); + } + #endregion + + } + } + #region Messages + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Point : pb::GeneratedMessage { + private Point() { } + private static readonly Point defaultInstance = new Point().MakeReadOnly(); + private static readonly string[] _pointFieldNames = new string[] { "latitude", "longitude" }; + private static readonly uint[] _pointFieldTags = new uint[] { 8, 16 }; + public static Point DefaultInstance { + get { return defaultInstance; } + } + + public override Point DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override Point ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::examples.Proto.RouteGuide.internal__static_examples_Point__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::examples.Proto.RouteGuide.internal__static_examples_Point__FieldAccessorTable; } + } + + public const int LatitudeFieldNumber = 1; + private bool hasLatitude; + private int latitude_; + public bool HasLatitude { + get { return hasLatitude; } + } + public int Latitude { + get { return latitude_; } + } + + public const int LongitudeFieldNumber = 2; + private bool hasLongitude; + private int longitude_; + public bool HasLongitude { + get { return hasLongitude; } + } + public int Longitude { + get { return longitude_; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _pointFieldNames; + if (hasLatitude) { + output.WriteInt32(1, field_names[0], Latitude); + } + if (hasLongitude) { + output.WriteInt32(2, field_names[1], Longitude); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasLatitude) { + size += pb::CodedOutputStream.ComputeInt32Size(1, Latitude); + } + if (hasLongitude) { + size += pb::CodedOutputStream.ComputeInt32Size(2, Longitude); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static Point ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static Point ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static Point ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static Point ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static Point ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static Point ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static Point ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static Point ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static Point ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static Point ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private Point MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(Point prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(Point cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private Point result; + + private Point PrepareBuilder() { + if (resultIsReadOnly) { + Point original = result; + result = new Point(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override Point MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::examples.Point.Descriptor; } + } + + public override Point DefaultInstanceForType { + get { return global::examples.Point.DefaultInstance; } + } + + public override Point BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is Point) { + return MergeFrom((Point) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(Point other) { + if (other == global::examples.Point.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasLatitude) { + Latitude = other.Latitude; + } + if (other.HasLongitude) { + Longitude = other.Longitude; + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_pointFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _pointFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 8: { + result.hasLatitude = input.ReadInt32(ref result.latitude_); + break; + } + case 16: { + result.hasLongitude = input.ReadInt32(ref result.longitude_); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasLatitude { + get { return result.hasLatitude; } + } + public int Latitude { + get { return result.Latitude; } + set { SetLatitude(value); } + } + public Builder SetLatitude(int value) { + PrepareBuilder(); + result.hasLatitude = true; + result.latitude_ = value; + return this; + } + public Builder ClearLatitude() { + PrepareBuilder(); + result.hasLatitude = false; + result.latitude_ = 0; + return this; + } + + public bool HasLongitude { + get { return result.hasLongitude; } + } + public int Longitude { + get { return result.Longitude; } + set { SetLongitude(value); } + } + public Builder SetLongitude(int value) { + PrepareBuilder(); + result.hasLongitude = true; + result.longitude_ = value; + return this; + } + public Builder ClearLongitude() { + PrepareBuilder(); + result.hasLongitude = false; + result.longitude_ = 0; + return this; + } + } + static Point() { + object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Rectangle : pb::GeneratedMessage { + private Rectangle() { } + private static readonly Rectangle defaultInstance = new Rectangle().MakeReadOnly(); + private static readonly string[] _rectangleFieldNames = new string[] { "hi", "lo" }; + private static readonly uint[] _rectangleFieldTags = new uint[] { 18, 10 }; + public static Rectangle DefaultInstance { + get { return defaultInstance; } + } + + public override Rectangle DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override Rectangle ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::examples.Proto.RouteGuide.internal__static_examples_Rectangle__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::examples.Proto.RouteGuide.internal__static_examples_Rectangle__FieldAccessorTable; } + } + + public const int LoFieldNumber = 1; + private bool hasLo; + private global::examples.Point lo_; + public bool HasLo { + get { return hasLo; } + } + public global::examples.Point Lo { + get { return lo_ ?? global::examples.Point.DefaultInstance; } + } + + public const int HiFieldNumber = 2; + private bool hasHi; + private global::examples.Point hi_; + public bool HasHi { + get { return hasHi; } + } + public global::examples.Point Hi { + get { return hi_ ?? global::examples.Point.DefaultInstance; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _rectangleFieldNames; + if (hasLo) { + output.WriteMessage(1, field_names[1], Lo); + } + if (hasHi) { + output.WriteMessage(2, field_names[0], Hi); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasLo) { + size += pb::CodedOutputStream.ComputeMessageSize(1, Lo); + } + if (hasHi) { + size += pb::CodedOutputStream.ComputeMessageSize(2, Hi); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static Rectangle ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static Rectangle ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static Rectangle ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static Rectangle ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static Rectangle ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static Rectangle ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static Rectangle ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static Rectangle ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static Rectangle ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static Rectangle ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private Rectangle MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(Rectangle prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(Rectangle cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private Rectangle result; + + private Rectangle PrepareBuilder() { + if (resultIsReadOnly) { + Rectangle original = result; + result = new Rectangle(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override Rectangle MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::examples.Rectangle.Descriptor; } + } + + public override Rectangle DefaultInstanceForType { + get { return global::examples.Rectangle.DefaultInstance; } + } + + public override Rectangle BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is Rectangle) { + return MergeFrom((Rectangle) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(Rectangle other) { + if (other == global::examples.Rectangle.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasLo) { + MergeLo(other.Lo); + } + if (other.HasHi) { + MergeHi(other.Hi); + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_rectangleFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _rectangleFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 10: { + global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); + if (result.hasLo) { + subBuilder.MergeFrom(Lo); + } + input.ReadMessage(subBuilder, extensionRegistry); + Lo = subBuilder.BuildPartial(); + break; + } + case 18: { + global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); + if (result.hasHi) { + subBuilder.MergeFrom(Hi); + } + input.ReadMessage(subBuilder, extensionRegistry); + Hi = subBuilder.BuildPartial(); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasLo { + get { return result.hasLo; } + } + public global::examples.Point Lo { + get { return result.Lo; } + set { SetLo(value); } + } + public Builder SetLo(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasLo = true; + result.lo_ = value; + return this; + } + public Builder SetLo(global::examples.Point.Builder builderForValue) { + pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); + PrepareBuilder(); + result.hasLo = true; + result.lo_ = builderForValue.Build(); + return this; + } + public Builder MergeLo(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + if (result.hasLo && + result.lo_ != global::examples.Point.DefaultInstance) { + result.lo_ = global::examples.Point.CreateBuilder(result.lo_).MergeFrom(value).BuildPartial(); + } else { + result.lo_ = value; + } + result.hasLo = true; + return this; + } + public Builder ClearLo() { + PrepareBuilder(); + result.hasLo = false; + result.lo_ = null; + return this; + } + + public bool HasHi { + get { return result.hasHi; } + } + public global::examples.Point Hi { + get { return result.Hi; } + set { SetHi(value); } + } + public Builder SetHi(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasHi = true; + result.hi_ = value; + return this; + } + public Builder SetHi(global::examples.Point.Builder builderForValue) { + pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); + PrepareBuilder(); + result.hasHi = true; + result.hi_ = builderForValue.Build(); + return this; + } + public Builder MergeHi(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + if (result.hasHi && + result.hi_ != global::examples.Point.DefaultInstance) { + result.hi_ = global::examples.Point.CreateBuilder(result.hi_).MergeFrom(value).BuildPartial(); + } else { + result.hi_ = value; + } + result.hasHi = true; + return this; + } + public Builder ClearHi() { + PrepareBuilder(); + result.hasHi = false; + result.hi_ = null; + return this; + } + } + static Rectangle() { + object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Feature : pb::GeneratedMessage { + private Feature() { } + private static readonly Feature defaultInstance = new Feature().MakeReadOnly(); + private static readonly string[] _featureFieldNames = new string[] { "location", "name" }; + private static readonly uint[] _featureFieldTags = new uint[] { 18, 10 }; + public static Feature DefaultInstance { + get { return defaultInstance; } + } + + public override Feature DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override Feature ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::examples.Proto.RouteGuide.internal__static_examples_Feature__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::examples.Proto.RouteGuide.internal__static_examples_Feature__FieldAccessorTable; } + } + + public const int NameFieldNumber = 1; + private bool hasName; + private string name_ = ""; + public bool HasName { + get { return hasName; } + } + public string Name { + get { return name_; } + } + + public const int LocationFieldNumber = 2; + private bool hasLocation; + private global::examples.Point location_; + public bool HasLocation { + get { return hasLocation; } + } + public global::examples.Point Location { + get { return location_ ?? global::examples.Point.DefaultInstance; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _featureFieldNames; + if (hasName) { + output.WriteString(1, field_names[1], Name); + } + if (hasLocation) { + output.WriteMessage(2, field_names[0], Location); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasName) { + size += pb::CodedOutputStream.ComputeStringSize(1, Name); + } + if (hasLocation) { + size += pb::CodedOutputStream.ComputeMessageSize(2, Location); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static Feature ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static Feature ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static Feature ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static Feature ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static Feature ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static Feature ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static Feature ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static Feature ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static Feature ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static Feature ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private Feature MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(Feature prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(Feature cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private Feature result; + + private Feature PrepareBuilder() { + if (resultIsReadOnly) { + Feature original = result; + result = new Feature(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override Feature MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::examples.Feature.Descriptor; } + } + + public override Feature DefaultInstanceForType { + get { return global::examples.Feature.DefaultInstance; } + } + + public override Feature BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is Feature) { + return MergeFrom((Feature) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(Feature other) { + if (other == global::examples.Feature.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasName) { + Name = other.Name; + } + if (other.HasLocation) { + MergeLocation(other.Location); + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_featureFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _featureFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 10: { + result.hasName = input.ReadString(ref result.name_); + break; + } + case 18: { + global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); + if (result.hasLocation) { + subBuilder.MergeFrom(Location); + } + input.ReadMessage(subBuilder, extensionRegistry); + Location = subBuilder.BuildPartial(); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasName { + get { return result.hasName; } + } + public string Name { + get { return result.Name; } + set { SetName(value); } + } + public Builder SetName(string value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasName = true; + result.name_ = value; + return this; + } + public Builder ClearName() { + PrepareBuilder(); + result.hasName = false; + result.name_ = ""; + return this; + } + + public bool HasLocation { + get { return result.hasLocation; } + } + public global::examples.Point Location { + get { return result.Location; } + set { SetLocation(value); } + } + public Builder SetLocation(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasLocation = true; + result.location_ = value; + return this; + } + public Builder SetLocation(global::examples.Point.Builder builderForValue) { + pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); + PrepareBuilder(); + result.hasLocation = true; + result.location_ = builderForValue.Build(); + return this; + } + public Builder MergeLocation(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + if (result.hasLocation && + result.location_ != global::examples.Point.DefaultInstance) { + result.location_ = global::examples.Point.CreateBuilder(result.location_).MergeFrom(value).BuildPartial(); + } else { + result.location_ = value; + } + result.hasLocation = true; + return this; + } + public Builder ClearLocation() { + PrepareBuilder(); + result.hasLocation = false; + result.location_ = null; + return this; + } + } + static Feature() { + object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class RouteNote : pb::GeneratedMessage { + private RouteNote() { } + private static readonly RouteNote defaultInstance = new RouteNote().MakeReadOnly(); + private static readonly string[] _routeNoteFieldNames = new string[] { "location", "message" }; + private static readonly uint[] _routeNoteFieldTags = new uint[] { 10, 18 }; + public static RouteNote DefaultInstance { + get { return defaultInstance; } + } + + public override RouteNote DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override RouteNote ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteNote__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteNote__FieldAccessorTable; } + } + + public const int LocationFieldNumber = 1; + private bool hasLocation; + private global::examples.Point location_; + public bool HasLocation { + get { return hasLocation; } + } + public global::examples.Point Location { + get { return location_ ?? global::examples.Point.DefaultInstance; } + } + + public const int MessageFieldNumber = 2; + private bool hasMessage; + private string message_ = ""; + public bool HasMessage { + get { return hasMessage; } + } + public string Message { + get { return message_; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _routeNoteFieldNames; + if (hasLocation) { + output.WriteMessage(1, field_names[0], Location); + } + if (hasMessage) { + output.WriteString(2, field_names[1], Message); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasLocation) { + size += pb::CodedOutputStream.ComputeMessageSize(1, Location); + } + if (hasMessage) { + size += pb::CodedOutputStream.ComputeStringSize(2, Message); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static RouteNote ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static RouteNote ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static RouteNote ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static RouteNote ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static RouteNote ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static RouteNote ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static RouteNote ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static RouteNote ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static RouteNote ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static RouteNote ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private RouteNote MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(RouteNote prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(RouteNote cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private RouteNote result; + + private RouteNote PrepareBuilder() { + if (resultIsReadOnly) { + RouteNote original = result; + result = new RouteNote(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override RouteNote MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::examples.RouteNote.Descriptor; } + } + + public override RouteNote DefaultInstanceForType { + get { return global::examples.RouteNote.DefaultInstance; } + } + + public override RouteNote BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is RouteNote) { + return MergeFrom((RouteNote) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(RouteNote other) { + if (other == global::examples.RouteNote.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasLocation) { + MergeLocation(other.Location); + } + if (other.HasMessage) { + Message = other.Message; + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_routeNoteFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _routeNoteFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 10: { + global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); + if (result.hasLocation) { + subBuilder.MergeFrom(Location); + } + input.ReadMessage(subBuilder, extensionRegistry); + Location = subBuilder.BuildPartial(); + break; + } + case 18: { + result.hasMessage = input.ReadString(ref result.message_); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasLocation { + get { return result.hasLocation; } + } + public global::examples.Point Location { + get { return result.Location; } + set { SetLocation(value); } + } + public Builder SetLocation(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasLocation = true; + result.location_ = value; + return this; + } + public Builder SetLocation(global::examples.Point.Builder builderForValue) { + pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); + PrepareBuilder(); + result.hasLocation = true; + result.location_ = builderForValue.Build(); + return this; + } + public Builder MergeLocation(global::examples.Point value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + if (result.hasLocation && + result.location_ != global::examples.Point.DefaultInstance) { + result.location_ = global::examples.Point.CreateBuilder(result.location_).MergeFrom(value).BuildPartial(); + } else { + result.location_ = value; + } + result.hasLocation = true; + return this; + } + public Builder ClearLocation() { + PrepareBuilder(); + result.hasLocation = false; + result.location_ = null; + return this; + } + + public bool HasMessage { + get { return result.hasMessage; } + } + public string Message { + get { return result.Message; } + set { SetMessage(value); } + } + public Builder SetMessage(string value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasMessage = true; + result.message_ = value; + return this; + } + public Builder ClearMessage() { + PrepareBuilder(); + result.hasMessage = false; + result.message_ = ""; + return this; + } + } + static RouteNote() { + object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class RouteSummary : pb::GeneratedMessage { + private RouteSummary() { } + private static readonly RouteSummary defaultInstance = new RouteSummary().MakeReadOnly(); + private static readonly string[] _routeSummaryFieldNames = new string[] { "distance", "elapsed_time", "feature_count", "point_count" }; + private static readonly uint[] _routeSummaryFieldTags = new uint[] { 24, 32, 16, 8 }; + public static RouteSummary DefaultInstance { + get { return defaultInstance; } + } + + public override RouteSummary DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override RouteSummary ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteSummary__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteSummary__FieldAccessorTable; } + } + + public const int PointCountFieldNumber = 1; + private bool hasPointCount; + private int pointCount_; + public bool HasPointCount { + get { return hasPointCount; } + } + public int PointCount { + get { return pointCount_; } + } + + public const int FeatureCountFieldNumber = 2; + private bool hasFeatureCount; + private int featureCount_; + public bool HasFeatureCount { + get { return hasFeatureCount; } + } + public int FeatureCount { + get { return featureCount_; } + } + + public const int DistanceFieldNumber = 3; + private bool hasDistance; + private int distance_; + public bool HasDistance { + get { return hasDistance; } + } + public int Distance { + get { return distance_; } + } + + public const int ElapsedTimeFieldNumber = 4; + private bool hasElapsedTime; + private int elapsedTime_; + public bool HasElapsedTime { + get { return hasElapsedTime; } + } + public int ElapsedTime { + get { return elapsedTime_; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _routeSummaryFieldNames; + if (hasPointCount) { + output.WriteInt32(1, field_names[3], PointCount); + } + if (hasFeatureCount) { + output.WriteInt32(2, field_names[2], FeatureCount); + } + if (hasDistance) { + output.WriteInt32(3, field_names[0], Distance); + } + if (hasElapsedTime) { + output.WriteInt32(4, field_names[1], ElapsedTime); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasPointCount) { + size += pb::CodedOutputStream.ComputeInt32Size(1, PointCount); + } + if (hasFeatureCount) { + size += pb::CodedOutputStream.ComputeInt32Size(2, FeatureCount); + } + if (hasDistance) { + size += pb::CodedOutputStream.ComputeInt32Size(3, Distance); + } + if (hasElapsedTime) { + size += pb::CodedOutputStream.ComputeInt32Size(4, ElapsedTime); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static RouteSummary ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static RouteSummary ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static RouteSummary ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static RouteSummary ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static RouteSummary ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static RouteSummary ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static RouteSummary ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static RouteSummary ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static RouteSummary ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static RouteSummary ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private RouteSummary MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(RouteSummary prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(RouteSummary cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private RouteSummary result; + + private RouteSummary PrepareBuilder() { + if (resultIsReadOnly) { + RouteSummary original = result; + result = new RouteSummary(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override RouteSummary MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::examples.RouteSummary.Descriptor; } + } + + public override RouteSummary DefaultInstanceForType { + get { return global::examples.RouteSummary.DefaultInstance; } + } + + public override RouteSummary BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is RouteSummary) { + return MergeFrom((RouteSummary) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(RouteSummary other) { + if (other == global::examples.RouteSummary.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasPointCount) { + PointCount = other.PointCount; + } + if (other.HasFeatureCount) { + FeatureCount = other.FeatureCount; + } + if (other.HasDistance) { + Distance = other.Distance; + } + if (other.HasElapsedTime) { + ElapsedTime = other.ElapsedTime; + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_routeSummaryFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _routeSummaryFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 8: { + result.hasPointCount = input.ReadInt32(ref result.pointCount_); + break; + } + case 16: { + result.hasFeatureCount = input.ReadInt32(ref result.featureCount_); + break; + } + case 24: { + result.hasDistance = input.ReadInt32(ref result.distance_); + break; + } + case 32: { + result.hasElapsedTime = input.ReadInt32(ref result.elapsedTime_); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasPointCount { + get { return result.hasPointCount; } + } + public int PointCount { + get { return result.PointCount; } + set { SetPointCount(value); } + } + public Builder SetPointCount(int value) { + PrepareBuilder(); + result.hasPointCount = true; + result.pointCount_ = value; + return this; + } + public Builder ClearPointCount() { + PrepareBuilder(); + result.hasPointCount = false; + result.pointCount_ = 0; + return this; + } + + public bool HasFeatureCount { + get { return result.hasFeatureCount; } + } + public int FeatureCount { + get { return result.FeatureCount; } + set { SetFeatureCount(value); } + } + public Builder SetFeatureCount(int value) { + PrepareBuilder(); + result.hasFeatureCount = true; + result.featureCount_ = value; + return this; + } + public Builder ClearFeatureCount() { + PrepareBuilder(); + result.hasFeatureCount = false; + result.featureCount_ = 0; + return this; + } + + public bool HasDistance { + get { return result.hasDistance; } + } + public int Distance { + get { return result.Distance; } + set { SetDistance(value); } + } + public Builder SetDistance(int value) { + PrepareBuilder(); + result.hasDistance = true; + result.distance_ = value; + return this; + } + public Builder ClearDistance() { + PrepareBuilder(); + result.hasDistance = false; + result.distance_ = 0; + return this; + } + + public bool HasElapsedTime { + get { return result.hasElapsedTime; } + } + public int ElapsedTime { + get { return result.ElapsedTime; } + set { SetElapsedTime(value); } + } + public Builder SetElapsedTime(int value) { + PrepareBuilder(); + result.hasElapsedTime = true; + result.elapsedTime_ = value; + return this; + } + public Builder ClearElapsedTime() { + PrepareBuilder(); + result.hasElapsedTime = false; + result.elapsedTime_ = 0; + return this; + } + } + static RouteSummary() { + object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); + } + } + + #endregion + +} + +#endregion Designer generated code diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj new file mode 100644 index 0000000000..8358974aac --- /dev/null +++ b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj @@ -0,0 +1,101 @@ + + + + + + + + Debug + AnyCPU + {49954D9C-5F17-4662-96B2-73BE833DD81A} + Library + Properties + RouteGuide + RouteGuide + v4.5 + 512 + 214cccda + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll + + + False + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll + + + False + ..\packages\Newtonsoft.Json.7.0.1-beta2\lib\net45\Newtonsoft.Json.dll + + + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + + ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll + + + + + + + + + + + + + + + + + + PreserveNewest + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs b/examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs new file mode 100644 index 0000000000..c4b3900dca --- /dev/null +++ b/examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs @@ -0,0 +1,123 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: route_guide.proto +#region Designer generated code + +using System; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; + +namespace examples { + public static class RouteGuide + { + static readonly string __ServiceName = "examples.RouteGuide"; + + static readonly Marshaller __Marshaller_Point = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.Point.ParseFrom); + static readonly Marshaller __Marshaller_Feature = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.Feature.ParseFrom); + static readonly Marshaller __Marshaller_Rectangle = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.Rectangle.ParseFrom); + static readonly Marshaller __Marshaller_RouteSummary = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.RouteSummary.ParseFrom); + static readonly Marshaller __Marshaller_RouteNote = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.RouteNote.ParseFrom); + + static readonly Method __Method_GetFeature = new Method( + MethodType.Unary, + "GetFeature", + __Marshaller_Point, + __Marshaller_Feature); + + static readonly Method __Method_ListFeatures = new Method( + MethodType.ServerStreaming, + "ListFeatures", + __Marshaller_Rectangle, + __Marshaller_Feature); + + static readonly Method __Method_RecordRoute = new Method( + MethodType.ClientStreaming, + "RecordRoute", + __Marshaller_Point, + __Marshaller_RouteSummary); + + static readonly Method __Method_RouteChat = new Method( + MethodType.DuplexStreaming, + "RouteChat", + __Marshaller_RouteNote, + __Marshaller_RouteNote); + + // client-side stub interface + public interface IRouteGuideClient + { + global::examples.Feature GetFeature(global::examples.Point request, CancellationToken token = default(CancellationToken)); + Task GetFeatureAsync(global::examples.Point request, CancellationToken token = default(CancellationToken)); + AsyncServerStreamingCall ListFeatures(global::examples.Rectangle request, CancellationToken token = default(CancellationToken)); + AsyncClientStreamingCall RecordRoute(CancellationToken token = default(CancellationToken)); + AsyncDuplexStreamingCall RouteChat(CancellationToken token = default(CancellationToken)); + } + + // server-side interface + public interface IRouteGuide + { + Task GetFeature(ServerCallContext context, global::examples.Point request); + Task ListFeatures(ServerCallContext context, global::examples.Rectangle request, IServerStreamWriter responseStream); + Task RecordRoute(ServerCallContext context, IAsyncStreamReader requestStream); + Task RouteChat(ServerCallContext context, IAsyncStreamReader requestStream, IServerStreamWriter responseStream); + } + + // client stub + public class RouteGuideClient : AbstractStub, IRouteGuideClient + { + public RouteGuideClient(Channel channel) : this(channel, StubConfiguration.Default) + { + } + public RouteGuideClient(Channel channel, StubConfiguration config) : base(channel, config) + { + } + public global::examples.Feature GetFeature(global::examples.Point request, CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_GetFeature); + return Calls.BlockingUnaryCall(call, request, token); + } + public Task GetFeatureAsync(global::examples.Point request, CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_GetFeature); + return Calls.AsyncUnaryCall(call, request, token); + } + public AsyncServerStreamingCall ListFeatures(global::examples.Rectangle request, CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_ListFeatures); + return Calls.AsyncServerStreamingCall(call, request, token); + } + public AsyncClientStreamingCall RecordRoute(CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_RecordRoute); + return Calls.AsyncClientStreamingCall(call, token); + } + public AsyncDuplexStreamingCall RouteChat(CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_RouteChat); + return Calls.AsyncDuplexStreamingCall(call, token); + } + } + + // creates service definition that can be registered with a server + public static ServerServiceDefinition BindService(IRouteGuide serviceImpl) + { + return ServerServiceDefinition.CreateBuilder(__ServiceName) + .AddMethod(__Method_GetFeature, serviceImpl.GetFeature) + .AddMethod(__Method_ListFeatures, serviceImpl.ListFeatures) + .AddMethod(__Method_RecordRoute, serviceImpl.RecordRoute) + .AddMethod(__Method_RouteChat, serviceImpl.RouteChat).Build(); + } + + // creates a new client stub + public static IRouteGuideClient NewStub(Channel channel) + { + return new RouteGuideClient(channel); + } + + // creates a new client stub + public static IRouteGuideClient NewStub(Channel channel, StubConfiguration config) + { + return new RouteGuideClient(channel, config); + } + } +} +#endregion diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuideUtil.cs b/examples/csharp/route_guide/RouteGuide/RouteGuideUtil.cs new file mode 100644 index 0000000000..6fb8b1e28a --- /dev/null +++ b/examples/csharp/route_guide/RouteGuide/RouteGuideUtil.cs @@ -0,0 +1,67 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace examples +{ + public static class RouteGuideUtil + { + public const string DefaultFeaturesFile = "route_guide_db.json"; + + private const double CoordFactor = 1e7; + + /// + /// Indicates whether the given feature exists (i.e. has a valid name). + /// + public static bool Exists(Feature feature) + { + return feature != null && (feature.Name.Length != 0); + } + + public static double GetLatitude(Point point) + { + return point.Latitude / CoordFactor; + } + + public static double GetLongitude(Point point) + { + return point.Longitude / CoordFactor; + } + + /// + /// Parses features from a JSON file. + /// + public static List ParseFeatures(string filename) + { + var features = new List(); + var jsonFeatures = JsonConvert.DeserializeObject>(File.ReadAllText(filename)); + + + foreach(var jsonFeature in jsonFeatures) + { + features.Add(Feature.CreateBuilder().SetName(jsonFeature.name).SetLocation( + Point.CreateBuilder() + .SetLongitude(jsonFeature.location.longitude) + .SetLatitude(jsonFeature.location.latitude).Build()).Build()); + } + return features; + } + + private class JsonFeature + { + public string name; + public JsonLocation location; + } + + private class JsonLocation + { + public int longitude; + public int latitude; + } + } +} diff --git a/examples/csharp/route_guide/RouteGuide/packages.config b/examples/csharp/route_guide/RouteGuide/packages.config new file mode 100644 index 0000000000..79abe0aa65 --- /dev/null +++ b/examples/csharp/route_guide/RouteGuide/packages.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/route_guide/RouteGuide/protos/route_guide.proto b/examples/csharp/route_guide/RouteGuide/protos/route_guide.proto new file mode 100644 index 0000000000..f4110b5515 --- /dev/null +++ b/examples/csharp/route_guide/RouteGuide/protos/route_guide.proto @@ -0,0 +1,123 @@ +// 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. + +// TODO(jtattermusch): as of now, C# protobufs don't officially support +// proto3. +syntax = "proto2"; + +package examples; + +// Interface exported by the server. +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + // + // A feature with an empty name is returned if there's no feature at the given + // position. + rpc GetFeature(Point) returns (Feature) {} + + // A server-to-client streaming RPC. + // + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} + + // A client-to-server streaming RPC. + // + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} + + // A Bidirectional streaming RPC. + // + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +} + +// Points are represented as latitude-longitude pairs in the E7 representation +// (degrees multiplied by 10**7 and rounded to the nearest integer). +// Latitudes should be in the range +/- 90 degrees and longitude should be in +// the range +/- 180 degrees (inclusive). +message Point { + optional int32 latitude = 1; + optional int32 longitude = 2; +} + +// A latitude-longitude rectangle, represented as two diagonally opposite +// points "lo" and "hi". +message Rectangle { + // One corner of the rectangle. + optional Point lo = 1; + + // The other corner of the rectangle. + optional Point hi = 2; +} + +// A feature names something at a given point. +// +// If a feature could not be named, the name is empty. +message Feature { + // The name of the feature. + optional string name = 1; + + // The point where the feature is detected. + optional Point location = 2; +} + +// A RouteNote is a message sent while at a given point. +message RouteNote { + // The location from which the message is sent. + optional Point location = 1; + + // The message to be sent. + optional string message = 2; +} + +// A RouteSummary is received in response to a RecordRoute rpc. +// +// It contains the number of individual points received, the number of +// detected features, and the total distance covered as the cumulative sum of +// the distance between each point. +message RouteSummary { + // The number of points received. + optional int32 point_count = 1; + + // The number of known features passed while traversing the route. + optional int32 feature_count = 2; + + // The distance covered in metres. + optional int32 distance = 3; + + // The duration of the traversal in seconds. + optional int32 elapsed_time = 4; +} diff --git a/examples/csharp/route_guide/RouteGuide/route_guide_db.json b/examples/csharp/route_guide/RouteGuide/route_guide_db.json new file mode 100644 index 0000000000..209f016259 --- /dev/null +++ b/examples/csharp/route_guide/RouteGuide/route_guide_db.json @@ -0,0 +1,601 @@ +[{ + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" +}, { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" +}, { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" +}, { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" +}, { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" +}, { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" +}, { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" +}, { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" +}, { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" +}, { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" +}, { + "location": { + "latitude": 415736605, + "longitude": -742847522 + }, + "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" +}, { + "location": { + "latitude": 413843930, + "longitude": -740501726 + }, + "name": "162 Merrill Road, Highland Mills, NY 10930, USA" +}, { + "location": { + "latitude": 410873075, + "longitude": -744459023 + }, + "name": "Clinton Road, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 412346009, + "longitude": -744026814 + }, + "name": "16 Old Brook Lane, Warwick, NY 10990, USA" +}, { + "location": { + "latitude": 402948455, + "longitude": -747903913 + }, + "name": "3 Drake Lane, Pennington, NJ 08534, USA" +}, { + "location": { + "latitude": 406337092, + "longitude": -740122226 + }, + "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" +}, { + "location": { + "latitude": 406421967, + "longitude": -747727624 + }, + "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" +}, { + "location": { + "latitude": 416318082, + "longitude": -749677716 + }, + "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" +}, { + "location": { + "latitude": 415301720, + "longitude": -748416257 + }, + "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" +}, { + "location": { + "latitude": 402647019, + "longitude": -747071791 + }, + "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" +}, { + "location": { + "latitude": 412567807, + "longitude": -741058078 + }, + "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" +}, { + "location": { + "latitude": 416855156, + "longitude": -744420597 + }, + "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" +}, { + "location": { + "latitude": 404663628, + "longitude": -744820157 + }, + "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" +}, { + "location": { + "latitude": 407113723, + "longitude": -749746483 + }, + "name": "" +}, { + "location": { + "latitude": 402133926, + "longitude": -743613249 + }, + "name": "" +}, { + "location": { + "latitude": 400273442, + "longitude": -741220915 + }, + "name": "" +}, { + "location": { + "latitude": 411236786, + "longitude": -744070769 + }, + "name": "" +}, { + "location": { + "latitude": 411633782, + "longitude": -746784970 + }, + "name": "211-225 Plains Road, Augusta, NJ 07822, USA" +}, { + "location": { + "latitude": 415830701, + "longitude": -742952812 + }, + "name": "" +}, { + "location": { + "latitude": 413447164, + "longitude": -748712898 + }, + "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" +}, { + "location": { + "latitude": 405047245, + "longitude": -749800722 + }, + "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" +}, { + "location": { + "latitude": 418858923, + "longitude": -746156790 + }, + "name": "" +}, { + "location": { + "latitude": 417951888, + "longitude": -748484944 + }, + "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" +}, { + "location": { + "latitude": 407033786, + "longitude": -743977337 + }, + "name": "26 East 3rd Street, New Providence, NJ 07974, USA" +}, { + "location": { + "latitude": 417548014, + "longitude": -740075041 + }, + "name": "" +}, { + "location": { + "latitude": 410395868, + "longitude": -744972325 + }, + "name": "" +}, { + "location": { + "latitude": 404615353, + "longitude": -745129803 + }, + "name": "" +}, { + "location": { + "latitude": 406589790, + "longitude": -743560121 + }, + "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" +}, { + "location": { + "latitude": 414653148, + "longitude": -740477477 + }, + "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" +}, { + "location": { + "latitude": 405957808, + "longitude": -743255336 + }, + "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" +}, { + "location": { + "latitude": 411733589, + "longitude": -741648093 + }, + "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" +}, { + "location": { + "latitude": 412676291, + "longitude": -742606606 + }, + "name": "1270 Lakes Road, Monroe, NY 10950, USA" +}, { + "location": { + "latitude": 409224445, + "longitude": -748286738 + }, + "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" +}, { + "location": { + "latitude": 406523420, + "longitude": -742135517 + }, + "name": "652 Garden Street, Elizabeth, NJ 07202, USA" +}, { + "location": { + "latitude": 401827388, + "longitude": -740294537 + }, + "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" +}, { + "location": { + "latitude": 410564152, + "longitude": -743685054 + }, + "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 408472324, + "longitude": -740726046 + }, + "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" +}, { + "location": { + "latitude": 412452168, + "longitude": -740214052 + }, + "name": "5 White Oak Lane, Stony Point, NY 10980, USA" +}, { + "location": { + "latitude": 409146138, + "longitude": -746188906 + }, + "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" +}, { + "location": { + "latitude": 404701380, + "longitude": -744781745 + }, + "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 409642566, + "longitude": -746017679 + }, + "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" +}, { + "location": { + "latitude": 408031728, + "longitude": -748645385 + }, + "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" +}, { + "location": { + "latitude": 413700272, + "longitude": -742135189 + }, + "name": "367 Prospect Road, Chester, NY 10918, USA" +}, { + "location": { + "latitude": 404310607, + "longitude": -740282632 + }, + "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" +}, { + "location": { + "latitude": 409319800, + "longitude": -746201391 + }, + "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" +}, { + "location": { + "latitude": 406685311, + "longitude": -742108603 + }, + "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" +}, { + "location": { + "latitude": 419018117, + "longitude": -749142781 + }, + "name": "43 Dreher Road, Roscoe, NY 12776, USA" +}, { + "location": { + "latitude": 412856162, + "longitude": -745148837 + }, + "name": "Swan Street, Pine Island, NY 10969, USA" +}, { + "location": { + "latitude": 416560744, + "longitude": -746721964 + }, + "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" +}, { + "location": { + "latitude": 405314270, + "longitude": -749836354 + }, + "name": "" +}, { + "location": { + "latitude": 414219548, + "longitude": -743327440 + }, + "name": "" +}, { + "location": { + "latitude": 415534177, + "longitude": -742900616 + }, + "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" +}, { + "location": { + "latitude": 406898530, + "longitude": -749127080 + }, + "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" +}, { + "location": { + "latitude": 407586880, + "longitude": -741670168 + }, + "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" +}, { + "location": { + "latitude": 400106455, + "longitude": -742870190 + }, + "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" +}, { + "location": { + "latitude": 400066188, + "longitude": -746793294 + }, + "name": "" +}, { + "location": { + "latitude": 418803880, + "longitude": -744102673 + }, + "name": "40 Mountain Road, Napanoch, NY 12458, USA" +}, { + "location": { + "latitude": 414204288, + "longitude": -747895140 + }, + "name": "" +}, { + "location": { + "latitude": 414777405, + "longitude": -740615601 + }, + "name": "" +}, { + "location": { + "latitude": 415464475, + "longitude": -747175374 + }, + "name": "48 North Road, Forestburgh, NY 12777, USA" +}, { + "location": { + "latitude": 404062378, + "longitude": -746376177 + }, + "name": "" +}, { + "location": { + "latitude": 405688272, + "longitude": -749285130 + }, + "name": "" +}, { + "location": { + "latitude": 400342070, + "longitude": -748788996 + }, + "name": "" +}, { + "location": { + "latitude": 401809022, + "longitude": -744157964 + }, + "name": "" +}, { + "location": { + "latitude": 404226644, + "longitude": -740517141 + }, + "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" +}, { + "location": { + "latitude": 410322033, + "longitude": -747871659 + }, + "name": "" +}, { + "location": { + "latitude": 407100674, + "longitude": -747742727 + }, + "name": "" +}, { + "location": { + "latitude": 418811433, + "longitude": -741718005 + }, + "name": "213 Bush Road, Stone Ridge, NY 12484, USA" +}, { + "location": { + "latitude": 415034302, + "longitude": -743850945 + }, + "name": "" +}, { + "location": { + "latitude": 411349992, + "longitude": -743694161 + }, + "name": "" +}, { + "location": { + "latitude": 404839914, + "longitude": -744759616 + }, + "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 414638017, + "longitude": -745957854 + }, + "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" +}, { + "location": { + "latitude": 412127800, + "longitude": -740173578 + }, + "name": "" +}, { + "location": { + "latitude": 401263460, + "longitude": -747964303 + }, + "name": "" +}, { + "location": { + "latitude": 412843391, + "longitude": -749086026 + }, + "name": "" +}, { + "location": { + "latitude": 418512773, + "longitude": -743067823 + }, + "name": "" +}, { + "location": { + "latitude": 404318328, + "longitude": -740835638 + }, + "name": "42-102 Main Street, Belford, NJ 07718, USA" +}, { + "location": { + "latitude": 419020746, + "longitude": -741172328 + }, + "name": "" +}, { + "location": { + "latitude": 404080723, + "longitude": -746119569 + }, + "name": "" +}, { + "location": { + "latitude": 401012643, + "longitude": -744035134 + }, + "name": "" +}, { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" +}, { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" +}, { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" +}, { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" +}, { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" +}, { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" +}, { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" +}, { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" +}, { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" +}, { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" +}] \ No newline at end of file diff --git a/examples/csharp/route_guide/RouteGuideClient/App.config b/examples/csharp/route_guide/RouteGuideClient/App.config new file mode 100644 index 0000000000..8e15646352 --- /dev/null +++ b/examples/csharp/route_guide/RouteGuideClient/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/examples/csharp/route_guide/RouteGuideClient/Program.cs b/examples/csharp/route_guide/RouteGuideClient/Program.cs new file mode 100644 index 0000000000..0352c78020 --- /dev/null +++ b/examples/csharp/route_guide/RouteGuideClient/Program.cs @@ -0,0 +1,223 @@ +using Grpc.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace examples +{ + class Program + { + /// + /// Sample client code that makes gRPC calls to the server. + /// + public class RouteGuideClient + { + readonly RouteGuide.IRouteGuideClient client; + + public RouteGuideClient(RouteGuide.IRouteGuideClient client) + { + this.client = client; + } + + /// + /// Blocking unary call example. Calls GetFeature and prints the response. + /// + public void GetFeature(int lat, int lon) + { + try + { + Log("*** GetFeature: lat={0} lon={1}", lat, lon); + + Point request = Point.CreateBuilder().SetLatitude(lat).SetLongitude(lon).Build(); + + Feature feature = client.GetFeature(request); + if (RouteGuideUtil.Exists(feature)) + { + Log("Found feature called \"{0}\" at {1}, {2}", + feature.Name, + RouteGuideUtil.GetLatitude(feature.Location), + RouteGuideUtil.GetLongitude(feature.Location)); + } + else + { + Log("Found no feature at {0}, {1}", + RouteGuideUtil.GetLatitude(feature.Location), + RouteGuideUtil.GetLongitude(feature.Location)); + } + } + catch (RpcException e) + { + Log("RPC failed " + e); + throw e; + } + } + + + /// + /// Server-streaming example. Calls listFeatures with a rectangle of interest. Prints each response feature as it arrives. + /// + public async Task ListFeatures(int lowLat, int lowLon, int hiLat, int hiLon) + { + try + { + Log("*** ListFeatures: lowLat={0} lowLon={1} hiLat={2} hiLon={3}", lowLat, lowLon, hiLat, + hiLon); + + Rectangle request = + Rectangle.CreateBuilder() + .SetLo(Point.CreateBuilder().SetLatitude(lowLat).SetLongitude(lowLon).Build()) + .SetHi(Point.CreateBuilder().SetLatitude(hiLat).SetLongitude(hiLon).Build()).Build(); + + using (var call = client.ListFeatures(request)) + { + StringBuilder responseLog = new StringBuilder("Result: "); + + while (await call.ResponseStream.MoveNext()) + { + Feature feature = call.ResponseStream.Current; + responseLog.Append(feature.ToString()); + } + Log(responseLog.ToString()); + } + } + catch (RpcException e) + { + Log("RPC failed " + e); + throw e; + } + } + + /// + /// Client-streaming example. Sends numPoints randomly chosen points from features + /// with a variable delay in between. Prints the statistics when they are sent from the server. + /// + public async Task RecordRoute(List features, int numPoints) + { + try + { + Log("*** RecordRoute"); + using (var call = client.RecordRoute()) + { + // Send numPoints points randomly selected from the features list. + StringBuilder numMsg = new StringBuilder(); + Random rand = new Random(); + for (int i = 0; i < numPoints; ++i) + { + int index = rand.Next(features.Count); + Point point = features[index].Location; + Log("Visiting point {0}, {1}", RouteGuideUtil.GetLatitude(point), + RouteGuideUtil.GetLongitude(point)); + + await call.RequestStream.WriteAsync(point); + + // A bit of delay before sending the next one. + await Task.Delay(rand.Next(1000) + 500); + } + await call.RequestStream.CompleteAsync(); + + RouteSummary summary = await call.Result; + Log("Finished trip with {0} points. Passed {1} features. " + + "Travelled {2} meters. It took {3} seconds.", summary.PointCount, + summary.FeatureCount, summary.Distance, summary.ElapsedTime); + + Log("Finished RecordRoute"); + } + } + catch (RpcException e) + { + Log("RPC failed", e); + throw e; + } + } + + /// + /// Bi-directional streaming example. Send some chat messages, and print any + /// chat messages that are sent from the server. + /// + public async Task RouteChat() + { + try + { + Log("*** RouteChat"); + var requests = + new List { NewNote("First message", 0, 0), NewNote("Second message", 0, 1), NewNote("Third message", 1, 0), NewNote("Fourth message", 1, 1) }; + + using (var call = client.RouteChat()) + { + var responseReaderTask = Task.Run(async () => + { + while (await call.ResponseStream.MoveNext()) + { + var note = call.ResponseStream.Current; + Log("Got message \"{0}\" at {1}, {2}", note.Message, + note.Location.Latitude, note.Location.Longitude); + } + }); + + foreach (RouteNote request in requests) + { + Log("Sending message \"{0}\" at {1}, {2}", request.Message, + request.Location.Latitude, request.Location.Longitude); + + await call.RequestStream.WriteAsync(request); + } + await call.RequestStream.CompleteAsync(); + await responseReaderTask; + + Log("Finished RouteChat"); + } + } + catch (RpcException e) + { + Log("RPC failed", e); + throw e; + } + } + + private void Log(string s, params object[] args) + { + Console.WriteLine(string.Format(s, args)); + } + + private void Log(string s) + { + Console.WriteLine(s); + } + + private RouteNote NewNote(string message, int lat, int lon) + { + return RouteNote.CreateBuilder().SetMessage(message).SetLocation( + Point.CreateBuilder().SetLatitude(lat).SetLongitude(lat).Build()).Build(); + } + } + + static void Main(string[] args) + { + GrpcEnvironment.Initialize(); + + using (Channel channel = new Channel("127.0.0.1:50052")) + { + var client = new RouteGuideClient(RouteGuide.NewStub(channel)); + + // Looking for a valid feature + client.GetFeature(409146138, -746188906); + + // Feature missing. + client.GetFeature(0, 0); + + // Looking for features between 40, -75 and 42, -73. + client.ListFeatures(400000000, -750000000, 420000000, -730000000).Wait(); + + // Record a few randomly selected points from the features file. + client.RecordRoute(RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile), 10).Wait(); + + // Send and receive some notes. + client.RouteChat().Wait(); + } + + GrpcEnvironment.Shutdown(); + } + } +} diff --git a/examples/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs b/examples/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..a17e164a78 --- /dev/null +++ b/examples/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RouteGuideClient")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RouteGuideClient")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("914644eb-47cd-4a37-9fba-5e62dd432333")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj b/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj new file mode 100644 index 0000000000..78034a9145 --- /dev/null +++ b/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj @@ -0,0 +1,100 @@ + + + + + + + + Debug + AnyCPU + {D47BE663-4DE3-4206-B7A8-EA3FA066DADC} + Exe + Properties + RouteGuideClient + RouteGuideClient + v4.5 + 512 + 794416d0 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll + + + False + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll + + + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + + ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll + + + + + + + + + + + + + + + + + + {49954d9c-5f17-4662-96b2-73be833dd81a} + RouteGuide + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/route_guide/RouteGuideClient/packages.config b/examples/csharp/route_guide/RouteGuideClient/packages.config new file mode 100644 index 0000000000..5922553bc3 --- /dev/null +++ b/examples/csharp/route_guide/RouteGuideClient/packages.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/route_guide/RouteGuideServer/App.config b/examples/csharp/route_guide/RouteGuideServer/App.config new file mode 100644 index 0000000000..8e15646352 --- /dev/null +++ b/examples/csharp/route_guide/RouteGuideServer/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/examples/csharp/route_guide/RouteGuideServer/Program.cs b/examples/csharp/route_guide/RouteGuideServer/Program.cs new file mode 100644 index 0000000000..e00b4d6723 --- /dev/null +++ b/examples/csharp/route_guide/RouteGuideServer/Program.cs @@ -0,0 +1,30 @@ +using Grpc.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace examples +{ + class Program + { + static void Main(string[] args) + { + var features = RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile); + GrpcEnvironment.Initialize(); + + Server server = new Server(); + server.AddServiceDefinition(RouteGuide.BindService(new RouteGuideImpl(features))); + int port = server.AddListeningPort("localhost", 50052); + server.Start(); + + Console.WriteLine("RouteGuide server listening on port " + port); + Console.WriteLine("Press any key to stop the server..."); + Console.ReadKey(); + + server.ShutdownAsync().Wait(); + GrpcEnvironment.Shutdown(); + } + } +} diff --git a/examples/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs b/examples/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..a161b1d602 --- /dev/null +++ b/examples/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RouteGuideServer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RouteGuideServer")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("908bdeef-05cc-42bf-9498-c4c573df8925")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/examples/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs b/examples/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs new file mode 100644 index 0000000000..0bdf386fc3 --- /dev/null +++ b/examples/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs @@ -0,0 +1,184 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace examples +{ + /// + /// Example implementation of RouteGuide server. + /// + public class RouteGuideImpl : RouteGuide.IRouteGuide + { + readonly List features; + private readonly ConcurrentDictionary> routeNotes = + new ConcurrentDictionary>(); + + public RouteGuideImpl(List features) + { + this.features = features; + } + + /// + /// Gets the feature at the requested point. If no feature at that location + /// exists, an unnammed feature is returned at the provided location. + /// + public Task GetFeature(Grpc.Core.ServerCallContext context, Point request) + { + return Task.FromResult(CheckFeature(request)); + } + + /// + /// Gets all features contained within the given bounding rectangle. + /// + public async Task ListFeatures(Grpc.Core.ServerCallContext context, Rectangle request, Grpc.Core.IServerStreamWriter responseStream) + { + int left = Math.Min(request.Lo.Longitude, request.Hi.Longitude); + int right = Math.Max(request.Lo.Longitude, request.Hi.Longitude); + int top = Math.Max(request.Lo.Latitude, request.Hi.Latitude); + int bottom = Math.Min(request.Lo.Latitude, request.Hi.Latitude); + + foreach (var feature in features) + { + if (!RouteGuideUtil.Exists(feature)) + { + continue; + } + + int lat = feature.Location.Latitude; + int lon = feature.Location.Longitude; + if (lon >= left && lon <= right && lat >= bottom && lat <= top) + { + await responseStream.WriteAsync(feature); + } + } + } + + /// + /// Gets a stream of points, and responds with statistics about the "trip": number of points, + /// number of known features visited, total distance traveled, and total time spent. + /// + public async Task RecordRoute(Grpc.Core.ServerCallContext context, Grpc.Core.IAsyncStreamReader requestStream) + { + int pointCount = 0; + int featureCount = 0; + int distance = 0; + Point previous = null; + var stopwatch = new Stopwatch(); + stopwatch.Start(); + + while (await requestStream.MoveNext()) + { + var point = requestStream.Current; + pointCount++; + if (RouteGuideUtil.Exists(CheckFeature(point))) + { + featureCount++; + } + if (previous != null) + { + distance += (int) CalcDistance(previous, point); + } + previous = point; + } + + stopwatch.Stop(); + return RouteSummary.CreateBuilder().SetPointCount(pointCount) + .SetFeatureCount(featureCount).SetDistance(distance) + .SetElapsedTime((int) (stopwatch.ElapsedMilliseconds / 1000)).Build(); + } + + /// + /// Receives a stream of message/location pairs, and responds with a stream of all previous + /// messages at each of those locations. + /// + public async Task RouteChat(Grpc.Core.ServerCallContext context, Grpc.Core.IAsyncStreamReader requestStream, Grpc.Core.IServerStreamWriter responseStream) + { + while (await requestStream.MoveNext()) + { + var note = requestStream.Current; + List notes = GetOrCreateNotes(note.Location); + + List prevNotes; + lock (notes) + { + prevNotes = new List(notes); + } + + foreach (var prevNote in prevNotes) + { + await responseStream.WriteAsync(prevNote); + } + + lock (notes) + { + notes.Add(note); + } + } + } + + + /// + /// Get the notes list for the given location. If missing, create it. + /// + private List GetOrCreateNotes(Point location) + { + List notes = new List(); + routeNotes.TryAdd(location, notes); + return routeNotes[location]; + } + + /// + /// Gets the feature at the given point. + /// + /// the location to check + /// The feature object at the point Note that an empty name indicates no feature. + private Feature CheckFeature(Point location) + { + foreach (var feature in features) + { + if (feature.Location.Latitude == location.Latitude + && feature.Location.Longitude == location.Longitude) + { + return feature; + } + } + + // No feature was found, return an unnamed feature. + return Feature.CreateBuilder().SetName("").SetLocation(location).Build(); + } + + /// + /// Calculate the distance between two points using the "haversine" formula. + /// This code was taken from http://www.movable-type.co.uk/scripts/latlong.html. + /// + /// the starting point + /// the end point + /// the distance between the points in meters + private static double CalcDistance(Point start, Point end) + { + double lat1 = RouteGuideUtil.GetLatitude(start); + double lat2 = RouteGuideUtil.GetLatitude(end); + double lon1 = RouteGuideUtil.GetLongitude(start); + double lon2 = RouteGuideUtil.GetLongitude(end); + int r = 6371000; // metres + double φ1 = ToRadians(lat1); + double φ2 = ToRadians(lat2); + double Δφ = ToRadians(lat2 - lat1); + double Δλ = ToRadians(lon2 - lon1); + + double a = Math.Sin(Δφ / 2) * Math.Sin(Δφ / 2) + Math.Cos(φ1) * Math.Cos(φ2) * Math.Sin(Δλ / 2) * Math.Sin(Δλ / 2); + double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); + + return r * c; + } + + private static double ToRadians(double val) + { + return (Math.PI / 180) * val; + } + } +} diff --git a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj new file mode 100644 index 0000000000..9ac1cfbf4d --- /dev/null +++ b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj @@ -0,0 +1,101 @@ + + + + + + + + Debug + AnyCPU + {4B7C7794-BE24-4477-ACE7-18259EB73D27} + Exe + Properties + RouteGuideServer + RouteGuideServer + v4.5 + 512 + 74781d8b + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll + + + False + ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll + + + + False + ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + + ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll + + + + + + + + + + + + + + + + + + + {49954d9c-5f17-4662-96b2-73be833dd81a} + RouteGuide + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/route_guide/RouteGuideServer/packages.config b/examples/csharp/route_guide/RouteGuideServer/packages.config new file mode 100644 index 0000000000..5922553bc3 --- /dev/null +++ b/examples/csharp/route_guide/RouteGuideServer/packages.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/examples/node/.gitignore b/examples/node/.gitignore new file mode 100644 index 0000000000..3d06f5db7b --- /dev/null +++ b/examples/node/.gitignore @@ -0,0 +1,3 @@ +*~ +node_modules +npm-debug.log \ No newline at end of file diff --git a/examples/node/README.md b/examples/node/README.md new file mode 100644 index 0000000000..8c24a960a3 --- /dev/null +++ b/examples/node/README.md @@ -0,0 +1,60 @@ +gRPC in 3 minutes (Node.js) +=========================== + +PREREQUISITES +------------- + +- `node`: This requires Node 10.x or greater. +- [homebrew][] on Mac OS X, [linuxbrew][] on Linux. These simplify the installation of the gRPC C core. + +INSTALL +------- + - On Mac OS X, install [homebrew][]. On Linux, install [linuxbrew][]. Run the following command to install gRPC Node.js. + + ```sh + $ curl -fsSL https://goo.gl/getgrpc | bash -s nodejs + ``` + This will download and run the [gRPC install script][], then install the latest version of gRPC Nodejs npm package. + - Clone this repository + + ```sh + $ git clone https://github.com/grpc/grpc-common.git + ``` + + - Install this package's dependencies + + ```sh + $ cd grpc-common/node + $ npm install + ``` + +TRY IT! +------- + + - Run the server + + ```sh + $ # from this directory (grpc_common/node). + $ node ./greeter_server.js & + ``` + + - Run the client + + ```sh + $ # from this directory + $ node ./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. + +TUTORIAL +-------- +You can find a more detailed tutorial in [gRPC Basics: Node.js][] + +[homebrew]:http://brew.sh +[linuxbrew]:https://github.com/Homebrew/linuxbrew#installation +[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install +[gRPC Basics: Node.js]:https://github.com/grpc/grpc-common/blob/master/node/route_guide/README.md diff --git a/examples/node/greeter_client.js b/examples/node/greeter_client.js new file mode 100644 index 0000000000..ab7050ab21 --- /dev/null +++ b/examples/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/examples/node/greeter_server.js b/examples/node/greeter_server.js new file mode 100644 index 0000000000..2fb95f0f90 --- /dev/null +++ b/examples/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/examples/node/helloworld.proto b/examples/node/helloworld.proto new file mode 100644 index 0000000000..a52c947f89 --- /dev/null +++ b/examples/node/helloworld.proto @@ -0,0 +1,50 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "ex.grpc"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + optional string name = 1; +} + +// The response message containing the greetings +message HelloReply { + optional string message = 1; +} diff --git a/examples/node/package.json b/examples/node/package.json new file mode 100644 index 0000000000..caf539518f --- /dev/null +++ b/examples/node/package.json @@ -0,0 +1,10 @@ +{ + "name": "grpc-demo", + "version": "0.5.0", + "dependencies": { + "async": "^0.9.0", + "grpc": "~0.9.0", + "minimist": "^1.1.0", + "underscore": "^1.8.2" + } +} diff --git a/examples/node/route_guide/README.md b/examples/node/route_guide/README.md new file mode 100644 index 0000000000..5460c9905d --- /dev/null +++ b/examples/node/route_guide/README.md @@ -0,0 +1,362 @@ +#gRPC Basics: Node.js + +This tutorial provides a basic Node.js programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Use the Node.js gRPC API to write a simple client and server for your service. + +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. + +This isn't a comprehensive guide to using gRPC in Node.js: more reference documentation is coming soon. + +## Why use gRPC? + +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/node/route_guide](https://github.com/grpc/grpc-common/tree/master/node/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/node/route_guide`: +```shell +$ cd grpc-common/node/route_guide +``` + +You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Node.js quick start guide](https://github.com/grpc/grpc-common/tree/master/node). + + +## Defining the service + +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +```protobuf +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +```protobuf + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. +```protobuf + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} +``` + +- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. +```protobuf + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +```protobuf + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +```protobuf +// 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; +} +``` + + +## Loading service descriptors from proto files + +The Node.js library dynamically generates service descriptors and client stub definitions from `.proto` files loaded at runtime. + +To load a `.proto` file, simply `require` the gRPC library, then use its `load()` method: + +```node +var grpc = require('grpc'); +var protoDescriptor = grpc.load(__dirname + '/route_guide.proto'); +// The protoDescriptor object has the full package hierarchy +var example = protoDescriptor.examples; +``` + +Once you've done this, the stub constructor is in the `examples` namespace (`protoDescriptor.examples.RouteGuide`) and the service descriptor (which is used to create a server) is a property of the stub (`protoDescriptor.examples.RouteGuide.service`); + + +## Creating the server + +First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). + +There are two parts to making our `RouteGuide` service do its job: +- Implementing the service interface generated from our service definition: doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and return the service responses. + +You can find our example `RouteGuide` server in [grpc-common/node/route_guide/route_guide_server.js](https://github.com/grpc/grpc-common/blob/master/node/route_guide/route_guide_server.js). Let's take a closer look at how it works. + +### Implementing RouteGuide + +As you can see, our server has a `Server` constructor generated from the `RouteGuide.service` descriptor object + +```node +var Server = grpc.buildServer([examples.RouteGuide.service]); +``` +In this case we're implementing the *asynchronous* version of `RouteGuide`, which provides our default gRPC server behaviour. + +The functions in `route_guide_server.js` implement all our service methods. Let's look at the simplest type first, `getFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. + +```node +function checkFeature(point) { + var feature; + // Check if there is already a feature object for the given point + for (var i = 0; i < feature_list.length; i++) { + feature = feature_list[i]; + if (feature.location.latitude === point.latitude && + feature.location.longitude === point.longitude) { + return feature; + } + } + var name = ''; + feature = { + name: name, + location: point + }; + return feature; +} +function getFeature(call, callback) { + callback(null, checkFeature(call.request)); +} +``` + +The method is passed a call object for the RPC, which has the `Point` parameter as a property, and a callback to which we can pass our returned `Feature`. In the method body we populate a `Feature` corresponding to the given point and pass it to the callback, with a null first parameter to indicate that there is no error. + +Now let's look at something a bit more complicated - a streaming RPC. `listFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. + +```node +function listFeatures(call) { + var lo = call.request.lo; + var hi = call.request.hi; + var left = _.min([lo.longitude, hi.longitude]); + var right = _.max([lo.longitude, hi.longitude]); + var top = _.max([lo.latitude, hi.latitude]); + var bottom = _.min([lo.latitude, hi.latitude]); + // For each feature, check if it is in the given bounding box + _.each(feature_list, function(feature) { + if (feature.name === '') { + return; + } + if (feature.location.longitude >= left && + feature.location.longitude <= right && + feature.location.latitude >= bottom && + feature.location.latitude <= top) { + call.write(feature); + } + }); + call.end(); +} +``` + +As you can see, instead of getting the call object and callback in our method parameters, this time we get a `call` object that implements the `Writable` interface. In the method, we create as many `Feature` objects as we need to return, writing them to the `call` using its `write()` method. Finally, we call `call.end()` to indicate that we have sent all messages. + +If you look at the client-side streaming method `RecordRoute` you'll see it's quite similar to the unary call, except this time the `call` parameter implements the `Reader` interface. The `call`'s `'data'` event fires every time there is new data, and the `'end'` event fires when all data has been read. Like the unary case, we respond by calling the callback + +```node +call.on('data', function(point) { + // Process user data +}); +call.on('end', function() { + callback(null, result); +}); +``` + +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. + +```node +function routeChat(call) { + call.on('data', function(note) { + var key = pointKey(note.location); + /* For each note sent, respond with all previous notes that correspond to + * the same point */ + if (route_notes.hasOwnProperty(key)) { + _.each(route_notes[key], function(note) { + call.write(note); + }); + } else { + route_notes[key] = []; + } + // Then add the new note to the list + route_notes[key].push(JSON.parse(JSON.stringify(note))); + }); + call.on('end', function() { + call.end(); + }); +} +``` + +This time we get a `call` implementing `Duplex` that can be used to read *and* write messages. The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + +### Starting the server + +Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: + +```node +function getServer() { + return new Server({ + 'examples.RouteGuide' : { + getFeature: getFeature, + listFeatures: listFeatures, + recordRoute: recordRoute, + routeChat: routeChat + } + }); +} +var routeServer = getServer(); +routeServer.bind('0.0.0.0:50051'); +routeServer.listen(); +``` + +As you can see, we build and start our server with the following steps: + + 1. Create a `Server` constructor from the `RouteGuide` service descriptor. + 2. Implement the service methods. + 3. Create an instance of the server by calling the `Server` constructor with the method implementations. + 4. Specify the address and port we want to use to listen for client requests using the instance's `bind()` method. + 5. Call `listen()` on the instance to start the RPC server. + + +## Creating the client + +In this section, we'll look at creating a Node.js client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/node/route_guide/route_guide_client.js](https://github.com/grpc/grpc-common/blob/master/node/route_guide/route_guide_client.js). + +### Creating a stub + +To call service methods, we first need to create a *stub*. To do this, we just need to call the RouteGuide stub constructor, specifying the server address and port. + +```node +new example.RouteGuide('localhost:50051'); +``` + +### Calling service methods + +Now let's look at how we call our service methods. Note that all of these methods are asynchronous: they use either events or callbacks to retrieve results. + +#### Simple RPC + +Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local asynchronous method. + +```node +var point = {latitude: 409146138, longitude: -746188906}; +stub.getFeature(point, function(err, feature) { + if (err) { + // process error + } else { + // process feature + } +}); +``` + +As you can see, we create and populate a request object. Finally, we call the method on the stub, passing it the request and callback. If there is no error, then we can read the response information from the server from our response object. + +```node + console.log('Found feature called "' + feature.name + '" at ' + + feature.location.latitude/COORD_FACTOR + ', ' + + feature.location.longitude/COORD_FACTOR); +``` + +#### Streaming RPCs + +Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: + +```node +var call = client.listFeatures(rectangle); + call.on('data', function(feature) { + console.log('Found feature called "' + feature.name + '" at ' + + feature.location.latitude/COORD_FACTOR + ', ' + + feature.location.longitude/COORD_FACTOR); + }); + call.on('end', function() { + // The server has finished sending + }); + call.on('status', function(status) { + // process status + }); +``` + +Instead of passing the method a request and callback, we pass it a request and get a `Readable` stream object back. The client can use the `Readable`'s `'data'` event to read the server's responses. This event fires with each `Feature` message object until there are no more messages: the `'end'` event indicates that the call is done. Finally, the status event fires when the server sends the status. + +The client-side streaming method `RecordRoute` is similar, except there we pass the method a callback and get back a `Writable`. + +```node + var call = client.recordRoute(function(error, stats) { + if (error) { + callback(error); + } + console.log('Finished trip with', stats.point_count, 'points'); + console.log('Passed', stats.feature_count, 'features'); + console.log('Travelled', stats.distance, 'meters'); + console.log('It took', stats.elapsed_time, 'seconds'); + }); + function pointSender(lat, lng) { + return function(callback) { + console.log('Visiting point ' + lat/COORD_FACTOR + ', ' + + lng/COORD_FACTOR); + call.write({ + latitude: lat, + longitude: lng + }); + _.delay(callback, _.random(500, 1500)); + }; + } + var point_senders = []; + for (var i = 0; i < num_points; i++) { + var rand_point = feature_list[_.random(0, feature_list.length - 1)]; + point_senders[i] = pointSender(rand_point.location.latitude, + rand_point.location.longitude); + } + async.series(point_senders, function() { + call.end(); + }); +``` + +Once we've finished writing our client's requests to the stream using `write()`, we need to call `end()` on the stream to let gRPC know that we've finished writing. If the status is `OK`, the `stats` object will be populated with the server's response. + +Finally, let's look at our bidirectional streaming RPC `routeChat()`. In this case, we just pass a context to the method and get back a `Duplex` stream object, which we can use to both write and read messages. + +```node +var call = client.routeChat(); +``` + +The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + +## Try it out! + +Build client and server: +```shell +$ npm install +``` +Run the server, which will listen on port 50051: +```shell +$ node ./route_guide_server.js --db_path=route_guide_db.json +``` +Run the client (in a different terminal): +```shell +$ node ./route_guide_client.js --db_path=route_guide_db.json +``` diff --git a/examples/node/route_guide/route_guide.proto b/examples/node/route_guide/route_guide.proto new file mode 100644 index 0000000000..442112823e --- /dev/null +++ b/examples/node/route_guide/route_guide.proto @@ -0,0 +1,120 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "io.grpc.examples"; + +package examples; + +// Interface exported by the server. +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} + + // A server-to-client streaming RPC. + // + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} + + // A client-to-server streaming RPC. + // + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} + + // A Bidirectional streaming RPC. + // + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +} + +// Points are represented as latitude-longitude pairs in the E7 representation +// (degrees multiplied by 10**7 and rounded to the nearest integer). +// Latitudes should be in the range +/- 90 degrees and longitude should be in +// the range +/- 180 degrees (inclusive). +message Point { + optional int32 latitude = 1; + optional int32 longitude = 2; +} + +// A latitude-longitude rectangle, represented as two diagonally opposite +// points "lo" and "hi". +message Rectangle { + // One corner of the rectangle. + optional Point lo = 1; + + // The other corner of the rectangle. + optional Point hi = 2; +} + +// A feature names something at a given point. +// +// If a feature could not be named, the name is empty. +message Feature { + // The name of the feature. + optional string name = 1; + + // The point where the feature is detected. + optional Point location = 2; +} + +// A RouteNote is a message sent while at a given point. +message RouteNote { + // The location from which the message is sent. + optional Point location = 1; + + // The message to be sent. + optional string message = 2; +} + +// A RouteSummary is received in response to a RecordRoute rpc. +// +// It contains the number of individual points received, the number of +// detected features, and the total distance covered as the cumulative sum of +// the distance between each point. +message RouteSummary { + // The number of points received. + optional int32 point_count = 1; + + // The number of known features passed while traversing the route. + optional int32 feature_count = 2; + + // The distance covered in metres. + optional int32 distance = 3; + + // The duration of the traversal in seconds. + optional int32 elapsed_time = 4; +} diff --git a/examples/node/route_guide/route_guide_client.js b/examples/node/route_guide/route_guide_client.js new file mode 100644 index 0000000000..60c47a429d --- /dev/null +++ b/examples/node/route_guide/route_guide_client.js @@ -0,0 +1,231 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +var async = require('async'); +var fs = require('fs'); +var parseArgs = require('minimist'); +var path = require('path'); +var _ = require('underscore'); +var grpc = require('grpc'); +var examples = grpc.load(__dirname + '/route_guide.proto').examples; +var client = new examples.RouteGuide('localhost:50051'); + +var COORD_FACTOR = 1e7; + +/** + * Run the getFeature demo. Calls getFeature with a point known to have a + * feature and a point known not to have a feature. + * @param {function} callback Called when this demo is complete + */ +function runGetFeature(callback) { + var next = _.after(2, callback); + function featureCallback(error, feature) { + if (error) { + callback(error); + } + if (feature.name === '') { + console.log('Found no feature at ' + + feature.location.latitude/COORD_FACTOR + ', ' + + feature.location.longitude/COORD_FACTOR); + } else { + console.log('Found feature called "' + feature.name + '" at ' + + feature.location.latitude/COORD_FACTOR + ', ' + + feature.location.longitude/COORD_FACTOR); + } + next(); + } + var point1 = { + latitude: 409146138, + longitude: -746188906 + }; + var point2 = { + latitude: 0, + longitude: 0 + }; + client.getFeature(point1, featureCallback); + client.getFeature(point2, featureCallback); +} + +/** + * Run the listFeatures demo. Calls listFeatures with a rectangle containing all + * of the features in the pre-generated database. Prints each response as it + * comes in. + * @param {function} callback Called when this demo is complete + */ +function runListFeatures(callback) { + var rectangle = { + lo: { + latitude: 400000000, + longitude: -750000000 + }, + hi: { + latitude: 420000000, + longitude: -730000000 + } + }; + console.log('Looking for features between 40, -75 and 42, -73'); + var call = client.listFeatures(rectangle); + call.on('data', function(feature) { + console.log('Found feature called "' + feature.name + '" at ' + + feature.location.latitude/COORD_FACTOR + ', ' + + feature.location.longitude/COORD_FACTOR); + }); + call.on('end', callback); +} + +/** + * Run the recordRoute demo. Sends several randomly chosen points from the + * pre-generated feature database with a variable delay in between. Prints the + * statistics when they are sent from the server. + * @param {function} callback Called when this demo is complete + */ +function runRecordRoute(callback) { + var argv = parseArgs(process.argv, { + string: 'db_path' + }); + fs.readFile(path.resolve(argv.db_path), function(err, data) { + if (err) callback(err); + var feature_list = JSON.parse(data); + + var num_points = 10; + var call = client.recordRoute(function(error, stats) { + if (error) { + callback(error); + } + console.log('Finished trip with', stats.point_count, 'points'); + console.log('Passed', stats.feature_count, 'features'); + console.log('Travelled', stats.distance, 'meters'); + console.log('It took', stats.elapsed_time, 'seconds'); + callback(); + }); + /** + * Constructs a function that asynchronously sends the given point and then + * delays sending its callback + * @param {number} lat The latitude to send + * @param {number} lng The longitude to send + * @return {function(function)} The function that sends the point + */ + function pointSender(lat, lng) { + /** + * Sends the point, then calls the callback after a delay + * @param {function} callback Called when complete + */ + return function(callback) { + console.log('Visiting point ' + lat/COORD_FACTOR + ', ' + + lng/COORD_FACTOR); + call.write({ + latitude: lat, + longitude: lng + }); + _.delay(callback, _.random(500, 1500)); + }; + } + var point_senders = []; + for (var i = 0; i < num_points; i++) { + var rand_point = feature_list[_.random(0, feature_list.length - 1)]; + point_senders[i] = pointSender(rand_point.location.latitude, + rand_point.location.longitude); + } + async.series(point_senders, function() { + call.end(); + }); + }); +} + +/** + * Run the routeChat demo. Send some chat messages, and print any chat messages + * that are sent from the server. + * @param {function} callback Called when the demo is complete + */ +function runRouteChat(callback) { + var call = client.routeChat(); + call.on('data', function(note) { + console.log('Got message "' + note.message + '" at ' + + note.location.latitude + ', ' + note.location.longitude); + }); + + call.on('end', callback); + + var notes = [{ + location: { + latitude: 0, + longitude: 0 + }, + message: 'First message' + }, { + location: { + latitude: 0, + longitude: 1 + }, + message: 'Second message' + }, { + location: { + latitude: 1, + longitude: 0 + }, + message: 'Third message' + }, { + location: { + latitude: 0, + longitude: 0 + }, + message: 'Fourth message' + }]; + for (var i = 0; i < notes.length; i++) { + var note = notes[i]; + console.log('Sending message "' + note.message + '" at ' + + note.location.latitude + ', ' + note.location.longitude); + call.write(note); + } + call.end(); +} + +/** + * Run all of the demos in order + */ +function main() { + async.series([ + runGetFeature, + runListFeatures, + runRecordRoute, + runRouteChat + ]); +} + +if (require.main === module) { + main(); +} + +exports.runGetFeature = runGetFeature; + +exports.runListFeatures = runListFeatures; + +exports.runRecordRoute = runRecordRoute; + +exports.runRouteChat = runRouteChat; diff --git a/examples/node/route_guide/route_guide_db.json b/examples/node/route_guide/route_guide_db.json new file mode 100644 index 0000000000..9d6a980ab7 --- /dev/null +++ b/examples/node/route_guide/route_guide_db.json @@ -0,0 +1,601 @@ +[{ + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" +}, { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" +}, { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" +}, { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" +}, { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" +}, { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" +}, { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" +}, { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" +}, { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" +}, { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" +}, { + "location": { + "latitude": 415736605, + "longitude": -742847522 + }, + "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" +}, { + "location": { + "latitude": 413843930, + "longitude": -740501726 + }, + "name": "162 Merrill Road, Highland Mills, NY 10930, USA" +}, { + "location": { + "latitude": 410873075, + "longitude": -744459023 + }, + "name": "Clinton Road, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 412346009, + "longitude": -744026814 + }, + "name": "16 Old Brook Lane, Warwick, NY 10990, USA" +}, { + "location": { + "latitude": 402948455, + "longitude": -747903913 + }, + "name": "3 Drake Lane, Pennington, NJ 08534, USA" +}, { + "location": { + "latitude": 406337092, + "longitude": -740122226 + }, + "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" +}, { + "location": { + "latitude": 406421967, + "longitude": -747727624 + }, + "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" +}, { + "location": { + "latitude": 416318082, + "longitude": -749677716 + }, + "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" +}, { + "location": { + "latitude": 415301720, + "longitude": -748416257 + }, + "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" +}, { + "location": { + "latitude": 402647019, + "longitude": -747071791 + }, + "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" +}, { + "location": { + "latitude": 412567807, + "longitude": -741058078 + }, + "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" +}, { + "location": { + "latitude": 416855156, + "longitude": -744420597 + }, + "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" +}, { + "location": { + "latitude": 404663628, + "longitude": -744820157 + }, + "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" +}, { + "location": { + "latitude": 407113723, + "longitude": -749746483 + }, + "name": "" +}, { + "location": { + "latitude": 402133926, + "longitude": -743613249 + }, + "name": "" +}, { + "location": { + "latitude": 400273442, + "longitude": -741220915 + }, + "name": "" +}, { + "location": { + "latitude": 411236786, + "longitude": -744070769 + }, + "name": "" +}, { + "location": { + "latitude": 411633782, + "longitude": -746784970 + }, + "name": "211-225 Plains Road, Augusta, NJ 07822, USA" +}, { + "location": { + "latitude": 415830701, + "longitude": -742952812 + }, + "name": "" +}, { + "location": { + "latitude": 413447164, + "longitude": -748712898 + }, + "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" +}, { + "location": { + "latitude": 405047245, + "longitude": -749800722 + }, + "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" +}, { + "location": { + "latitude": 418858923, + "longitude": -746156790 + }, + "name": "" +}, { + "location": { + "latitude": 417951888, + "longitude": -748484944 + }, + "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" +}, { + "location": { + "latitude": 407033786, + "longitude": -743977337 + }, + "name": "26 East 3rd Street, New Providence, NJ 07974, USA" +}, { + "location": { + "latitude": 417548014, + "longitude": -740075041 + }, + "name": "" +}, { + "location": { + "latitude": 410395868, + "longitude": -744972325 + }, + "name": "" +}, { + "location": { + "latitude": 404615353, + "longitude": -745129803 + }, + "name": "" +}, { + "location": { + "latitude": 406589790, + "longitude": -743560121 + }, + "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" +}, { + "location": { + "latitude": 414653148, + "longitude": -740477477 + }, + "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" +}, { + "location": { + "latitude": 405957808, + "longitude": -743255336 + }, + "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" +}, { + "location": { + "latitude": 411733589, + "longitude": -741648093 + }, + "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" +}, { + "location": { + "latitude": 412676291, + "longitude": -742606606 + }, + "name": "1270 Lakes Road, Monroe, NY 10950, USA" +}, { + "location": { + "latitude": 409224445, + "longitude": -748286738 + }, + "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" +}, { + "location": { + "latitude": 406523420, + "longitude": -742135517 + }, + "name": "652 Garden Street, Elizabeth, NJ 07202, USA" +}, { + "location": { + "latitude": 401827388, + "longitude": -740294537 + }, + "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" +}, { + "location": { + "latitude": 410564152, + "longitude": -743685054 + }, + "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 408472324, + "longitude": -740726046 + }, + "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" +}, { + "location": { + "latitude": 412452168, + "longitude": -740214052 + }, + "name": "5 White Oak Lane, Stony Point, NY 10980, USA" +}, { + "location": { + "latitude": 409146138, + "longitude": -746188906 + }, + "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" +}, { + "location": { + "latitude": 404701380, + "longitude": -744781745 + }, + "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 409642566, + "longitude": -746017679 + }, + "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" +}, { + "location": { + "latitude": 408031728, + "longitude": -748645385 + }, + "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" +}, { + "location": { + "latitude": 413700272, + "longitude": -742135189 + }, + "name": "367 Prospect Road, Chester, NY 10918, USA" +}, { + "location": { + "latitude": 404310607, + "longitude": -740282632 + }, + "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" +}, { + "location": { + "latitude": 409319800, + "longitude": -746201391 + }, + "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" +}, { + "location": { + "latitude": 406685311, + "longitude": -742108603 + }, + "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" +}, { + "location": { + "latitude": 419018117, + "longitude": -749142781 + }, + "name": "43 Dreher Road, Roscoe, NY 12776, USA" +}, { + "location": { + "latitude": 412856162, + "longitude": -745148837 + }, + "name": "Swan Street, Pine Island, NY 10969, USA" +}, { + "location": { + "latitude": 416560744, + "longitude": -746721964 + }, + "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" +}, { + "location": { + "latitude": 405314270, + "longitude": -749836354 + }, + "name": "" +}, { + "location": { + "latitude": 414219548, + "longitude": -743327440 + }, + "name": "" +}, { + "location": { + "latitude": 415534177, + "longitude": -742900616 + }, + "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" +}, { + "location": { + "latitude": 406898530, + "longitude": -749127080 + }, + "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" +}, { + "location": { + "latitude": 407586880, + "longitude": -741670168 + }, + "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" +}, { + "location": { + "latitude": 400106455, + "longitude": -742870190 + }, + "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" +}, { + "location": { + "latitude": 400066188, + "longitude": -746793294 + }, + "name": "" +}, { + "location": { + "latitude": 418803880, + "longitude": -744102673 + }, + "name": "40 Mountain Road, Napanoch, NY 12458, USA" +}, { + "location": { + "latitude": 414204288, + "longitude": -747895140 + }, + "name": "" +}, { + "location": { + "latitude": 414777405, + "longitude": -740615601 + }, + "name": "" +}, { + "location": { + "latitude": 415464475, + "longitude": -747175374 + }, + "name": "48 North Road, Forestburgh, NY 12777, USA" +}, { + "location": { + "latitude": 404062378, + "longitude": -746376177 + }, + "name": "" +}, { + "location": { + "latitude": 405688272, + "longitude": -749285130 + }, + "name": "" +}, { + "location": { + "latitude": 400342070, + "longitude": -748788996 + }, + "name": "" +}, { + "location": { + "latitude": 401809022, + "longitude": -744157964 + }, + "name": "" +}, { + "location": { + "latitude": 404226644, + "longitude": -740517141 + }, + "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" +}, { + "location": { + "latitude": 410322033, + "longitude": -747871659 + }, + "name": "" +}, { + "location": { + "latitude": 407100674, + "longitude": -747742727 + }, + "name": "" +}, { + "location": { + "latitude": 418811433, + "longitude": -741718005 + }, + "name": "213 Bush Road, Stone Ridge, NY 12484, USA" +}, { + "location": { + "latitude": 415034302, + "longitude": -743850945 + }, + "name": "" +}, { + "location": { + "latitude": 411349992, + "longitude": -743694161 + }, + "name": "" +}, { + "location": { + "latitude": 404839914, + "longitude": -744759616 + }, + "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 414638017, + "longitude": -745957854 + }, + "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" +}, { + "location": { + "latitude": 412127800, + "longitude": -740173578 + }, + "name": "" +}, { + "location": { + "latitude": 401263460, + "longitude": -747964303 + }, + "name": "" +}, { + "location": { + "latitude": 412843391, + "longitude": -749086026 + }, + "name": "" +}, { + "location": { + "latitude": 418512773, + "longitude": -743067823 + }, + "name": "" +}, { + "location": { + "latitude": 404318328, + "longitude": -740835638 + }, + "name": "42-102 Main Street, Belford, NJ 07718, USA" +}, { + "location": { + "latitude": 419020746, + "longitude": -741172328 + }, + "name": "" +}, { + "location": { + "latitude": 404080723, + "longitude": -746119569 + }, + "name": "" +}, { + "location": { + "latitude": 401012643, + "longitude": -744035134 + }, + "name": "" +}, { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" +}, { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" +}, { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" +}, { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" +}, { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" +}, { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" +}, { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" +}, { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" +}, { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" +}, { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" +}] diff --git a/examples/node/route_guide/route_guide_server.js b/examples/node/route_guide/route_guide_server.js new file mode 100644 index 0000000000..5dd8412654 --- /dev/null +++ b/examples/node/route_guide/route_guide_server.js @@ -0,0 +1,249 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +var fs = require('fs'); +var parseArgs = require('minimist'); +var path = require('path'); +var _ = require('underscore'); +var grpc = require('grpc'); +var examples = grpc.load(__dirname + '/route_guide.proto').examples; + +var Server = grpc.buildServer([examples.RouteGuide.service]); + +var COORD_FACTOR = 1e7; + +/** + * For simplicity, a point is a record type that looks like + * {latitude: number, longitude: number}, and a feature is a record type that + * looks like {name: string, location: point}. feature objects with name==='' + * are points with no feature. + */ + +/** + * List of feature objects at points that have been requested so far. + */ +var feature_list = []; + +/** + * Get a feature object at the given point, or creates one if it does not exist. + * @param {point} point The point to check + * @return {feature} The feature object at the point. Note that an empty name + * indicates no feature + */ +function checkFeature(point) { + var feature; + // Check if there is already a feature object for the given point + for (var i = 0; i < feature_list.length; i++) { + feature = feature_list[i]; + if (feature.location.latitude === point.latitude && + feature.location.longitude === point.longitude) { + return feature; + } + } + var name = ''; + feature = { + name: name, + location: point + }; + return feature; +} + +/** + * getFeature request handler. Gets a request with a point, and responds with a + * feature object indicating whether there is a feature at that point. + * @param {EventEmitter} call Call object for the handler to process + * @param {function(Error, feature)} callback Response callback + */ +function getFeature(call, callback) { + callback(null, checkFeature(call.request)); +} + +/** + * listFeatures request handler. Gets a request with two points, and responds + * with a stream of all features in the bounding box defined by those points. + * @param {Writable} call Writable stream for responses with an additional + * request property for the request value. + */ +function listFeatures(call) { + var lo = call.request.lo; + var hi = call.request.hi; + var left = _.min([lo.longitude, hi.longitude]); + var right = _.max([lo.longitude, hi.longitude]); + var top = _.max([lo.latitude, hi.latitude]); + var bottom = _.min([lo.latitude, hi.latitude]); + // For each feature, check if it is in the given bounding box + _.each(feature_list, function(feature) { + if (feature.name === '') { + return; + } + if (feature.location.longitude >= left && + feature.location.longitude <= right && + feature.location.latitude >= bottom && + feature.location.latitude <= top) { + call.write(feature); + } + }); + call.end(); +} + +/** + * Calculate the distance between two points using the "haversine" formula. + * This code was taken from http://www.movable-type.co.uk/scripts/latlong.html. + * @param start The starting point + * @param end The end point + * @return The distance between the points in meters + */ +function getDistance(start, end) { + function toRadians(num) { + return num * Math.PI / 180; + } + var lat1 = start.latitude / COORD_FACTOR; + var lat2 = end.latitude / COORD_FACTOR; + var lon1 = start.longitude / COORD_FACTOR; + var lon2 = end.longitude / COORD_FACTOR; + var R = 6371000; // metres + var φ1 = toRadians(lat1); + var φ2 = toRadians(lat2); + var Δφ = toRadians(lat2-lat1); + var Δλ = toRadians(lon2-lon1); + + var a = Math.sin(Δφ/2) * Math.sin(Δφ/2) + + Math.cos(φ1) * Math.cos(φ2) * + Math.sin(Δλ/2) * Math.sin(Δλ/2); + var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); + + return R * c; +} + +/** + * recordRoute handler. Gets a stream of points, and responds with statistics + * about the "trip": number of points, number of known features visited, total + * distance traveled, and total time spent. + * @param {Readable} call The request point stream. + * @param {function(Error, routeSummary)} callback The callback to pass the + * response to + */ +function recordRoute(call, callback) { + var point_count = 0; + var feature_count = 0; + var distance = 0; + var previous = null; + // Start a timer + var start_time = process.hrtime(); + call.on('data', function(point) { + point_count += 1; + if (checkFeature(point).name !== '') { + feature_count += 1; + } + /* For each point after the first, add the incremental distance from the + * previous point to the total distance value */ + if (previous != null) { + distance += getDistance(previous, point); + } + previous = point; + }); + call.on('end', function() { + callback(null, { + point_count: point_count, + feature_count: feature_count, + // Cast the distance to an integer + distance: distance|0, + // End the timer + elapsed_time: process.hrtime(start_time)[0] + }); + }); +} + +var route_notes = {}; + +/** + * Turn the point into a dictionary key. + * @param {point} point The point to use + * @return {string} The key for an object + */ +function pointKey(point) { + return point.latitude + ' ' + point.longitude; +} + +/** + * routeChat handler. Receives a stream of message/location pairs, and responds + * with a stream of all previous messages at each of those locations. + * @param {Duplex} call The stream for incoming and outgoing messages + */ +function routeChat(call) { + call.on('data', function(note) { + var key = pointKey(note.location); + /* For each note sent, respond with all previous notes that correspond to + * the same point */ + if (route_notes.hasOwnProperty(key)) { + _.each(route_notes[key], function(note) { + call.write(note); + }); + } else { + route_notes[key] = []; + } + // Then add the new note to the list + route_notes[key].push(JSON.parse(JSON.stringify(note))); + }); + call.on('end', function() { + call.end(); + }); +} + +/** + * Get a new server with the handler functions in this file bound to the methods + * it serves. + * @return {Server} The new server object + */ +function getServer() { + return new Server({ + 'examples.RouteGuide' : { + getFeature: getFeature, + listFeatures: listFeatures, + recordRoute: recordRoute, + routeChat: routeChat + } + }); +} + +if (require.main === module) { + // If this is run as a script, start a server on an unused port + var routeServer = getServer(); + routeServer.bind('0.0.0.0:50051'); + var argv = parseArgs(process.argv, { + string: 'db_path' + }); + fs.readFile(path.resolve(argv.db_path), function(err, data) { + if (err) throw err; + feature_list = JSON.parse(data); + routeServer.listen(); + }); +} + +exports.getServer = getServer; diff --git a/examples/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj b/examples/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..51a39c578c --- /dev/null +++ b/examples/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj @@ -0,0 +1,366 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 63E1E9821B28CB2100EF0978 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9811B28CB2100EF0978 /* main.m */; }; + 63E1E9851B28CB2100EF0978 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9841B28CB2100EF0978 /* AppDelegate.m */; }; + 63E1E9881B28CB2100EF0978 /* SelectUserViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9871B28CB2100EF0978 /* SelectUserViewController.m */; }; + 63E1E98B1B28CB2100EF0978 /* MakeRPCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E98A1B28CB2100EF0978 /* MakeRPCViewController.m */; }; + 63E1E98E1B28CB2100EF0978 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 63E1E98C1B28CB2100EF0978 /* Main.storyboard */; }; + 63E1E9901B28CB2100EF0978 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 63E1E98F1B28CB2100EF0978 /* Images.xcassets */; }; + 63F5DE481B28F5C100CDD07E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */; }; + 832213142AB24DB816D02635 /* libPods-AuthSample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F217A6ECA7F5BD1D5FB5071B /* libPods-AuthSample.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 63E1E97C1B28CB2100EF0978 /* AuthSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AuthSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 63E1E9801B28CB2100EF0978 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 63E1E9811B28CB2100EF0978 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 63E1E9831B28CB2100EF0978 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 63E1E9841B28CB2100EF0978 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 63E1E9861B28CB2100EF0978 /* SelectUserViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SelectUserViewController.h; sourceTree = ""; }; + 63E1E9871B28CB2100EF0978 /* SelectUserViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SelectUserViewController.m; sourceTree = ""; }; + 63E1E9891B28CB2100EF0978 /* MakeRPCViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MakeRPCViewController.h; sourceTree = ""; }; + 63E1E98A1B28CB2100EF0978 /* MakeRPCViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MakeRPCViewController.m; sourceTree = ""; }; + 63E1E98D1B28CB2100EF0978 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 63E1E98F1B28CB2100EF0978 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + A387D6CECBCF2EAF2983033A /* Pods-AuthSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AuthSample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AuthSample/Pods-AuthSample.debug.xcconfig"; sourceTree = ""; }; + B444176735DA81FBE4B8B80C /* Pods-AuthSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AuthSample.release.xcconfig"; path = "Pods/Target Support Files/Pods-AuthSample/Pods-AuthSample.release.xcconfig"; sourceTree = ""; }; + F217A6ECA7F5BD1D5FB5071B /* libPods-AuthSample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AuthSample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 63E1E9791B28CB2000EF0978 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 832213142AB24DB816D02635 /* libPods-AuthSample.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 021FA0E0B3F5D3D477DDAC10 /* Pods */ = { + isa = PBXGroup; + children = ( + A387D6CECBCF2EAF2983033A /* Pods-AuthSample.debug.xcconfig */, + B444176735DA81FBE4B8B80C /* Pods-AuthSample.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 4F443572636F3D60F26E870D /* Frameworks */ = { + isa = PBXGroup; + children = ( + F217A6ECA7F5BD1D5FB5071B /* libPods-AuthSample.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + 63E1E9731B28CB2000EF0978 = { + isa = PBXGroup; + children = ( + 63E1E97E1B28CB2100EF0978 /* AuthSample */, + 63E1E97D1B28CB2100EF0978 /* Products */, + 021FA0E0B3F5D3D477DDAC10 /* Pods */, + 4F443572636F3D60F26E870D /* Frameworks */, + ); + sourceTree = ""; + }; + 63E1E97D1B28CB2100EF0978 /* Products */ = { + isa = PBXGroup; + children = ( + 63E1E97C1B28CB2100EF0978 /* AuthSample.app */, + ); + name = Products; + sourceTree = ""; + }; + 63E1E97E1B28CB2100EF0978 /* AuthSample */ = { + isa = PBXGroup; + children = ( + 63E1E9861B28CB2100EF0978 /* SelectUserViewController.h */, + 63E1E9871B28CB2100EF0978 /* SelectUserViewController.m */, + 63E1E9891B28CB2100EF0978 /* MakeRPCViewController.h */, + 63E1E98A1B28CB2100EF0978 /* MakeRPCViewController.m */, + 63E1E97F1B28CB2100EF0978 /* Supporting Files */, + ); + name = AuthSample; + sourceTree = SOURCE_ROOT; + }; + 63E1E97F1B28CB2100EF0978 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 63E1E98C1B28CB2100EF0978 /* Main.storyboard */, + 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */, + 63E1E98F1B28CB2100EF0978 /* Images.xcassets */, + 63E1E9801B28CB2100EF0978 /* Info.plist */, + 63E1E9831B28CB2100EF0978 /* AppDelegate.h */, + 63E1E9841B28CB2100EF0978 /* AppDelegate.m */, + 63E1E9811B28CB2100EF0978 /* main.m */, + ); + name = "Supporting Files"; + path = Misc; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 63E1E97B1B28CB2000EF0978 /* AuthSample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 63E1E9A21B28CB2100EF0978 /* Build configuration list for PBXNativeTarget "AuthSample" */; + buildPhases = ( + DAABBA7B5788A39108D7CA83 /* Check Pods Manifest.lock */, + 63E1E9781B28CB2000EF0978 /* Sources */, + 63E1E9791B28CB2000EF0978 /* Frameworks */, + 63E1E97A1B28CB2000EF0978 /* Resources */, + AEFCCC69DD59CE8F6EB769D7 /* Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AuthSample; + productName = AuthSample; + productReference = 63E1E97C1B28CB2100EF0978 /* AuthSample.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 63E1E9741B28CB2000EF0978 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = gRPC; + TargetAttributes = { + 63E1E97B1B28CB2000EF0978 = { + CreatedOnToolsVersion = 6.3.1; + }; + }; + }; + buildConfigurationList = 63E1E9771B28CB2000EF0978 /* Build configuration list for PBXProject "AuthSample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 63E1E9731B28CB2000EF0978; + productRefGroup = 63E1E97D1B28CB2100EF0978 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 63E1E97B1B28CB2000EF0978 /* AuthSample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 63E1E97A1B28CB2000EF0978 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 63E1E98E1B28CB2100EF0978 /* Main.storyboard in Resources */, + 63E1E9901B28CB2100EF0978 /* Images.xcassets in Resources */, + 63F5DE481B28F5C100CDD07E /* GoogleService-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + AEFCCC69DD59CE8F6EB769D7 /* Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AuthSample/Pods-AuthSample-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + DAABBA7B5788A39108D7CA83 /* Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 63E1E9781B28CB2000EF0978 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 63E1E98B1B28CB2100EF0978 /* MakeRPCViewController.m in Sources */, + 63E1E9851B28CB2100EF0978 /* AppDelegate.m in Sources */, + 63E1E9881B28CB2100EF0978 /* SelectUserViewController.m in Sources */, + 63E1E9821B28CB2100EF0978 /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 63E1E98C1B28CB2100EF0978 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 63E1E98D1B28CB2100EF0978 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 63E1E9A01B28CB2100EF0978 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 63E1E9A11B28CB2100EF0978 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 63E1E9A31B28CB2100EF0978 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A387D6CECBCF2EAF2983033A /* Pods-AuthSample.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = Misc/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 63E1E9A41B28CB2100EF0978 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B444176735DA81FBE4B8B80C /* Pods-AuthSample.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = Misc/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 63E1E9771B28CB2000EF0978 /* Build configuration list for PBXProject "AuthSample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 63E1E9A01B28CB2100EF0978 /* Debug */, + 63E1E9A11B28CB2100EF0978 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 63E1E9A21B28CB2100EF0978 /* Build configuration list for PBXNativeTarget "AuthSample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 63E1E9A31B28CB2100EF0978 /* Debug */, + 63E1E9A41B28CB2100EF0978 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 63E1E9741B28CB2000EF0978 /* Project object */; +} diff --git a/examples/objective-c/auth_sample/AuthSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/objective-c/auth_sample/AuthSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..39b57a4b33 --- /dev/null +++ b/examples/objective-c/auth_sample/AuthSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/examples/objective-c/auth_sample/AuthTestService.podspec b/examples/objective-c/auth_sample/AuthTestService.podspec new file mode 100644 index 0000000000..9f2a2cc361 --- /dev/null +++ b/examples/objective-c/auth_sample/AuthTestService.podspec @@ -0,0 +1,35 @@ +Pod::Spec.new do |s| + s.name = "AuthTestService" + s.version = "0.0.1" + s.license = "New BSD" + + s.ios.deployment_target = "6.0" + s.osx.deployment_target = "10.8" + + # Base directory where the .proto files are. + src = "../../protos" + + # Directory where the generated files will be place. + dir = "Pods/" + s.name + + # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. + s.prepare_command = <<-CMD + mkdir -p #{dir} + protoc -I #{src} --objc_out=#{dir} --objcgrpc_out=#{dir} #{src}/auth_sample.proto + CMD + + s.subspec "Messages" do |ms| + ms.source_files = "#{dir}/*.pbobjc.{h,m}", "#{dir}/**/*.pbobjc.{h,m}" + ms.header_mappings_dir = dir + ms.requires_arc = false + ms.dependency "Protobuf", "~> 3.0.0-alpha-3" + end + + s.subspec "Services" do |ss| + ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}" + ss.header_mappings_dir = dir + ss.requires_arc = true + ss.dependency "gRPC", "~> 0.6" + ss.dependency "#{s.name}/Messages" + end +end diff --git a/examples/objective-c/auth_sample/MakeRPCViewController.h b/examples/objective-c/auth_sample/MakeRPCViewController.h new file mode 100644 index 0000000000..c75a8b3180 --- /dev/null +++ b/examples/objective-c/auth_sample/MakeRPCViewController.h @@ -0,0 +1,40 @@ +/* + * + * 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. + * + */ + +#import + +extern NSString * const kTestScope; + +@interface MakeRPCViewController : UIViewController +@property(weak, nonatomic) IBOutlet UILabel *mainLabel; +@end diff --git a/examples/objective-c/auth_sample/MakeRPCViewController.m b/examples/objective-c/auth_sample/MakeRPCViewController.m new file mode 100644 index 0000000000..366bc9deea --- /dev/null +++ b/examples/objective-c/auth_sample/MakeRPCViewController.m @@ -0,0 +1,100 @@ +/* + * + * 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. + * + */ + +#import "MakeRPCViewController.h" + +#import +#import +#include +#import + +NSString * const kTestScope = @"https://www.googleapis.com/auth/xapi.zoo"; + +static NSString * const kTestHostAddress = @"grpc-test.sandbox.google.com"; + +// Category for RPC errors to create the descriptions as we want them to appear on our view. +@interface NSError (AuthSample) +- (NSString *)UIDescription; +@end + +@implementation NSError (AuthSample) +- (NSString *)UIDescription { + if (self.code == GRPC_STATUS_UNAUTHENTICATED) { + // Authentication error. OAuth2 specifies we'll receive a challenge header. + // |userInfo[kGRPCStatusMetadataKey]| is the dictionary of response metadata. + NSString *challengeHeader = self.userInfo[kGRPCStatusMetadataKey][@"www-authenticate"] ?: @""; + return [@"Invalid credentials. Server challenge:\n" stringByAppendingString:challengeHeader]; + } else { + // Any other error. + return [NSString stringWithFormat:@"Unexpected RPC error %li: %@", + (long)self.code, self.localizedDescription]; + } +} +@end + +@implementation MakeRPCViewController + +- (void)viewWillAppear:(BOOL)animated { + + // Create a service client and a proto request as usual. + AUTHTestService *client = [[AUTHTestService alloc] initWithHost:kTestHostAddress]; + + AUTHRequest *request = [AUTHRequest message]; + request.fillUsername = YES; + request.fillOauthScope = YES; + + // Create a not-yet-started RPC. We want to set the request headers on this object before starting + // it. + ProtoRPC *call = + [client RPCToUnaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { + if (response) { + // This test server responds with the email and scope of the access token it receives. + self.mainLabel.text = [NSString stringWithFormat:@"Used scope: %@ on behalf of user %@", + response.oauthScope, response.username]; + + } else { + self.mainLabel.text = error.UIDescription; + } + }]; + + // Set the access token to be used. + NSString *accessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken; + call.requestMetadata[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken]; + + // Start the RPC. + [call start]; + + self.mainLabel.text = @"Waiting for RPC to complete..."; +} + +@end diff --git a/examples/objective-c/auth_sample/Misc/AppDelegate.h b/examples/objective-c/auth_sample/Misc/AppDelegate.h new file mode 100644 index 0000000000..102e7f3ade --- /dev/null +++ b/examples/objective-c/auth_sample/Misc/AppDelegate.h @@ -0,0 +1,38 @@ +/* + * + * 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. + * + */ + +#import + +@interface AppDelegate : UIResponder +@property (strong, nonatomic) UIWindow *window; +@end diff --git a/examples/objective-c/auth_sample/Misc/AppDelegate.m b/examples/objective-c/auth_sample/Misc/AppDelegate.m new file mode 100644 index 0000000000..798d342938 --- /dev/null +++ b/examples/objective-c/auth_sample/Misc/AppDelegate.m @@ -0,0 +1,61 @@ +/* + * + * 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. + * + */ + +#import "AppDelegate.h" + +#import + +@implementation AppDelegate + +// As instructed in https://developers.google.com/identity/sign-in/ios/sign-in +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + NSError* configureError; + [GGLContext.sharedInstance configureWithError: &configureError]; + NSAssert(!configureError, @"Error configuring Google services: %@", configureError); + + return YES; +} + +// As instructed in https://developers.google.com/identity/sign-in/ios/sign-in +- (BOOL)application:(UIApplication *)application + openURL:(NSURL *)url + sourceApplication:(NSString *)sourceApplication + annotation:(id)annotation { + // This will properly handle the URL that the application receives at the end of the + // authentication process. + return [GIDSignIn.sharedInstance handleURL:url + sourceApplication:sourceApplication + annotation:annotation]; +} + +@end diff --git a/examples/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard b/examples/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard new file mode 100644 index 0000000000..fb29c124e2 --- /dev/null +++ b/examples/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/objective-c/auth_sample/Misc/GoogleService-Info.plist b/examples/objective-c/auth_sample/Misc/GoogleService-Info.plist new file mode 100644 index 0000000000..86909d84a3 --- /dev/null +++ b/examples/objective-c/auth_sample/Misc/GoogleService-Info.plist @@ -0,0 +1,10 @@ + + + + + CLIENT_ID + 15087385131-lh9bpkiai9nls53uadju0if6k7un3uih.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.15087385131-lh9bpkiai9nls53uadju0if6k7un3uih + + \ No newline at end of file diff --git a/examples/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..36d2c80d88 --- /dev/null +++ b/examples/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json b/examples/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json new file mode 100644 index 0000000000..33a745102c --- /dev/null +++ b/examples/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "first.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf b/examples/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf new file mode 100644 index 0000000000..47d911dea6 Binary files /dev/null and b/examples/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf differ diff --git a/examples/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json b/examples/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json new file mode 100644 index 0000000000..03bd9c927f --- /dev/null +++ b/examples/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "second.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf b/examples/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf new file mode 100644 index 0000000000..401614e288 Binary files /dev/null and b/examples/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf differ diff --git a/examples/objective-c/auth_sample/Misc/Info.plist b/examples/objective-c/auth_sample/Misc/Info.plist new file mode 100644 index 0000000000..fc292507c7 --- /dev/null +++ b/examples/objective-c/auth_sample/Misc/Info.plist @@ -0,0 +1,80 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + io.grpc.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + REVERSED_CLIENT_ID + CFBundleURLSchemes + + com.googleusercontent.apps.15087385131-lh9bpkiai9nls53uadju0if6k7un3uih + + + + CFBundleTypeRole + Editor + CFBundleURLName + BUNDLE_ID + CFBundleURLSchemes + + io.grpc.AuthSample + + + + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + Main + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarTintParameters + + UINavigationBar + + Style + UIBarStyleDefault + Translucent + + + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/objective-c/auth_sample/Misc/main.m b/examples/objective-c/auth_sample/Misc/main.m new file mode 100644 index 0000000000..81e9d44e54 --- /dev/null +++ b/examples/objective-c/auth_sample/Misc/main.m @@ -0,0 +1,41 @@ +/* + * + * 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. + * + */ + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/objective-c/auth_sample/Podfile b/examples/objective-c/auth_sample/Podfile new file mode 100644 index 0000000000..dd4fd558c0 --- /dev/null +++ b/examples/objective-c/auth_sample/Podfile @@ -0,0 +1,10 @@ +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '8.0' + +target 'AuthSample' do + # Depend on the generated AuthTestService library. + pod 'AuthTestService', :path => '.' + + # Depend on Google's OAuth2 library + pod 'Google/SignIn' +end diff --git a/examples/objective-c/auth_sample/README.md b/examples/objective-c/auth_sample/README.md new file mode 100644 index 0000000000..4ca4982f53 --- /dev/null +++ b/examples/objective-c/auth_sample/README.md @@ -0,0 +1,189 @@ +#OAuth2 on gRPC: Objective-C + +This example application demostrates how to use OAuth2 on gRPC to make authenticated API calls on +behalf of a user. By walking through it you'll learn how to use the Objective-C gRPC API to: + +- Initialize and configure a remote call object before the RPC is started. +- Set request metadata elements on a call, which are semantically equivalent to HTTP request +headers. +- Read response metadata from a call, which is equivalent to HTTP response headers and trailers. + +It assumes you know the basics on how to make gRPC API calls using the Objective-C client library, +as shown in the [Hello World](https://github.com/grpc/grpc-common/tree/master/objective-c/helloworld) +or [Route Guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide) tutorials, +and are familiar with OAuth2 concepts like _access token_. + +- [Example code and setup](#setup) +- [Try it out!](#try) +- [Create an RPC object and start it later](#rpc-object) +- [Set request metadata of a call: Authorization header with an access token](#request-metadata) +- [Get response metadata of a call: Auth challenge header](#response-metadata) + + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/objective-c/auth_sample](https://github.com/grpc/grpc-common/tree/master/objective-c/auth_sample). +To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/objective-c/auth_sample`: +```shell +$ cd grpc-common/objective-c/auth_sample +``` + +Our example is a simple application with two views. The first one lets a user sign in and out using +the OAuth2 flow of Google's [iOS SignIn library](https://developers.google.com/identity/sign-in/ios/). +(Google's library is used in this example because the test gRPC service we are going to call expects +Google account credentials, but neither gRPC nor the Objective-C client library is tied to any +specific OAuth2 provider). The second view makes a gRPC request to the test server, using the +access token obtained by the first view. + +Note: OAuth2 libraries need the application to register and obtain an ID from the identity provider +(in the case of this example app, Google). The app's XCode project is configured using that ID, so +you shouldn't copy this project "as is" for your own app: it would result in your app being +identified in the consent screen as "gRPC-AuthSample", and not having access to real Google +services. Instead, configure your own XCode project following the [instructions here](https://developers.google.com/identity/sign-in/ios/). + +As with the other examples, you also should have [Cocoapods](https://cocoapods.org/#install) +installed, as well as the relevant tools to generate the client library code. You can obtain the +latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). + + + +## Try it out! + +To try the sample app, first have Cocoapods generate and install the client library for our .proto +files: + +```shell +$ pod install +``` + +(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet +on your computer's cache). + +Finally, open the XCode workspace created by Cocoapods, and run the app. + +The first view, `SelectUserViewController.h/m`, asks you to sign in with your Google account, and to +give the "gRPC-AuthSample" app the following permissions: + +- View your email address. +- View your basic profile info. +- "Test scope for access to the Zoo service". + +This last permission, corresponding to the scope `https://www.googleapis.com/auth/xapi.zoo` doesn't +grant any real capability: it's only used for testing. You can log out at any time. + +The second view, `MakeRPCViewController.h/m`, makes a gRPC request to a test server at +https://grpc-test.sandbox.google.com, sending the access token along with the request. The test +service simply validates the token and writes in its response which user it belongs to, and which +scopes it gives access to. (The client application already knows those two values; it's a way to +verify that everything went as expected). + +The next sections guide you step-by-step through how the gRPC call in `MakeRPCViewController` is +performed. + + +## Create an RPC object and start it later + +The other basic tutorials show how to invoke an RPC by calling an asynchronous method in a generated +client object. This shows how to initialize an object that represents the RPC, and configure it +before starting the network request. + +Assume you have a proto service definition like this: + +```protobuf +option objc_class_prefix = "AUTH"; + +service TestService { + rpc UnaryCall(Request) returns (Response); +} +``` + +A `unaryCallWithRequest:handler:` method, with which you're already familiar, is generated for the +`AUTHTestService` class: + +```objective-c +[client unaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { + ... +}]; +``` + +In addition, an `RPCToUnaryCallWithRequest:handler:` method is generated, which returns a +not-yet-started RPC object: + +```objective-c +#import + +ProtoRPC *call = + [client RPCToUnaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { + ... + }]; +``` + +The RPC represented by this object can be started at any later time like this: + +```objective-c +[call start]; +``` + + +## Set request metadata of a call: Authorization header with an access token + +The `ProtoRPC` class has a `requestMetadata` property (inherited from `GRPCCall`) defined like this: + +```objective-c +- (NSMutableDictionary *)requestMetadata; // nonatomic +- (void)setRequestMetadata:(NSDictionary *)requestMetadata; // nonatomic, copy +``` + +Setting it to a dictionary of metadata keys and values will have them sent on the wire when the call +is started. gRPC metadata are pieces of information about the call sent by the client to the server +(and vice versa). They take the form of key-value pairs and are essentially opaque to gRPC itself. + +```objective-c +call.requestMetadata = @{@"My-Header": @"Value for this header", + @"Another-Header": @"Its value"}; +``` + +For convenience, the property is initialized with an empty `NSMutableDictionary`, so that request +metadata elements can be set like this: + +```objective-c +call.requestMetadata[@"My-Header"] = @"Value for this header"; +``` + +If you have an access token, OAuth2 specifies it is to be sent in this format: + +```objective-c +call.requestMetadata[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken]; +``` + + +## Get response metadata of a call: Auth challenge header + +The `ProtoRPC` class also inherits a `responseMetadata` property, analogous to the request metadata +we just looked at. It's defined like this: + +```objective-c +@property(atomic, readonly) NSDictionary *responseMetadata; +``` + +To access OAuth2's authentication challenge header you write: + +```objective-c +call.responseMetadata[@"www-authenticate"] +``` + +Note that, as gRPC metadata elements are mapped to HTTP/2 headers (or trailers), the keys of the +response metadata are always ASCII strings in lowercase. + +Many uses cases of response metadata are getting more details about an RPC error. For convenience, +when a `NSError` instance is passed to an RPC handler block, the response metadata dictionary can +also be accessed this way: + +```objective-c +error.userInfo[kGRPCStatusMetadataKey] +``` diff --git a/examples/objective-c/auth_sample/SelectUserViewController.h b/examples/objective-c/auth_sample/SelectUserViewController.h new file mode 100644 index 0000000000..eb3c2cf5f0 --- /dev/null +++ b/examples/objective-c/auth_sample/SelectUserViewController.h @@ -0,0 +1,42 @@ +/* + * + * 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. + * + */ + +#import +#import + +@interface SelectUserViewController : UIViewController +@property(weak, nonatomic) IBOutlet GIDSignInButton *signInButton; +@property(weak, nonatomic) IBOutlet UIButton *signOutButton; +@property(weak, nonatomic) IBOutlet UILabel *mainLabel; +@property(weak, nonatomic) IBOutlet UILabel *subLabel; +@end diff --git a/examples/objective-c/auth_sample/SelectUserViewController.m b/examples/objective-c/auth_sample/SelectUserViewController.m new file mode 100644 index 0000000000..954c531f3f --- /dev/null +++ b/examples/objective-c/auth_sample/SelectUserViewController.m @@ -0,0 +1,86 @@ +/* + * + * 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. + * + */ + +#import "SelectUserViewController.h" + +#import "MakeRPCViewController.h" + +@implementation SelectUserViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.signOutButton.layer.cornerRadius = 5; + self.signOutButton.hidden = YES; + + // As instructed in https://developers.google.com/identity/sign-in/ios/sign-in + GIDSignIn *signIn = GIDSignIn.sharedInstance; + signIn.delegate = self; + signIn.uiDelegate = self; + + // As instructed in https://developers.google.com/identity/sign-in/ios/additional-scopes + if (![signIn.scopes containsObject:kTestScope]) { + signIn.scopes = [signIn.scopes arrayByAddingObject:kTestScope]; + } + + [signIn signInSilently]; +} + +- (void)signIn:(GIDSignIn *)signIn +didSignInForUser:(GIDGoogleUser *)user + withError:(NSError *)error { + if (error) { + // The user probably cancelled the sign-in flow. + return; + } + + self.mainLabel.text = [NSString stringWithFormat:@"User: %@", user.profile.email]; + NSString *scopes = [user.accessibleScopes componentsJoinedByString:@", "]; + scopes = scopes.length ? scopes : @"(none)"; + self.subLabel.text = [NSString stringWithFormat:@"Scopes: %@", scopes]; + + self.signInButton.hidden = YES; + self.signOutButton.hidden = NO; +} + +- (IBAction)didTapSignOut { + [GIDSignIn.sharedInstance signOut]; + + self.mainLabel.text = @"Please sign in."; + self.subLabel.text = @""; + + self.signInButton.hidden = NO; + self.signOutButton.hidden = YES; +} + +@end diff --git a/examples/objective-c/helloworld/HelloWorld.podspec b/examples/objective-c/helloworld/HelloWorld.podspec new file mode 100644 index 0000000000..ae009a688c --- /dev/null +++ b/examples/objective-c/helloworld/HelloWorld.podspec @@ -0,0 +1,35 @@ +Pod::Spec.new do |s| + s.name = "HelloWorld" + s.version = "0.0.1" + s.license = "New BSD" + + s.ios.deployment_target = "6.0" + s.osx.deployment_target = "10.8" + + # Base directory where the .proto files are. + src = "../../protos" + + # Directory where the generated files will be place. + dir = "Pods/" + s.name + + # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. + s.prepare_command = <<-CMD + mkdir -p #{dir} + protoc -I #{src} --objc_out=#{dir} --objcgrpc_out=#{dir} #{src}/helloworld.proto + CMD + + s.subspec "Messages" do |ms| + ms.source_files = "#{dir}/*.pbobjc.{h,m}", "#{dir}/**/*.pbobjc.{h,m}" + ms.header_mappings_dir = dir + ms.requires_arc = false + ms.dependency "Protobuf", "~> 3.0.0-alpha-3" + end + + s.subspec "Services" do |ss| + ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}" + ss.header_mappings_dir = dir + ss.requires_arc = true + ss.dependency "gRPC", "~> 0.6" + ss.dependency "#{s.name}/Messages" + end +end diff --git a/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj b/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..702ad3ff8b --- /dev/null +++ b/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj @@ -0,0 +1,349 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 5E3690661B2A23800040F884 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3690651B2A23800040F884 /* main.m */; }; + 5E3690691B2A23800040F884 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3690681B2A23800040F884 /* AppDelegate.m */; }; + 5E36906C1B2A23800040F884 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E36906B1B2A23800040F884 /* ViewController.m */; }; + 5E36906F1B2A23800040F884 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E36906D1B2A23800040F884 /* Main.storyboard */; }; + 5E3690711B2A23800040F884 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5E3690701B2A23800040F884 /* Images.xcassets */; }; + EF61CF6AE2536A31D47F0E63 /* libPods-HelloWorld.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B4E1F55F8A2EC95A0E7EE88 /* libPods-HelloWorld.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.release.xcconfig"; path = "Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld.release.xcconfig"; sourceTree = ""; }; + 5E3690601B2A23800040F884 /* HelloWorld.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorld.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E3690641B2A23800040F884 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5E3690651B2A23800040F884 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 5E3690671B2A23800040F884 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 5E3690681B2A23800040F884 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5E36906B1B2A23800040F884 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 5E36906E1B2A23800040F884 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5E3690701B2A23800040F884 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6B4E1F55F8A2EC95A0E7EE88 /* libPods-HelloWorld.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HelloWorld.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.debug.xcconfig"; path = "Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5E36905D1B2A23800040F884 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EF61CF6AE2536A31D47F0E63 /* libPods-HelloWorld.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 5E3690571B2A23800040F884 = { + isa = PBXGroup; + children = ( + 5E3690651B2A23800040F884 /* main.m */, + 5E3690621B2A23800040F884 /* HelloWorld */, + 5E3690611B2A23800040F884 /* Products */, + BD9CE6458E7C4FF49A1DF69F /* Pods */, + 66CEC7120220DDD2221DD075 /* Frameworks */, + ); + sourceTree = ""; + }; + 5E3690611B2A23800040F884 /* Products */ = { + isa = PBXGroup; + children = ( + 5E3690601B2A23800040F884 /* HelloWorld.app */, + ); + name = Products; + sourceTree = ""; + }; + 5E3690621B2A23800040F884 /* HelloWorld */ = { + isa = PBXGroup; + children = ( + 5E3690631B2A23800040F884 /* Supporting Files */, + ); + path = HelloWorld; + sourceTree = ""; + }; + 5E3690631B2A23800040F884 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 5E3690701B2A23800040F884 /* Images.xcassets */, + 5E36906D1B2A23800040F884 /* Main.storyboard */, + 5E36906B1B2A23800040F884 /* ViewController.m */, + 5E3690681B2A23800040F884 /* AppDelegate.m */, + 5E3690671B2A23800040F884 /* AppDelegate.h */, + 5E3690641B2A23800040F884 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 66CEC7120220DDD2221DD075 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 6B4E1F55F8A2EC95A0E7EE88 /* libPods-HelloWorld.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + BD9CE6458E7C4FF49A1DF69F /* Pods */ = { + isa = PBXGroup; + children = ( + DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */, + 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5E36905F1B2A23800040F884 /* HelloWorld */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5E3690831B2A23810040F884 /* Build configuration list for PBXNativeTarget "HelloWorld" */; + buildPhases = ( + ACF9162361FB8F24C70657DE /* Check Pods Manifest.lock */, + 5E36905C1B2A23800040F884 /* Sources */, + 5E36905D1B2A23800040F884 /* Frameworks */, + 5E36905E1B2A23800040F884 /* Resources */, + 4C7D815378D98AB3BFC1A7D5 /* Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = HelloWorld; + productName = HelloWorld; + productReference = 5E3690601B2A23800040F884 /* HelloWorld.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5E3690581B2A23800040F884 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0620; + ORGANIZATIONNAME = Google; + TargetAttributes = { + 5E36905F1B2A23800040F884 = { + CreatedOnToolsVersion = 6.2; + }; + }; + }; + buildConfigurationList = 5E36905B1B2A23800040F884 /* Build configuration list for PBXProject "HelloWorld" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5E3690571B2A23800040F884; + productRefGroup = 5E3690611B2A23800040F884 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5E36905F1B2A23800040F884 /* HelloWorld */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5E36905E1B2A23800040F884 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E36906F1B2A23800040F884 /* Main.storyboard in Resources */, + 5E3690711B2A23800040F884 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 4C7D815378D98AB3BFC1A7D5 /* Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + ACF9162361FB8F24C70657DE /* Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5E36905C1B2A23800040F884 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E36906C1B2A23800040F884 /* ViewController.m in Sources */, + 5E3690691B2A23800040F884 /* AppDelegate.m in Sources */, + 5E3690661B2A23800040F884 /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 5E36906D1B2A23800040F884 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5E36906E1B2A23800040F884 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 5E3690811B2A23810040F884 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.2; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5E3690821B2A23810040F884 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.2; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5E3690841B2A23810040F884 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = HelloWorld/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 5E3690851B2A23810040F884 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = HelloWorld/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5E36905B1B2A23800040F884 /* Build configuration list for PBXProject "HelloWorld" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E3690811B2A23810040F884 /* Debug */, + 5E3690821B2A23810040F884 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5E3690831B2A23810040F884 /* Build configuration list for PBXNativeTarget "HelloWorld" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E3690841B2A23810040F884 /* Debug */, + 5E3690851B2A23810040F884 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5E3690581B2A23800040F884 /* Project object */; +} diff --git a/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..174a04ecb8 --- /dev/null +++ b/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/examples/objective-c/helloworld/HelloWorld/AppDelegate.h b/examples/objective-c/helloworld/HelloWorld/AppDelegate.h new file mode 100644 index 0000000000..102e7f3ade --- /dev/null +++ b/examples/objective-c/helloworld/HelloWorld/AppDelegate.h @@ -0,0 +1,38 @@ +/* + * + * 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. + * + */ + +#import + +@interface AppDelegate : UIResponder +@property (strong, nonatomic) UIWindow *window; +@end diff --git a/examples/objective-c/helloworld/HelloWorld/AppDelegate.m b/examples/objective-c/helloworld/HelloWorld/AppDelegate.m new file mode 100644 index 0000000000..a38e36651e --- /dev/null +++ b/examples/objective-c/helloworld/HelloWorld/AppDelegate.m @@ -0,0 +1,37 @@ +/* + * + * 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. + * + */ + +#import "AppDelegate.h" + +@implementation AppDelegate +@end diff --git a/examples/objective-c/helloworld/HelloWorld/Base.lproj/Main.storyboard b/examples/objective-c/helloworld/HelloWorld/Base.lproj/Main.storyboard new file mode 100644 index 0000000000..f56d2f3bb5 --- /dev/null +++ b/examples/objective-c/helloworld/HelloWorld/Base.lproj/Main.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/objective-c/helloworld/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/objective-c/helloworld/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..36d2c80d88 --- /dev/null +++ b/examples/objective-c/helloworld/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/objective-c/helloworld/HelloWorld/Info.plist b/examples/objective-c/helloworld/HelloWorld/Info.plist new file mode 100644 index 0000000000..1078fff723 --- /dev/null +++ b/examples/objective-c/helloworld/HelloWorld/Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + Google.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + Main + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/objective-c/helloworld/HelloWorld/ViewController.m b/examples/objective-c/helloworld/HelloWorld/ViewController.m new file mode 100644 index 0000000000..090fd93689 --- /dev/null +++ b/examples/objective-c/helloworld/HelloWorld/ViewController.m @@ -0,0 +1,40 @@ +/* + * + * 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. + * + */ + +#import + +@interface ViewController : UIViewController +@end + +@implementation ViewController +@end diff --git a/examples/objective-c/helloworld/Podfile b/examples/objective-c/helloworld/Podfile new file mode 100644 index 0000000000..2934ebc2c8 --- /dev/null +++ b/examples/objective-c/helloworld/Podfile @@ -0,0 +1,7 @@ +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '8.0' + +target 'HelloWorld' do + # Depend on the generated HelloWorld library. + pod 'HelloWorld', :path => '.' +end diff --git a/examples/objective-c/helloworld/README.md b/examples/objective-c/helloworld/README.md new file mode 100644 index 0000000000..685339e84a --- /dev/null +++ b/examples/objective-c/helloworld/README.md @@ -0,0 +1,56 @@ +#gRPC in 3 minutes (Objective-C) + +## Installation + +To run this example you should have [Cocoapods](https://cocoapods.org/#install) installed, as well +as the relevant tools to generate the client library code (and a server in another language, for +testing). You can obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). + +## Hello Objective-C gRPC! + +Here's how to build and run the Objective-C implementation of the [Hello World](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto) +example used in [Getting started](https://github.com/grpc/grpc-common). + +The example code for this and our other examples lives in the `grpc-common` GitHub repository. Clone +this repository to your local machine by running the following command: + + +```sh +$ git clone https://github.com/grpc/grpc-common.git +``` + +Change your current directory to `grpc-common/objective-c/helloworld` + +```sh +$ cd grpc-common/objective-c/helloworld +``` + +### Try it! +To try the sample app, we need a gRPC server running locally. Let's compile and run, for example, +the C++ server in this repository: + +```shell +$ pushd ../../cpp/helloworld +$ make +$ ./greeter_server & +$ popd +``` + +Now have Cocoapods generate and install the client library for our .proto files: + +```shell +$ pod install +``` + +(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet +on your computer's cache.) + +Finally, open the XCode workspace created by Cocoapods, and run the app. You can check the calling +code in `main.m` and see the results in XCode's log console. + +The code sends a `HLWHelloRequest` containing the string "Objective-C" to a local server. The server +responds with a `HLWHelloResponse`, which contains a string that is then output to the log. + +## Tutorial + +You can find a more detailed tutorial in [gRPC Basics: Objective-C](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/README.md). diff --git a/examples/objective-c/helloworld/main.m b/examples/objective-c/helloworld/main.m new file mode 100644 index 0000000000..458580be30 --- /dev/null +++ b/examples/objective-c/helloworld/main.m @@ -0,0 +1,51 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import +#import "AppDelegate.h" + +#import + +static NSString * const kHostAddress = @"http://localhost:50051"; + +int main(int argc, char * argv[]) { + @autoreleasepool { + HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress]; + HLWHelloRequest *request = [HLWHelloRequest message]; + request.name = @"Objective-C"; + [client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { + NSLog(@"%@", response.message); + }]; + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/objective-c/route_guide/Misc/AppDelegate.h b/examples/objective-c/route_guide/Misc/AppDelegate.h new file mode 100644 index 0000000000..102e7f3ade --- /dev/null +++ b/examples/objective-c/route_guide/Misc/AppDelegate.h @@ -0,0 +1,38 @@ +/* + * + * 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. + * + */ + +#import + +@interface AppDelegate : UIResponder +@property (strong, nonatomic) UIWindow *window; +@end diff --git a/examples/objective-c/route_guide/Misc/AppDelegate.m b/examples/objective-c/route_guide/Misc/AppDelegate.m new file mode 100644 index 0000000000..a38e36651e --- /dev/null +++ b/examples/objective-c/route_guide/Misc/AppDelegate.m @@ -0,0 +1,37 @@ +/* + * + * 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. + * + */ + +#import "AppDelegate.h" + +@implementation AppDelegate +@end diff --git a/examples/objective-c/route_guide/Misc/Base.lproj/Main.storyboard b/examples/objective-c/route_guide/Misc/Base.lproj/Main.storyboard new file mode 100644 index 0000000000..9bf9498d62 --- /dev/null +++ b/examples/objective-c/route_guide/Misc/Base.lproj/Main.storyboard @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..36d2c80d88 --- /dev/null +++ b/examples/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json b/examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json new file mode 100644 index 0000000000..33a745102c --- /dev/null +++ b/examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "first.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf b/examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf new file mode 100644 index 0000000000..47d911dea6 Binary files /dev/null and b/examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf differ diff --git a/examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json b/examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json new file mode 100644 index 0000000000..03bd9c927f --- /dev/null +++ b/examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "second.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf b/examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf new file mode 100644 index 0000000000..401614e288 Binary files /dev/null and b/examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf differ diff --git a/examples/objective-c/route_guide/Misc/Info.plist b/examples/objective-c/route_guide/Misc/Info.plist new file mode 100644 index 0000000000..33ad4800f6 --- /dev/null +++ b/examples/objective-c/route_guide/Misc/Info.plist @@ -0,0 +1,57 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + gRPC.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + Main + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarTintParameters + + UINavigationBar + + Style + UIBarStyleDefault + Translucent + + + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/objective-c/route_guide/Misc/main.m b/examples/objective-c/route_guide/Misc/main.m new file mode 100644 index 0000000000..fb701005d1 --- /dev/null +++ b/examples/objective-c/route_guide/Misc/main.m @@ -0,0 +1,41 @@ +/* + * + * 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. + * + */ + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/objective-c/route_guide/Podfile b/examples/objective-c/route_guide/Podfile new file mode 100644 index 0000000000..a97f414685 --- /dev/null +++ b/examples/objective-c/route_guide/Podfile @@ -0,0 +1,7 @@ +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '8.0' + +target 'RouteGuideClient' do + # Depend on the generated RouteGuide library. + pod 'RouteGuide', :path => '.' +end diff --git a/examples/objective-c/route_guide/README.md b/examples/objective-c/route_guide/README.md new file mode 100644 index 0000000000..bbbd9e020d --- /dev/null +++ b/examples/objective-c/route_guide/README.md @@ -0,0 +1,360 @@ +#gRPC Basics: Objective-C + +This tutorial provides a basic Objective-C programmer's introduction to working with gRPC. By +walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate client code using the protocol buffer compiler. +- Use the Objective-C gRPC API to write a simple client for your service. + +It assumes a passing familiarity with [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). +Note that the example in this tutorial uses the proto3 version of the protocol buffers language, +which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) +and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the +protocol buffers Github repository. + +This isn't a comprehensive guide to using gRPC in Objective-C: more reference documentation is +coming soon. + +- [Why use gRPC?](#why-grpc) +- [Example code and setup](#setup) +- [Try it out!](#try) +- [Defining the service](#proto) +- [Generating client code](#protoc) +- [Creating the client](#client) + + +## Why use gRPC? + +With gRPC you can define your service once in a .proto file and implement clients and servers in any +of gRPC's supported languages, which in turn can be run in environments ranging from servers inside +Google to your own tablet - all the complexity of communication between different languages and +environments is handled for you by gRPC. You also get all the advantages of working with protocol +buffers, including efficient serialization, a simple IDL, and easy interface updating. + +gRPC and proto3 are specially suited for mobile clients: gRPC is implemented on top of HTTP/2, which +results in network bandwidth savings over using HTTP/1.1. Serialization and parsing of the proto +binary format is more efficient than the equivalent JSON, resulting in CPU and battery savings. And +proto3 uses a runtime that has been optimized over the years at Google to keep code size to a +minimum. The latter is important in Objective-C, because the ability of the compiler to strip unused +code is limited by the dynamic nature of the language. + + + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/objective-c/route_guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide). +To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/objective-c/route_guide`: +```shell +$ cd grpc-common/objective-c/route_guide +``` + +Our example is a simple route mapping application that lets clients get information about features +on their route, create a summary of their route, and exchange route information such as traffic +updates with the server and other clients. + +You also should have [Cocoapods](https://cocoapods.org/#install) installed, as well as the relevant +tools to generate the client library code (and a server in another language, for testing). You can +obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). + + + +## Try it out! + +To try the sample app, we need a gRPC server running locally. Let's compile and run, for example, +the C++ server in this repository: + +```shell +$ pushd ../../cpp/route_guide +$ make +$ ./route_guide_server & +$ popd +``` + +Now have Cocoapods generate and install the client library for our .proto files: + +```shell +$ pod install +``` + +(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet +on your computer's cache). + +Finally, open the XCode workspace created by Cocoapods, and run the app. You can check the calling +code in `ViewControllers.m` and see the results in XCode's log console. + +The next sections guide you step-by-step through how this proto service is defined, how to generate +a client library from it, and how to create an app that uses that library. + + + +## Defining the service + +First let's look at how the service we're using is defined. A gRPC *service* and its method +*request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). +You can see the complete .proto file for our example in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +```protobuf +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response +types. Protocol buffers let you define four kinds of service method, all of which are used in the +`RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server and receives a response later, just +like a normal remote procedure call. +```protobuf + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *response-streaming RPC* where the client sends a request to the server and gets back a stream +of response messages. You specify a response-streaming method by placing the `stream` keyword before +the *response* type. +```protobuf + // 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 *request-streaming RPC* where the client sends a sequence of messages to the server. Once the +client has finished writing the messages, it waits for the server to read them all and return its +response. You specify a request-streaming method by placing the `stream` keyword before the +*request* type. +```protobuf + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages to the other. The two +streams operate independently, so clients and servers can read and write in whatever order they +like: for example, the server could wait to receive all the client messages before writing its +responses, or it could alternately read a message then write a message, or some other combination of +reads and writes. The order of messages in each stream is preserved. You specify this type of method +by placing the `stream` keyword before both the request and the response. +```protobuf + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and +response types used in our service methods - for example, here's the `Point` message type: +```protobuf +// 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; +} +``` + +You can specify a prefix to be used for your generated classes by adding the `objc_class_prefix` +option at the top of the file. For example: +```protobuf +option objc_class_prefix = "RTG"; +``` + + + +## Generating client code + +Next we need to generate the gRPC client interfaces from our .proto service definition. We do this +using the protocol buffer compiler (`protoc`) with a special gRPC Objective-C plugin. + +For simplicity, we've provided a [Podspec file](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/RouteGuide.podspec) +that runs `protoc` for you with the appropriate plugin, input, and output, and describes how to +compile the generated files. You just need to run in this directory (`grpc-common/objective-c/route_guide`): + +```shell +$ pod install +``` + +which, before installing the generated library in the XCode project of this sample, runs: + +```shell +$ protoc -I ../../protos --objc_out=Pods/RouteGuide --objcgrpc_out=Pods/RouteGuide ../../protos/route_guide.proto +``` + +Running this command generates the following files under `Pods/RouteGuide/`: +- `RouteGuide.pbobjc.h`, the header which declares your generated message classes. +- `RouteGuide.pbobjc.m`, which contains the implementation of your message classes. +- `RouteGuide.pbrpc.h`, the header which declares your generated service classes. +- `RouteGuide.pbrpc.m`, which contains the implementation of your service classes. + +These contain: +- All the protocol buffer code to populate, serialize, and retrieve our request and response message +types. +- A class called `RTGRouteGuide` that lets clients call the methods defined in the `RouteGuide` +service. + +You can also use the provided Podspec file to generate client code from any other proto service +definition; just replace the name (matching the file name), version, and other metadata. + + + +## Creating the client + +In this section, we'll look at creating an Objective-C client for our `RouteGuide` service. You can +see our complete example client code in [grpc-common/objective-c/route_guide/ViewControllers.m](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/ViewControllers.m). +(Note: In your apps, for maintainability and readability reasons, you shouldn't put all of your view +controllers in a single file; it's done here only to simplify the learning process). + +### Constructing a client object + +To call service methods, we first need to create a client object, an instance of the generated +`RTGRouteGuide` class. The designated initializer of the class expects a `NSString *` with the +server address and port we want to connect to: + +```objective-c +#import + +static NSString * const kHostAddress = @"http://localhost:50051"; + +... + +RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; +``` + +Notice that we've specified the HTTP scheme in the host address. This is because the server we will +be using to test our client doesn't use [TLS](http://en.wikipedia.org/wiki/Transport_Layer_Security). +This is fine because it will be running locally on our development machine. The most common case, +though, is connecting with a gRPC server on the internet, running gRPC over TLS. For that case, the +HTTPS scheme can be specified (or no scheme at all, as HTTPS is the default value). The default +value of the port is that of the scheme selected: 443 for HTTPS and 80 for HTTP. + + +### Calling service methods + +Now let's look at how we call our service methods. As you will see, all these methods are +asynchronous, so you can call them from the main thread of your app without worrying about freezing +your UI or the OS killing your app. + +#### Simple RPC + +Calling the simple RPC `GetFeature` is nearly as straightforward as calling any other asynchronous +method on Cocoa. + +```objective-c +RTGPoint *point = [RTGPoint message]; +point.latitude = 40E7; +point.longitude = -74E7; + +[client getFeatureWithRequest:point handler:^(RTGFeature *response, NSError *error) { + if (response) { + // Successful response received + } else { + // RPC error + } +}]; +``` + +As you can see, we create and populate a request protocol buffer object (in our case `RTGPoint`). +Then, we call the method on the client object, passing it the request, and a block to handle the +response (or any RPC error). If the RPC finishes successfully, the handler block is called with a +`nil` error argument, and we can read the response information from the server from the response +argument. If, instead, some RPC error happens, the handler block is called with a `nil` response +argument, and we can read the details of the problem from the error argument. + +```objective-c +NSLog(@"Found feature called %@ at %@.", response.name, response.location); +``` + +#### Streaming RPCs + +Now let's look at our streaming methods. Here's where we call the response-streaming method +`ListFeatures`, which results in our client receiving a stream of geographical `RTGFeature`s: + +```objective-c +[client listFeaturesWithRequest:rectangle + eventHandler:^(BOOL done, RTGFeature *response, NSError *error) { + if (response) { + // Element of the stream of responses received + } else if (error) { + // RPC error; the stream is over. + } + if (done) { + // The stream is over (all the responses were received, or an error occured). Do any cleanup. + } +}]; +``` + +Notice how the signature of the `eventHandler` block now includes a `BOOL done` parameter. The +`eventHandler` block can be called any number of times; only on the last call is the `done` argument +value set to `YES`. If an error occurs, the RPC finishes and the block is called with the arguments +`(YES, nil, error)`. + +The request-streaming method `RecordRoute` expects a stream of `RTGPoint`s from the cient. This +stream is passed to the method as an object of class `GRXWriter`. The simplest way to create one is +to initialize one from a `NSArray` object: + + +```objective-c +#import + +... + +RTGPoint *point1 = [RTGPoint message]; +point.latitude = 40E7; +point.longitude = -74E7; + +RTGPoint *point2 = [RTGPoint message]; +point.latitude = 40E7; +point.longitude = -74E7; + +GRXWriter *locationsWriter = [GRXWriter writerWithContainer:@[point1, point2]]; + +[client recordRouteWithRequestsWriter:locationsWriter + handler:^(RTGRouteSummary *response, NSError *error) { + if (response) { + NSLog(@"Finished trip with %i points", response.pointCount); + NSLog(@"Passed %i features", response.featureCount); + NSLog(@"Travelled %i meters", response.distance); + NSLog(@"It took %i seconds", response.elapsedTime); + } else { + NSLog(@"RPC error: %@", error); + } +}]; + +``` + +The `GRXWriter` class is generic enough to allow for asynchronous streams, streams of future values, +or even infinite streams. + +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. The way to call a +bidirectional streaming RPC is just a combination of how to call request-streaming RPCs and +response-streaming RPCs. + +```objective-c +[client routeChatWithRequestsWriter:notesWriter + eventHandler:^(BOOL done, RTGRouteNote *note, NSError *error) { + if (note) { + NSLog(@"Got message %@ at %@", note.message, note.location); + } else if (error) { + NSLog(@"RPC error: %@", error); + } + if (done) { + NSLog(@"Chat ended."); + } +}]; +``` + +The semantics for the handler block and the `GRXWriter` argument here are exactly the same as for +our request-streaming and response-streaming methods. Although both client and server will always +get the other's messages in the order they were written, the two streams operate completely +independently. diff --git a/examples/objective-c/route_guide/RouteGuide.podspec b/examples/objective-c/route_guide/RouteGuide.podspec new file mode 100644 index 0000000000..7b99a6c6a7 --- /dev/null +++ b/examples/objective-c/route_guide/RouteGuide.podspec @@ -0,0 +1,35 @@ +Pod::Spec.new do |s| + s.name = "RouteGuide" + s.version = "0.0.1" + s.license = "New BSD" + + s.ios.deployment_target = "6.0" + s.osx.deployment_target = "10.8" + + # Base directory where the .proto files are. + src = "../../protos" + + # Directory where the generated files will be place. + dir = "Pods/" + s.name + + # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. + s.prepare_command = <<-CMD + mkdir -p #{dir} + protoc -I #{src} --objc_out=#{dir} --objcgrpc_out=#{dir} #{src}/route_guide.proto + CMD + + s.subspec "Messages" do |ms| + ms.source_files = "#{dir}/*.pbobjc.{h,m}", "#{dir}/**/*.pbobjc.{h,m}" + ms.header_mappings_dir = dir + ms.requires_arc = false + ms.dependency "Protobuf", "~> 3.0.0-alpha-3" + end + + s.subspec "Services" do |ss| + ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}" + ss.header_mappings_dir = dir + ss.requires_arc = true + ss.dependency "gRPC", "~> 0.6" + ss.dependency "#{s.name}/Messages" + end +end diff --git a/examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj b/examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..6ab6b27a1b --- /dev/null +++ b/examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj @@ -0,0 +1,366 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 124E20A2FC8EAE54460D4ED2 /* libPods-RouteGuideClient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 71CEE03D66D40FC37264D6E4 /* libPods-RouteGuideClient.a */; }; + 632527831B1D0396003073D9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 632527821B1D0396003073D9 /* main.m */; }; + 632527861B1D0396003073D9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 632527851B1D0396003073D9 /* AppDelegate.m */; }; + 6325278F1B1D0396003073D9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6325278D1B1D0396003073D9 /* Main.storyboard */; }; + 632527911B1D0396003073D9 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 632527901B1D0396003073D9 /* Images.xcassets */; }; + 6367B55B1B223AFA008861F5 /* route_guide_db.json in Resources */ = {isa = PBXBuildFile; fileRef = 6367B55A1B223AFA008861F5 /* route_guide_db.json */; }; + 63A6015C1B1DAB5000FA5B86 /* ViewControllers.m in Sources */ = {isa = PBXBuildFile; fileRef = 63A6015B1B1DAB5000FA5B86 /* ViewControllers.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 6325277D1B1D0396003073D9 /* RouteGuideClient.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RouteGuideClient.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 632527811B1D0396003073D9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 632527821B1D0396003073D9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 632527841B1D0396003073D9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 632527851B1D0396003073D9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6325278E1B1D0396003073D9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 632527901B1D0396003073D9 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6367B55A1B223AFA008861F5 /* route_guide_db.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = route_guide_db.json; sourceTree = ""; }; + 63A6015B1B1DAB5000FA5B86 /* ViewControllers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewControllers.m; sourceTree = ""; }; + 71CEE03D66D40FC37264D6E4 /* libPods-RouteGuideClient.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RouteGuideClient.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + ADA4C647BAE906F79AD9A45E /* Pods-RouteGuideClient.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RouteGuideClient.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RouteGuideClient/Pods-RouteGuideClient.debug.xcconfig"; sourceTree = ""; }; + C83C5A54D1A4EA07569F1AED /* Pods-RouteGuideClient.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RouteGuideClient.release.xcconfig"; path = "Pods/Target Support Files/Pods-RouteGuideClient/Pods-RouteGuideClient.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 6325277A1B1D0395003073D9 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 124E20A2FC8EAE54460D4ED2 /* libPods-RouteGuideClient.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 56849C29DC376BF4B902CD77 /* Pods */ = { + isa = PBXGroup; + children = ( + ADA4C647BAE906F79AD9A45E /* Pods-RouteGuideClient.debug.xcconfig */, + C83C5A54D1A4EA07569F1AED /* Pods-RouteGuideClient.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 631C63891B1DBC41001295D5 /* Misc */ = { + isa = PBXGroup; + children = ( + 632527841B1D0396003073D9 /* AppDelegate.h */, + 632527851B1D0396003073D9 /* AppDelegate.m */, + 632527901B1D0396003073D9 /* Images.xcassets */, + 632527801B1D0396003073D9 /* Supporting Files */, + ); + path = Misc; + sourceTree = ""; + }; + 632527741B1D0395003073D9 = { + isa = PBXGroup; + children = ( + 6325277F1B1D0396003073D9 /* RouteGuideClient */, + 6325277E1B1D0396003073D9 /* Products */, + 56849C29DC376BF4B902CD77 /* Pods */, + 7482B8A18481F7B13ADE4530 /* Frameworks */, + ); + sourceTree = ""; + }; + 6325277E1B1D0396003073D9 /* Products */ = { + isa = PBXGroup; + children = ( + 6325277D1B1D0396003073D9 /* RouteGuideClient.app */, + ); + name = Products; + sourceTree = ""; + }; + 6325277F1B1D0396003073D9 /* RouteGuideClient */ = { + isa = PBXGroup; + children = ( + 63A6015B1B1DAB5000FA5B86 /* ViewControllers.m */, + 6367B55A1B223AFA008861F5 /* route_guide_db.json */, + 6325278D1B1D0396003073D9 /* Main.storyboard */, + 631C63891B1DBC41001295D5 /* Misc */, + ); + name = RouteGuideClient; + sourceTree = SOURCE_ROOT; + }; + 632527801B1D0396003073D9 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 632527811B1D0396003073D9 /* Info.plist */, + 632527821B1D0396003073D9 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 7482B8A18481F7B13ADE4530 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 71CEE03D66D40FC37264D6E4 /* libPods-RouteGuideClient.a */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 6325277C1B1D0395003073D9 /* RouteGuideClient */ = { + isa = PBXNativeTarget; + buildConfigurationList = 632527A31B1D0396003073D9 /* Build configuration list for PBXNativeTarget "RouteGuideClient" */; + buildPhases = ( + C6FC30AD2376EC04317237C5 /* Check Pods Manifest.lock */, + 632527791B1D0395003073D9 /* Sources */, + 6325277A1B1D0395003073D9 /* Frameworks */, + 6325277B1B1D0395003073D9 /* Resources */, + FFE0BCF30339E7A50A989EAB /* Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RouteGuideClient; + productName = RouteGuideClient; + productReference = 6325277D1B1D0396003073D9 /* RouteGuideClient.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 632527751B1D0395003073D9 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = gRPC; + TargetAttributes = { + 6325277C1B1D0395003073D9 = { + CreatedOnToolsVersion = 6.3.1; + }; + }; + }; + buildConfigurationList = 632527781B1D0395003073D9 /* Build configuration list for PBXProject "RouteGuideClient" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 632527741B1D0395003073D9; + productRefGroup = 6325277E1B1D0396003073D9 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6325277C1B1D0395003073D9 /* RouteGuideClient */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 6325277B1B1D0395003073D9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6325278F1B1D0396003073D9 /* Main.storyboard in Resources */, + 632527911B1D0396003073D9 /* Images.xcassets in Resources */, + 6367B55B1B223AFA008861F5 /* route_guide_db.json in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + C6FC30AD2376EC04317237C5 /* Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + FFE0BCF30339E7A50A989EAB /* Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RouteGuideClient/Pods-RouteGuideClient-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 632527791B1D0395003073D9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 632527861B1D0396003073D9 /* AppDelegate.m in Sources */, + 632527831B1D0396003073D9 /* main.m in Sources */, + 63A6015C1B1DAB5000FA5B86 /* ViewControllers.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6325278D1B1D0396003073D9 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6325278E1B1D0396003073D9 /* Base */, + ); + name = Main.storyboard; + path = Misc; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 632527A11B1D0396003073D9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 632527A21B1D0396003073D9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 632527A41B1D0396003073D9 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = ADA4C647BAE906F79AD9A45E /* Pods-RouteGuideClient.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = Misc/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 632527A51B1D0396003073D9 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C83C5A54D1A4EA07569F1AED /* Pods-RouteGuideClient.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = Misc/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 632527781B1D0395003073D9 /* Build configuration list for PBXProject "RouteGuideClient" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 632527A11B1D0396003073D9 /* Debug */, + 632527A21B1D0396003073D9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 632527A31B1D0396003073D9 /* Build configuration list for PBXNativeTarget "RouteGuideClient" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 632527A41B1D0396003073D9 /* Debug */, + 632527A51B1D0396003073D9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 632527751B1D0395003073D9 /* Project object */; +} diff --git a/examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..f208589e44 --- /dev/null +++ b/examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/examples/objective-c/route_guide/ViewControllers.m b/examples/objective-c/route_guide/ViewControllers.m new file mode 100644 index 0000000000..cfc3338bca --- /dev/null +++ b/examples/objective-c/route_guide/ViewControllers.m @@ -0,0 +1,228 @@ +/* + * + * 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. + * + */ + +#import +#import +#import +#import + +static NSString * const kHostAddress = @"http://localhost:50051"; + +// Category to override RTGPoint's description. +@interface RTGPoint (Description) +- (NSString *)description; +@end + +@implementation RTGPoint (Description) +- (NSString *)description { + NSString *verticalDirection = self.latitude >= 0 ? @"N" : @"S"; + NSString *horizontalDirection = self.longitude >= 0 ? @"E" : @"W"; + return [NSString stringWithFormat:@"%.02f%@ %.02f%@", + abs(self.latitude) / 1E7f, verticalDirection, + abs(self.longitude) / 1E7f, horizontalDirection]; +} +@end + +// Category to give RTGRouteNote a convenience constructor. +@interface RTGRouteNote (Constructors) ++ (instancetype)noteWithMessage:(NSString *)message + latitude:(float)latitude + longitude:(float)longitude; +@end + +@implementation RTGRouteNote (Constructors) ++ (instancetype)noteWithMessage:(NSString *)message + latitude:(float)latitude + longitude:(float)longitude { + RTGRouteNote *note = [self message]; + note.message = message; + note.location.latitude = (int32_t) latitude * 1E7; + note.location.longitude = (int32_t) longitude * 1E7; + return note; +} +@end + + +#pragma mark Demo: Get Feature + +// Run the getFeature demo. Calls getFeature with a point known to have a feature and a point known +// not to have a feature. + +@interface GetFeatureViewController : UIViewController +@end + +@implementation GetFeatureViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + + void (^handler)(RTGFeature *response, NSError *error) = ^(RTGFeature *response, NSError *error) { + if (response.name.length) { + NSLog(@"Found feature called %@ at %@.", response.name, response.location); + } else if (response) { + NSLog(@"Found no features at %@", response.location); + } else { + NSLog(@"RPC error: %@", error); + } + }; + + RTGPoint *point = [RTGPoint message]; + point.latitude = 409146138; + point.longitude = -746188906; + + [client getFeatureWithRequest:point handler:handler]; + [client getFeatureWithRequest:[RTGPoint message] handler:handler]; +} + +@end + + +#pragma mark Demo: List Features + +// Run the listFeatures demo. Calls listFeatures with a rectangle containing all of the features in +// the pre-generated database. Prints each response as it comes in. + +@interface ListFeaturesViewController : UIViewController +@end + +@implementation ListFeaturesViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + + RTGRectangle *rectangle = [RTGRectangle message]; + rectangle.lo.latitude = 405E6; + rectangle.lo.longitude = -750E6; + rectangle.hi.latitude = 410E6; + rectangle.hi.longitude = -745E6; + + NSLog(@"Looking for features between %@ and %@", rectangle.lo, rectangle.hi); + [client listFeaturesWithRequest:rectangle + eventHandler:^(BOOL done, RTGFeature *response, NSError *error) { + if (response) { + NSLog(@"Found feature at %@ called %@.", response.location, response.name); + } else if (error) { + NSLog(@"RPC error: %@", error); + } + }]; +} + +@end + + +#pragma mark Demo: Record Route + +// Run the recordRoute demo. Sends several randomly chosen points from the pre-generated feature +// database with a variable delay in between. Prints the statistics when they are sent from the +// server. + +@interface RecordRouteViewController : UIViewController +@end + +@implementation RecordRouteViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + NSString *dataBasePath = [NSBundle.mainBundle pathForResource:@"route_guide_db" + ofType:@"json"]; + NSData *dataBaseContent = [NSData dataWithContentsOfFile:dataBasePath]; + NSArray *features = [NSJSONSerialization JSONObjectWithData:dataBaseContent options:0 error:NULL]; + + GRXWriter *locations = [[GRXWriter writerWithContainer:features] map:^id(id feature) { + RTGPoint *location = [RTGPoint message]; + location.longitude = [((NSNumber *) feature[@"location"][@"longitude"]) intValue]; + location.latitude = [((NSNumber *) feature[@"location"][@"latitude"]) intValue]; + NSLog(@"Visiting point %@", location); + return location; + }]; + + RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + + [client recordRouteWithRequestsWriter:locations handler:^(RTGRouteSummary *response, NSError *error) { + if (response) { + NSLog(@"Finished trip with %i points", response.pointCount); + NSLog(@"Passed %i features", response.featureCount); + NSLog(@"Travelled %i meters", response.distance); + NSLog(@"It took %i seconds", response.elapsedTime); + } else { + NSLog(@"RPC error: %@", error); + } + }]; +} + +@end + + +#pragma mark Demo: Route Chat + +// Run the routeChat demo. Send some chat messages, and print any chat messages that are sent from +// the server. + +@interface RouteChatViewController : UIViewController +@end + +@implementation RouteChatViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + NSArray *notes = @[[RTGRouteNote noteWithMessage:@"First message" latitude:0 longitude:0], + [RTGRouteNote noteWithMessage:@"Second message" latitude:0 longitude:1], + [RTGRouteNote noteWithMessage:@"Third message" latitude:1 longitude:0], + [RTGRouteNote noteWithMessage:@"Fourth message" latitude:0 longitude:0]]; + GRXWriter *notesWriter = [[GRXWriter writerWithContainer:notes] map:^id(RTGRouteNote *note) { + NSLog(@"Sending message %@ at %@", note.message, note.location); + return note; + }]; + + RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + + [client routeChatWithRequestsWriter:notesWriter + eventHandler:^(BOOL done, RTGRouteNote *note, NSError *error) { + if (note) { + NSLog(@"Got message %@ at %@", note.message, note.location); + } else if (error) { + NSLog(@"RPC error: %@", error); + } + if (done) { + NSLog(@"Chat ended."); + } + }]; +} + +@end diff --git a/examples/objective-c/route_guide/route_guide_db.json b/examples/objective-c/route_guide/route_guide_db.json new file mode 100644 index 0000000000..9caebaa433 --- /dev/null +++ b/examples/objective-c/route_guide/route_guide_db.json @@ -0,0 +1,121 @@ +[{ + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" +}, { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" +}, { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" +}, { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" +}, { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" +}, { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" +}, { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" +}, { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" +}, { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" +}, { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" +}, { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" +}, { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" +}, { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" +}, { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" +}, { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" +}, { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" +}, { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" +}, { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" +}, { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" +}, { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" +}] diff --git a/examples/php/.gitignore b/examples/php/.gitignore new file mode 100644 index 0000000000..d8a7996ab3 --- /dev/null +++ b/examples/php/.gitignore @@ -0,0 +1,2 @@ +composer.lock +vendor/ diff --git a/examples/php/README.md b/examples/php/README.md new file mode 100644 index 0000000000..247235adfd --- /dev/null +++ b/examples/php/README.md @@ -0,0 +1,64 @@ +gRPC in 3 minutes (PHP) +=========================== + +PREREQUISITES +------------- + +This requires PHP 5.5 or greater. + +INSTALL +------- + - On Mac OS X, install [homebrew][]. On Linux, install [linuxbrew][]. Run the following command to install gRPC. + + ```sh + $ curl -fsSL https://goo.gl/getgrpc | bash -s php + ``` + This will download and run the [gRPC install script][] and compile the gRPC PHP extension. + + - Clone this repository + + ```sh + $ git clone https://github.com/grpc/grpc-common.git + ``` + + - Install composer + + ``` + $ cd grpc-common/php + $ curl -sS https://getcomposer.org/installer | php + $ php composer.phar install + ``` + +TRY IT! +------- + + - Run the server + + Please follow the instruction in [Node][] to run the server + ``` + $ cd grpc-common/node + $ nodejs greeter_server.js + ``` + + - Run the client + + ``` + $ cd grpc-common/php + $ ./run_greeter_client.sh + ``` + +NOTE +---- + +This directory has a copy of `helloworld.proto` because it currently depends on +some Protocol Buffer 2.0 syntax. There is no proto3 support for PHP yet. + +TUTORIAL +-------- + +Coming soon + +[homebrew]:http://brew.sh +[linuxbrew]:https://github.com/Homebrew/linuxbrew#installation +[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install +[Node]:https://github.com/grpc/grpc-common/tree/master/node diff --git a/examples/php/composer.json b/examples/php/composer.json new file mode 100644 index 0000000000..f0ce3a2aff --- /dev/null +++ b/examples/php/composer.json @@ -0,0 +1,17 @@ +{ + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/stanley-cheung/Protobuf-PHP" + } + ], + "name": "grpc/grpc-demo", + "description": "gRPC example for PHP", + "minimum-stability": "dev", + "require": { + "php": ">=5.5.0", + "datto/protobuf-php": "dev-master", + "google/auth": "dev-master", + "grpc/grpc": "dev-master" + } +} diff --git a/examples/php/greeter_client.php b/examples/php/greeter_client.php new file mode 100644 index 0000000000..8ae19ae46c --- /dev/null +++ b/examples/php/greeter_client.php @@ -0,0 +1,49 @@ +setName($name); + list($reply, $status) = $client->SayHello($request)->wait(); + $message = $reply->getMessage(); + return $message; +} + +$name = !empty($argv[1]) ? $argv[1] : 'world'; +print(greet($name)."\n"); diff --git a/examples/php/helloworld.php b/examples/php/helloworld.php new file mode 100644 index 0000000000..22da3d3970 --- /dev/null +++ b/examples/php/helloworld.php @@ -0,0 +1,160 @@ +number = 1; + $f->name = "name"; + $f->type = \DrSlump\Protobuf::TYPE_STRING; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasName(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \helloworld\HelloRequest + */ + public function clearName(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return string + */ + public function getName(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param string $value + * @return \helloworld\HelloRequest + */ + public function setName( $value){ + return $this->_set(1, $value); + } + } +} + +namespace helloworld { + + class HelloReply extends \DrSlump\Protobuf\Message { + + /** @var string */ + public $message = null; + + + /** @var \Closure[] */ + protected static $__extensions = array(); + + public static function descriptor() + { + $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloReply'); + + // OPTIONAL STRING message = 1 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 1; + $f->name = "message"; + $f->type = \DrSlump\Protobuf::TYPE_STRING; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasMessage(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \helloworld\HelloReply + */ + public function clearMessage(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return string + */ + public function getMessage(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param string $value + * @return \helloworld\HelloReply + */ + public function setMessage( $value){ + return $this->_set(1, $value); + } + } +} + +namespace helloworld { + + class GreeterClient{ + + private $rpc_impl; + + public function __construct($rpc_impl) { + $this->rpc_impl = $rpc_impl; + } + /** + * @param helloworld\HelloRequest $input + */ + public function SayHello(\helloworld\HelloRequest $argument, $metadata = array()) { + return $this->rpc_impl->_simpleRequest('/helloworld.Greeter/SayHello', $argument, '\helloworld\HelloReply::deserialize', $metadata); + } + } +} diff --git a/examples/php/helloworld.proto b/examples/php/helloworld.proto new file mode 100644 index 0000000000..ad8f7a1524 --- /dev/null +++ b/examples/php/helloworld.proto @@ -0,0 +1,50 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto2"; + +option java_package = "ex.grpc"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + optional string name = 1; +} + +// The response message containing the greetings +message HelloReply { + optional string message = 1; +} diff --git a/examples/php/route_guide/README.md b/examples/php/route_guide/README.md new file mode 100644 index 0000000000..084661a5eb --- /dev/null +++ b/examples/php/route_guide/README.md @@ -0,0 +1,262 @@ +#gRPC Basics: PHP + +This tutorial provides a basic PHP programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate client code using the protocol buffer compiler. +- Use the PHP gRPC API to write a simple client for your service. + +It assumes a passing familiarity with [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto2 version of the protocol buffers language. + +Also note that currently you can only create clients in PHP for gRPC services - you can find out how to create gRPC servers in our other tutorials, e.g. [Node.js](https://github.com/grpc/grpc-common/tree/master/node/route_guide). + +This isn't a comprehensive guide to using gRPC in PHP: more reference documentation is coming soon. + +- [Why use gRPC?](#why-grpc) +- [Example code and setup](#setup) +- [Try it out!](#try) +- [Defining the service](#proto) +- [Generating client code](#protoc) +- [Creating the client](#client) + + + +## Why use gRPC? + +With gRPC you can define your service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. You also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + + + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/php/route_guide](https://github.com/grpc/grpc-common/tree/master/php/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/php/route_guide`: +```shell +$ cd grpc-common/php/route_guide +``` + +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +You also should have the relevant tools installed to generate the client interface code (and a server in another language, for testing). You can obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). + + + +## Try it out! + +To try the sample app, we need a gRPC server running locally. Let's compile and run, for example, the Node.js server in this repository: + +```shell +$ cd ../../node +$ npm install +$ cd route_guide +$ nodejs ./route_guide_server.js --db_path=route_guide_db.json +``` + +Run the PHP client (in a different terminal): + +```shell +$ ./run_route_guide_client.sh +``` + +The next sections guide you step-by-step through how this proto service is defined, how to generate a client library from it, and how to create a client stub that uses that library. + + + +## Defining the service + +First let's look at how the service we're using is defined. A gRPC *service* and its method *request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file for our example in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +```protobuf +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. Protocol buffers let you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server and receives a response later, just like a normal remote procedure call. +```protobuf + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *response-streaming RPC* where the client sends a request to the server and gets back a stream of response messages. You specify a response-streaming method by placing the `stream` keyword before the *response* type. +```protobuf + // 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 *request-streaming RPC* where the client sends a sequence of messages to the server. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a request-streaming method by placing the `stream` keyword before the *request* type. +```protobuf + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages to the other. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +```protobuf + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +```protobuf +// 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; +} +``` + + + +## Generating client code + +The PHP client stub implementation of the proto files can be generated by the [`protoc-gen-php`](https://github.com/datto/protobuf-php) tool. To install the tool: + +```sh +$ cd grpc-common/php +$ php composer.phar install +$ cd vendor/datto/protobuf-php +$ gem install rake ronn +$ rake pear:package version=1.0 +$ sudo pear install Protobuf-1.0.tgz +``` + +To generate the client stub implementation .php file: + +```sh +$ cd php/route_guide +$ protoc-gen-php -i . -o . ./route_guide.proto +``` + +A `route_guide.php` file will be generated in the `php/route_guide` directory. You do not need to modify the file. + +To load the generated client stub file, simply `require` it in your PHP application: + +```php +require dirname(__FILE__) . '/route_guide.php'; +``` + +The file contains: +- All the protocol buffer code to populate, serialize, and retrieve our request and response message types. +- A class called `examples\RouteGuideClient` that lets clients call the methods defined in the `RouteGuide` service. + + + +## Creating the client + +In this section, we'll look at creating a PHP client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/php/route_guide/route_guide_client.php](https://github.com/grpc/grpc-common/blob/master/php/route_guide/route_guide_client.php). + +### Constructing a client object + +To call service methods, we first need to create a client object, an instance of the generated `RouteGuideClient` class. The constructor of the class expects the server address and port we want to connect to: + +```php +$client = new examples\RouteGuideClient(new Grpc\BaseStub('localhost:50051', [])); +``` + +### Calling service methods + +Now let's look at how we call our service methods. + +#### Simple RPC + +Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local asynchronous method. + +```php + $point = new examples\Point(); + $point->setLatitude(409146138); + $point->setLongitude(-746188906); + list($feature, $status) = $client->GetFeature($point)->wait(); +``` + +As you can see, we create and populate a request object, i.e. an `examples\Point` object. Then, we call the method on the stub, passing it the request object. If there is no error, then we can read the response information from the server from our response object, i.e. an `examples\Feature` object. + +```php + print sprintf("Found %s \n at %f, %f\n", $feature->getName(), + $feature->getLocation()->getLatitude() / COORD_FACTOR, + $feature->getLocation()->getLongitude() / COORD_FACTOR); +``` + +#### Streaming RPCs + +Now let's look at our streaming methods. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: + +```php + $lo_point = new examples\Point(); + $hi_point = new examples\Point(); + + $lo_point->setLatitude(400000000); + $lo_point->setLongitude(-750000000); + $hi_point->setLatitude(420000000); + $hi_point->setLongitude(-730000000); + + $rectangle = new examples\Rectangle(); + $rectangle->setLo($lo_point); + $rectangle->setHi($hi_point); + + $call = $client->ListFeatures($rectangle); + // an iterator over the server streaming responses + $features = $call->responses(); + foreach ($features as $feature) { + // process each feature + } // the loop will end when the server indicates there is no more responses to be sent. +``` + +The `$call->responses()` method call returns an iterator. When the server sends a response, a `$feature` object will be returned in the `foreach` loop, until the server indiciates that there will be no more responses to be sent. + +The client-side streaming method `RecordRoute` is similar, except there we pass the method an iterator and get back a `examples\RouteSummary`. + +```php + $points_iter = function($db) { + for ($i = 0; $i < $num_points; $i++) { + $point = new examples\Point(); + $point->setLatitude($lat); + $point->setLongitude($long); + yield $point; + } + }; + // $points_iter is an iterator simulating client streaming + list($route_summary, $status) = + $client->RecordRoute($points_iter($db))->wait(); +``` + +Finally, let's look at our bidirectional streaming RPC `routeChat()`. In this case, we just pass a context to the method and get back a `BidiStreamingCall` stream object, which we can use to both write and read messages. + +```php +$call = $client->RouteChat(); +``` + +To write messages from the client: + +```php + foreach ($notes as $n) { + $route_note = new examples\RouteNote(); + $call->write($route_note); + } + $call->writesDone(); +``` + +To read messages from the server: + +```php + while ($route_note_reply = $call->read()) { + // process $route_note_reply + } +``` + +Each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. diff --git a/examples/php/route_guide/route_guide.php b/examples/php/route_guide/route_guide.php new file mode 100644 index 0000000000..a836e03b55 --- /dev/null +++ b/examples/php/route_guide/route_guide.php @@ -0,0 +1,731 @@ +number = 1; + $f->name = "latitude"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + // OPTIONAL INT32 longitude = 2 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 2; + $f->name = "longitude"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasLatitude(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \examples\Point + */ + public function clearLatitude(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return int + */ + public function getLatitude(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param int $value + * @return \examples\Point + */ + public function setLatitude( $value){ + return $this->_set(1, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasLongitude(){ + return $this->_has(2); + } + + /** + * Clear value + * + * @return \examples\Point + */ + public function clearLongitude(){ + return $this->_clear(2); + } + + /** + * Get value + * + * @return int + */ + public function getLongitude(){ + return $this->_get(2); + } + + /** + * Set value + * + * @param int $value + * @return \examples\Point + */ + public function setLongitude( $value){ + return $this->_set(2, $value); + } + } +} + +namespace examples { + + class Rectangle extends \DrSlump\Protobuf\Message { + + /** @var \examples\Point */ + public $lo = null; + + /** @var \examples\Point */ + public $hi = null; + + + /** @var \Closure[] */ + protected static $__extensions = array(); + + public static function descriptor() + { + $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.Rectangle'); + + // OPTIONAL MESSAGE lo = 1 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 1; + $f->name = "lo"; + $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->reference = '\examples\Point'; + $descriptor->addField($f); + + // OPTIONAL MESSAGE hi = 2 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 2; + $f->name = "hi"; + $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->reference = '\examples\Point'; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasLo(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \examples\Rectangle + */ + public function clearLo(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return \examples\Point + */ + public function getLo(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param \examples\Point $value + * @return \examples\Rectangle + */ + public function setLo(\examples\Point $value){ + return $this->_set(1, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasHi(){ + return $this->_has(2); + } + + /** + * Clear value + * + * @return \examples\Rectangle + */ + public function clearHi(){ + return $this->_clear(2); + } + + /** + * Get value + * + * @return \examples\Point + */ + public function getHi(){ + return $this->_get(2); + } + + /** + * Set value + * + * @param \examples\Point $value + * @return \examples\Rectangle + */ + public function setHi(\examples\Point $value){ + return $this->_set(2, $value); + } + } +} + +namespace examples { + + class Feature extends \DrSlump\Protobuf\Message { + + /** @var string */ + public $name = null; + + /** @var \examples\Point */ + public $location = null; + + + /** @var \Closure[] */ + protected static $__extensions = array(); + + public static function descriptor() + { + $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.Feature'); + + // OPTIONAL STRING name = 1 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 1; + $f->name = "name"; + $f->type = \DrSlump\Protobuf::TYPE_STRING; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $descriptor->addField($f); + + // OPTIONAL MESSAGE location = 2 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 2; + $f->name = "location"; + $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->reference = '\examples\Point'; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasName(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \examples\Feature + */ + public function clearName(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return string + */ + public function getName(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param string $value + * @return \examples\Feature + */ + public function setName( $value){ + return $this->_set(1, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasLocation(){ + return $this->_has(2); + } + + /** + * Clear value + * + * @return \examples\Feature + */ + public function clearLocation(){ + return $this->_clear(2); + } + + /** + * Get value + * + * @return \examples\Point + */ + public function getLocation(){ + return $this->_get(2); + } + + /** + * Set value + * + * @param \examples\Point $value + * @return \examples\Feature + */ + public function setLocation(\examples\Point $value){ + return $this->_set(2, $value); + } + } +} + +namespace examples { + + class RouteNote extends \DrSlump\Protobuf\Message { + + /** @var \examples\Point */ + public $location = null; + + /** @var string */ + public $message = null; + + + /** @var \Closure[] */ + protected static $__extensions = array(); + + public static function descriptor() + { + $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.RouteNote'); + + // OPTIONAL MESSAGE location = 1 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 1; + $f->name = "location"; + $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->reference = '\examples\Point'; + $descriptor->addField($f); + + // OPTIONAL STRING message = 2 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 2; + $f->name = "message"; + $f->type = \DrSlump\Protobuf::TYPE_STRING; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasLocation(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \examples\RouteNote + */ + public function clearLocation(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return \examples\Point + */ + public function getLocation(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param \examples\Point $value + * @return \examples\RouteNote + */ + public function setLocation(\examples\Point $value){ + return $this->_set(1, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasMessage(){ + return $this->_has(2); + } + + /** + * Clear value + * + * @return \examples\RouteNote + */ + public function clearMessage(){ + return $this->_clear(2); + } + + /** + * Get value + * + * @return string + */ + public function getMessage(){ + return $this->_get(2); + } + + /** + * Set value + * + * @param string $value + * @return \examples\RouteNote + */ + public function setMessage( $value){ + return $this->_set(2, $value); + } + } +} + +namespace examples { + + class RouteSummary extends \DrSlump\Protobuf\Message { + + /** @var int */ + public $point_count = 0; + + /** @var int */ + public $feature_count = 0; + + /** @var int */ + public $distance = 0; + + /** @var int */ + public $elapsed_time = 0; + + + /** @var \Closure[] */ + protected static $__extensions = array(); + + public static function descriptor() + { + $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.RouteSummary'); + + // OPTIONAL INT32 point_count = 1 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 1; + $f->name = "point_count"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + // OPTIONAL INT32 feature_count = 2 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 2; + $f->name = "feature_count"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + // OPTIONAL INT32 distance = 3 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 3; + $f->name = "distance"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + // OPTIONAL INT32 elapsed_time = 4 + $f = new \DrSlump\Protobuf\Field(); + $f->number = 4; + $f->name = "elapsed_time"; + $f->type = \DrSlump\Protobuf::TYPE_INT32; + $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; + $f->default = 0; + $descriptor->addField($f); + + foreach (self::$__extensions as $cb) { + $descriptor->addField($cb(), true); + } + + return $descriptor; + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasPointCount(){ + return $this->_has(1); + } + + /** + * Clear value + * + * @return \examples\RouteSummary + */ + public function clearPointCount(){ + return $this->_clear(1); + } + + /** + * Get value + * + * @return int + */ + public function getPointCount(){ + return $this->_get(1); + } + + /** + * Set value + * + * @param int $value + * @return \examples\RouteSummary + */ + public function setPointCount( $value){ + return $this->_set(1, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasFeatureCount(){ + return $this->_has(2); + } + + /** + * Clear value + * + * @return \examples\RouteSummary + */ + public function clearFeatureCount(){ + return $this->_clear(2); + } + + /** + * Get value + * + * @return int + */ + public function getFeatureCount(){ + return $this->_get(2); + } + + /** + * Set value + * + * @param int $value + * @return \examples\RouteSummary + */ + public function setFeatureCount( $value){ + return $this->_set(2, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasDistance(){ + return $this->_has(3); + } + + /** + * Clear value + * + * @return \examples\RouteSummary + */ + public function clearDistance(){ + return $this->_clear(3); + } + + /** + * Get value + * + * @return int + */ + public function getDistance(){ + return $this->_get(3); + } + + /** + * Set value + * + * @param int $value + * @return \examples\RouteSummary + */ + public function setDistance( $value){ + return $this->_set(3, $value); + } + + /** + * Check if has a value + * + * @return boolean + */ + public function hasElapsedTime(){ + return $this->_has(4); + } + + /** + * Clear value + * + * @return \examples\RouteSummary + */ + public function clearElapsedTime(){ + return $this->_clear(4); + } + + /** + * Get value + * + * @return int + */ + public function getElapsedTime(){ + return $this->_get(4); + } + + /** + * Set value + * + * @param int $value + * @return \examples\RouteSummary + */ + public function setElapsedTime( $value){ + return $this->_set(4, $value); + } + } +} + +namespace examples { + + class RouteGuideClient{ + + private $rpc_impl; + + public function __construct($rpc_impl) { + $this->rpc_impl = $rpc_impl; + } + /** + * @param examples\Point $input + */ + public function GetFeature(\examples\Point $argument, $metadata = array()) { + return $this->rpc_impl->_simpleRequest('/examples.RouteGuide/GetFeature', $argument, '\examples\Feature::deserialize', $metadata); + } + /** + * @param examples\Rectangle $input + */ + public function ListFeatures($argument, $metadata = array()) { + return $this->rpc_impl->_serverStreamRequest('/examples.RouteGuide/ListFeatures', $argument, '\examples\Feature::deserialize', $metadata); + } + /** + * @param examples\Point $input + */ + public function RecordRoute($arguments, $metadata = array()) { + return $this->rpc_impl->_clientStreamRequest('/examples.RouteGuide/RecordRoute', $arguments, '\examples\RouteSummary::deserialize', $metadata); + } + /** + * @param examples\RouteNote $input + */ + public function RouteChat($metadata = array()) { + return $this->rpc_impl->_bidiRequest('/examples.RouteGuide/RouteChat', '\examples\RouteNote::deserialize', $metadata); + } + } +} diff --git a/examples/php/route_guide/route_guide.proto b/examples/php/route_guide/route_guide.proto new file mode 100644 index 0000000000..0947184dbb --- /dev/null +++ b/examples/php/route_guide/route_guide.proto @@ -0,0 +1,120 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto2"; + +option java_package = "io.grpc.examples"; + +package examples; + +// Interface exported by the server. +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} + + // A server-to-client streaming RPC. + // + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} + + // A client-to-server streaming RPC. + // + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} + + // A Bidirectional streaming RPC. + // + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +} + +// Points are represented as latitude-longitude pairs in the E7 representation +// (degrees multiplied by 10**7 and rounded to the nearest integer). +// Latitudes should be in the range +/- 90 degrees and longitude should be in +// the range +/- 180 degrees (inclusive). +message Point { + optional int32 latitude = 1 [default = 0]; + optional int32 longitude = 2 [default = 0]; +} + +// A latitude-longitude rectangle, represented as two diagonally opposite +// points "lo" and "hi". +message Rectangle { + // One corner of the rectangle. + optional Point lo = 1; + + // The other corner of the rectangle. + optional Point hi = 2; +} + +// A feature names something at a given point. +// +// If a feature could not be named, the name is empty. +message Feature { + // The name of the feature. + optional string name = 1; + + // The point where the feature is detected. + optional Point location = 2; +} + +// A RouteNote is a message sent while at a given point. +message RouteNote { + // The location from which the message is sent. + optional Point location = 1; + + // The message to be sent. + optional string message = 2; +} + +// A RouteSummary is received in response to a RecordRoute rpc. +// +// It contains the number of individual points received, the number of +// detected features, and the total distance covered as the cumulative sum of +// the distance between each point. +message RouteSummary { + // The number of points received. + optional int32 point_count = 1 [default = 0]; + + // The number of known features passed while traversing the route. + optional int32 feature_count = 2 [default = 0]; + + // The distance covered in metres. + optional int32 distance = 3 [default = 0]; + + // The duration of the traversal in seconds. + optional int32 elapsed_time = 4 [default = 0]; +} diff --git a/examples/php/route_guide/route_guide_client.php b/examples/php/route_guide/route_guide_client.php new file mode 100644 index 0000000000..6d9ae58b66 --- /dev/null +++ b/examples/php/route_guide/route_guide_client.php @@ -0,0 +1,205 @@ +getName(); + if (!$name) { + $name_str = "no feature"; + } else { + $name_str = "feature called $name"; + } + print sprintf("Found %s \n at %f, %f\n", $name_str, + $feature->getLocation()->getLatitude() / COORD_FACTOR, + $feature->getLocation()->getLongitude() / COORD_FACTOR); +} + +/** + * Run the getFeature demo. Calls getFeature with a point known to have a + * feature and a point known not to have a feature. + */ +function runGetFeature() { + print "Running GetFeature...\n"; + global $client; + + $point = new examples\Point(); + $points = array( + array(409146138, -746188906), + array(0, 0), + ); + + foreach ($points as $p) { + $point->setLatitude($p[0]); + $point->setLongitude($p[1]); + // make a unary grpc call + list($feature, $status) = $client->GetFeature($point)->wait(); + printFeature($feature); + } +} + +/** + * Run the listFeatures demo. Calls listFeatures with a rectangle + * containing all of the features in the pre-generated + * database. Prints each response as it comes in. + */ +function runListFeatures() { + print "Running ListFeatures...\n"; + global $client; + + $lo_point = new examples\Point(); + $hi_point = new examples\Point(); + + $lo_point->setLatitude(400000000); + $lo_point->setLongitude(-750000000); + $hi_point->setLatitude(420000000); + $hi_point->setLongitude(-730000000); + + $rectangle = new examples\Rectangle(); + $rectangle->setLo($lo_point); + $rectangle->setHi($hi_point); + + $call = $client->ListFeatures($rectangle); + // an iterator over the server streaming responses + $features = $call->responses(); + foreach ($features as $feature) { + printFeature($feature); + } +} + +/** + * Run the recordRoute demo. Sends several randomly chosen points from the + * pre-generated feature database with a variable delay in between. Prints + * the statistics when they are sent from the server. + */ +function runRecordRoute() { + print "Running RecordRoute...\n"; + global $client, $argv; + + $db = json_decode(file_get_contents($argv[1]), true); + $points_iter = function($db) { + $num_points_in_db = count($db); + $num_points = 10; + for ($i = 0; $i < $num_points; $i++) { + $point = new examples\Point(); + $index = rand(0, $num_points_in_db - 1); + $lat = $db[$index]['location']['latitude']; + $long = $db[$index]['location']['longitude']; + $feature_name = $db[$index]['name']; + $point->setLatitude($lat); + $point->setLongitude($long); + print sprintf("Visiting point %f, %f,\n with feature name: %s\n", + $lat / COORD_FACTOR, $long / COORD_FACTOR, + $feature_name ? $feature_name : ''); + usleep(rand(300000, 800000)); + yield $point; + } + }; + // $points_iter is an iterator simulating client streaming + list($route_summary, $status) = + $client->RecordRoute($points_iter($db))->wait(); + print sprintf("Finished trip with %d points\nPassed %d features\n". + "Travelled %d meters\nIt took %d seconds\n", + $route_summary->getPointCount(), + $route_summary->getFeatureCount(), + $route_summary->getDistance(), + $route_summary->getElapsedTime()); +} + +/** + * Run the routeChat demo. Send some chat messages, and print any chat + * messages that are sent from the server. + */ +function runRouteChat() { + print "Running RouteChat...\n"; + global $client; + + // start the bidirectional streaming call + $call = $client->RouteChat(); + + $notes = array( + array(1, 1, 'first message'), + array(1, 2, 'second message'), + array(2, 1, 'third message'), + array(1, 1, 'fourth message'), + array(1, 1, 'fifth message'), + ); + + foreach ($notes as $n) { + $point = new examples\Point(); + $point->setLatitude($lat = $n[0]); + $point->setLongitude($long = $n[1]); + + $route_note = new examples\RouteNote(); + $route_note->setLocation($point); + $route_note->setMessage($message = $n[2]); + + print sprintf("Sending message: '%s' at (%d, %d)\n", + $message, $lat, $long); + // send a bunch of messages to the server + $call->write($route_note); + } + $call->writesDone(); + + // read from the server until there's no more + while ($route_note_reply = $call->read()) { + print sprintf("Previous left message at (%d, %d): '%s'\n", + $route_note_reply->getLocation()->getLatitude(), + $route_note_reply->getLocation()->getLongitude(), + $route_note_reply->getMessage()); + } +} + +/** + * Run all of the demos in order + */ +function main() { + runGetFeature(); + runListFeatures(); + runRecordRoute(); + runRouteChat(); +} + +if (empty($argv[1])) { + print "Usage: php -d extension=grpc.so route_guide_client.php " . + "\n"; + exit(1); +} +main(); diff --git a/examples/php/route_guide/run_route_guide_client.sh b/examples/php/route_guide/run_route_guide_client.sh new file mode 100755 index 0000000000..e5ca07796b --- /dev/null +++ b/examples/php/route_guide/run_route_guide_client.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# 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. + +set -e +cd $(dirname $0) +command -v brew >/dev/null 2>&1 && \ + extension_dir="-d extension_dir="`brew --prefix`/opt/grpc-php +php $extension_dir -d extension=grpc.so \ + route_guide_client.php ../../node/route_guide/route_guide_db.json diff --git a/examples/php/run_greeter_client.sh b/examples/php/run_greeter_client.sh new file mode 100755 index 0000000000..2906de9af8 --- /dev/null +++ b/examples/php/run_greeter_client.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# 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. + +set -e +cd $(dirname $0) +command -v brew >/dev/null 2>&1 && \ + extension_dir="-d extension_dir="`brew --prefix`/opt/grpc-php +php $extension_dir -d extension=grpc.so greeter_client.php $1 diff --git a/examples/protos/README.md b/examples/protos/README.md new file mode 100644 index 0000000000..48df7c8943 --- /dev/null +++ b/examples/protos/README.md @@ -0,0 +1,8 @@ +# Example protos + +## Contents + +- [helloworld.proto] + - The simple example used in the overview. +- [route_guide.proto] + - An example service described in detail in the tutorial. diff --git a/examples/protos/auth_sample.proto b/examples/protos/auth_sample.proto new file mode 100644 index 0000000000..a49caca657 --- /dev/null +++ b/examples/protos/auth_sample.proto @@ -0,0 +1,57 @@ +// 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 grpc.testing; + +option objc_class_prefix = "AUTH"; + +// Unary request. +message Request { + // Whether Response should include username. + bool fill_username = 4; + + // Whether Response should include OAuth scope. + bool fill_oauth_scope = 5; +} + +// Unary response, as configured by the request. +message Response { + // The user the request came from, for verifying authentication was + // successful. + string username = 2; + // OAuth scope. + string oauth_scope = 3; +} + +service TestService { + // One request followed by one response. + rpc UnaryCall(Request) returns (Response); +} diff --git a/examples/protos/hellostreamingworld.proto b/examples/protos/hellostreamingworld.proto new file mode 100644 index 0000000000..bd5af3b2d5 --- /dev/null +++ b/examples/protos/hellostreamingworld.proto @@ -0,0 +1,54 @@ +// 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"; +option objc_class_prefix = "HSW"; + +package hellostreamingworld; + +// The greeting service definition. +service MultiGreeter { + // Sends multiple greetings + rpc sayHello (HelloRequest) returns (stream HelloReply) {} +} + +// The request message containing the user's name and how many greetings +// they want. +message HelloRequest { + string name = 1; + string num_greetings = 2; +} + +// A response message containing a greeting +message HelloReply { + string message = 1; +} + diff --git a/examples/protos/helloworld.proto b/examples/protos/helloworld.proto new file mode 100644 index 0000000000..7d58870a70 --- /dev/null +++ b/examples/protos/helloworld.proto @@ -0,0 +1,51 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "io.grpc.examples"; +option objc_class_prefix = "HLW"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} diff --git a/examples/protos/route_guide.proto b/examples/protos/route_guide.proto new file mode 100644 index 0000000000..bfde5f1ead --- /dev/null +++ b/examples/protos/route_guide.proto @@ -0,0 +1,124 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "ex.grpc"; +option objc_class_prefix = "RTG"; + +package examples; + +// Interface exported by the server. +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + // + // A feature with an empty name is returned if there's no feature at the 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/examples/python/helloworld/.gitignore b/examples/python/helloworld/.gitignore new file mode 100644 index 0000000000..0d20b6487c --- /dev/null +++ b/examples/python/helloworld/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/examples/python/helloworld/README.md b/examples/python/helloworld/README.md new file mode 100644 index 0000000000..0a6a718bae --- /dev/null +++ b/examples/python/helloworld/README.md @@ -0,0 +1,116 @@ +# gRPC Python Hello World + +This is a quick introduction with a simple example and installation instructions: for a more complete tutorial see [gRPC Basics: Python](https://github.com/grpc/grpc-common/tree/master/python/route_guide). + +### Install gRPC +Make sure you have built gRPC Python from source on your system. Follow the instructions here: +[https://github.com/grpc/grpc/blob/master/src/python/README.md](https://github.com/grpc/grpc/blob/master/src/python/README.md). + +This gives you a python virtual environment with installed gRPC Python +in GRPC_ROOT/python2.7_virtual_environment. GRPC_ROOT is the path to which you +have cloned the [gRPC git repo](https://github.com/grpc/grpc). + +### Get the source code + +The example code for our Hello World and our other examples live in the `grpc-common` +GitHub repository. Clone this repository to your local machine by running the +following command: + + +```sh +$ git clone https://github.com/grpc/grpc-common.git +``` + +Change your current directory to grpc-common/python/helloworld + +```sh +$ cd grpc-common/python/helloworld/ +``` + +### Defining a service + +The first step in creating our example is to define a *service*: an RPC +service specifies the methods that can be called remotely with their parameters +and return types. As you saw in the +[overview](#protocolbuffers) above, gRPC does this using [protocol +buffers](https://developers.google.com/protocol-buffers/docs/overview). We +use the protocol buffers interface definition language (IDL) to define our +service methods, and define the parameters and return +types as protocol buffer message types. Both the client and the +server use interface code generated from the service definition. + +Here's our example service definition. The `Greeting` +service has one method, `hello`, that lets the server receive a single +`HelloRequest` +message from the remote client containing the user's name, then send back +a greeting in a single `HelloReply`. This is the simplest type of RPC you +can specify in gRPC. + +``` +syntax = "proto3"; + +option java_package = "io.grpc.examples"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} + +``` + + +### Generating gRPC code + +Once we've defined our service, we use the protocol buffer compiler +`protoc` to generate the special client and server code we need to create +our application. The generated code contains both stub code for clients to +use and an abstract interface for servers to implement, both with the method +defined in our `Greeting` service. + +To generate the client and server side interfaces: + +```sh +$ ./run_codegen.sh +``` +Which internally invokes the proto-compiler as: + +```sh +$ protoc -I ../../protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` ../../protos/helloworld.proto +``` + +Optionally, you can just skip the code generation step as the generated python module has already +been generated for you (helloworld_pb2.py). + +### The client + +Client-side code can be found in [greeter_client.py](https://github.com/grpc/grpc-common/blob/master/python/helloworld/greeter_client.py). + +You can run the client using: + +```sh +$ ./run_client.sh +``` + + +### The server + +Server side code can be found in [greeter_server.py](https://github.com/grpc/grpc-common/blob/master/python/helloworld/greeter_server.py). + +You can run the server using: + +```sh +$ ./run_server.sh +``` diff --git a/examples/python/helloworld/greeter_client.py b/examples/python/helloworld/greeter_client.py new file mode 100755 index 0000000000..370ce46770 --- /dev/null +++ b/examples/python/helloworld/greeter_client.py @@ -0,0 +1,44 @@ +# 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. + +"""The Python implementation of the GRPC helloworld.Greeter client.""" + +import helloworld_pb2 + +_TIMEOUT_SECONDS = 10 + + +def run(): + with helloworld_pb2.early_adopter_create_Greeter_stub('localhost', 50051) as stub: + response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'), _TIMEOUT_SECONDS) + print "Greeter client received: " + response.message + + +if __name__ == '__main__': + run() diff --git a/examples/python/helloworld/greeter_server.py b/examples/python/helloworld/greeter_server.py new file mode 100644 index 0000000000..81353666b1 --- /dev/null +++ b/examples/python/helloworld/greeter_server.py @@ -0,0 +1,56 @@ +# 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. + +"""The Python implementation of the GRPC helloworld.Greeter server.""" + +import time + +import helloworld_pb2 + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +class Greeter(helloworld_pb2.EarlyAdopterGreeterServicer): + + def SayHello(self, request, context): + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) + + +def serve(): + server = helloworld_pb2.early_adopter_create_Greeter_server( + Greeter(), 50051, None, None) + server.start() + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop() + +if __name__ == '__main__': + serve() diff --git a/examples/python/helloworld/run_client.sh b/examples/python/helloworld/run_client.sh new file mode 100755 index 0000000000..095e6bc2f0 --- /dev/null +++ b/examples/python/helloworld/run_client.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# This is where you have cloned out the https://github.com/grpc/grpc repository +# And built gRPC Python. +# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS +GRPC_ROOT=~/github/grpc + +$GRPC_ROOT/python2.7_virtual_environment/bin/python greeter_client.py diff --git a/examples/python/helloworld/run_codegen.sh b/examples/python/helloworld/run_codegen.sh new file mode 100755 index 0000000000..4d826c7946 --- /dev/null +++ b/examples/python/helloworld/run_codegen.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Runs the protoc with gRPC plugin to generate protocol messages and gRPC stubs. +protoc -I ../../protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` ../../protos/helloworld.proto diff --git a/examples/python/helloworld/run_server.sh b/examples/python/helloworld/run_server.sh new file mode 100755 index 0000000000..13b009e6cc --- /dev/null +++ b/examples/python/helloworld/run_server.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# This is where you have cloned out the https://github.com/grpc/grpc repository +# And built gRPC Python. +# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS +GRPC_ROOT=~/github/grpc + +$GRPC_ROOT/python2.7_virtual_environment/bin/python greeter_server.py + diff --git a/examples/python/route_guide/.gitignore b/examples/python/route_guide/.gitignore new file mode 100644 index 0000000000..0d20b6487c --- /dev/null +++ b/examples/python/route_guide/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/examples/python/route_guide/README.md b/examples/python/route_guide/README.md new file mode 100644 index 0000000000..91bef0ac00 --- /dev/null +++ b/examples/python/route_guide/README.md @@ -0,0 +1,303 @@ +#gRPC Basics: Python + +This tutorial provides a basic Python programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate server and client code using the protocol buffer compiler. +- Use the Python gRPC API to write a simple client and server for your service. + +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. + +This isn't a comprehensive guide to using gRPC in Python: more reference documentation is coming soon. + + +## Why use gRPC? + +This example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +With gRPC you can define your service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet, with all the complexity of communication between different languages and environments is handled for you by gRPC. You also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + +## Example code and setup + +The example code for this tutorial is in [grpc/grpc-common/python/route_guide](https://github.com/grpc/grpc-common/tree/master/python/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/python/route_guide`: +```shell +$ cd grpc-common/python/route_guide +``` + +You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Python quick start guide](https://github.com/grpc/grpc-common/tree/master/python). + +## Defining the service + +Your first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +```protobuf +service RouteGuide { + // (Method definitions not shown) +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +```protobuf + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *response-streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in the example, you specify a response-streaming method by placing the `stream` keyword before the *response* type. +```protobuf + // 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 *request-streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a request-streaming method by placing the `stream` keyword before the *request* type. +```protobuf + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectionally-streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +```protobuf + // 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) {} +``` + +Your .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +```protobuf +// 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; +} +``` + +## Generating client and server code + +Next you need to generate the gRPC client and server interfaces from your .proto service definition. You do this using the protocol buffer compiler `protoc` with a special gRPC Python plugin. Make sure you've installed protoc and followed the gRPC Python plugin [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): + +With `protoc` and the gRPC Python plugin installed, use the following command to generate the Python code: + +```shell +$ protoc -I ../../protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` ../../protos/route_guide.proto +``` + +Note that as we've already provided a version of the generated code in the example repository, running this command regenerates the appropriate file rather than creates a new one. The generated code file is called `route_guide_pb2.py` and contains: +- classes for the messages defined in route_guide.proto +- abstract classes for the service defined in route_guide.proto + - `EarlyAdopterRouteGuideServicer`, which defines the interface for implementations of the RouteGuide service + - `EarlyAdopterRouteGuideServer`, which may be started and stopped + - `EarlyAdopterRouteGuideStub`, which can be used by clients to invoke RouteGuide RPCs +- functions for application use + - `early_adopter_create_RouteGuide_server`, which creates a gRPC server given an `EarlyAdopterRouteGuideServicer` object + - `early_adopter_create_RouteGuide_stub`, which can be used by clients to create a stub object + + +## Creating the server + +First let's look at how you create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). + +Creating and running a `RouteGuide` server breaks down into two work items: +- Implementing the servicer interface generated from our service definition with functions that perform the actual "work" of the service. +- Running a gRPC server to listen for requests from clients and transmit responses. + +You can find the example `RouteGuide` server in [grpc-common/python/route_guide/route_guide_server.py](https://github.com/grpc/grpc-common/blob/master/python/route_guide/route_guide_server.py). + +### Implementing RouteGuide + +`route_guide_server.py` has a `RouteGuideServicer` class that implements the generated interface `route_guide_pb2.EarlyAdopterRouteGuideServicer`: + +```python +# RouteGuideServicer provides an implementation of the methods of the RouteGuide service. +class RouteGuideServicer(route_guide_pb2.EarlyAdopterRouteGuideServicer): +``` + +`RouteGuideServicer` implements all the `RouteGuide` service methods. + +#### Simple RPC + +Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. + +```python + def GetFeature(self, request, context): + feature = get_feature(self.db, request) + if feature is None: + return route_guide_pb2.Feature(name="", location=request) + else: + return feature +``` + +The method is passed a `route_guide_pb2.Point` request for the RPC, and an `RpcContext` object that provides RPC-specific information such as timeout limits. It returns a `route_guide_pb2.Feature` response. + +#### Response-streaming RPC + +Now let's look at the next method. `ListFeatures` is a response-streaming RPC that sends multiple `Feature`s to the client. + +```python + def ListFeatures(self, request, context): + left = min(request.lo.longitude, request.hi.longitude) + right = max(request.lo.longitude, request.hi.longitude) + top = max(request.lo.latitude, request.hi.latitude) + bottom = min(request.lo.latitude, request.hi.latitude) + for feature in self.db: + if (feature.location.longitude >= left and + feature.location.longitude <= right and + feature.location.latitude >= bottom and + feature.location.latitude <= top): + yield feature +``` + +Here the request message is a `route_guide_pb2.Rectangle` within which the client wants to find `Feature`s. Instead of returning a single response the method yields zero or more responses. + +#### Request-streaming RPC + +The request-streaming method `RecordRoute` uses an [iterator](https://docs.python.org/2/library/stdtypes.html#iterator-types) of request values and returns a single response value. + +```python + def RecordRoute(self, request_iterator, context): + point_count = 0 + feature_count = 0 + distance = 0.0 + prev_point = None + + start_time = time.time() + for point in request_iterator: + point_count += 1 + if get_feature(self.db, point): + feature_count += 1 + if prev_point: + distance += get_distance(prev_point, point) + prev_point = point + + elapsed_time = time.time() - start_time + return route_guide_pb2.RouteSummary(point_count=point_count, + feature_count=feature_count, + distance=int(distance), + elapsed_time=int(elapsed_time)) +``` + +#### Bidirectional streaming RPC + +Lastly let's look at the bidirectionally-streaming method `RouteChat`. + +```python + def RouteChat(self, request_iterator, context): + prev_notes = [] + for new_note in request_iterator: + for prev_note in prev_notes: + if prev_note.location == new_note.location: + yield prev_note + prev_notes.append(new_note) +``` + +This method's semantics are a combination of those of the request-streaming method and the response-streaming method. It is passed an iterator of request values and is itself an iterator of response values. + +### Starting the server + +Once you have implemented all the `RouteGuide` methods, the next step is to start up a gRPC server so that clients can actually use your service: + +```python +def serve(): + server = route_guide_pb2.early_adopter_create_RouteGuide_server( + RouteGuideServicer(), 50051, None, None) + server.start() +``` + +Because `start()` does not block you may need to sleep-loop if there is nothing else for your code to do while serving. + + +## Creating the client + +You can see the complete example client code in [grpc-common/python/route_guide/route_guide_client.py](https://github.com/grpc/grpc-common/blob/master/python/route_guide/route_guide_client.py). + +### Creating a stub + +To call service methods, we first need to create a *stub*. + +We use the `early_adopter_create_RouteGuide_stub` function of the `route_guide_pb2` module, generated from our .proto. + +```python +stub = RouteGuide::Stub.new('localhost', 50051) +``` + +The returned object implements all the methods defined by the `EarlyAdopterRouteGuideStub` interface, and is also a [context manager](https://docs.python.org/2/library/stdtypes.html#typecontextmanager). All RPCs invoked on the stub must be invoked within the stub's context, so it is common for stubs to be created and used with a [with statement](https://docs.python.org/2/reference/compound_stmts.html#the-with-statement): + +```python +with route_guide_pb2.early_adopter_create_RouteGuide_stub('localhost', 50051) as stub: +``` + +### Calling service methods + +For RPC methods that return a single response ("response-unary" methods), gRPC Python supports both synchronous (blocking) and asynchronous (non-blocking) control flow semantics. For response-streaming RPC methods, calls immediately return an iterator of response values. Calls to that iterator's `next()` method block until the response to be yielded from the iterator becomes available. + +#### Simple RPC + +A synchronous call to the simple RPC `GetFeature` is nearly as straightforward as calling a local method. The RPC call waits for the server to respond, and will either return a response or raise an exception: + +```python +feature = stub.GetFeature(point, timeout_in_seconds) +``` + +An asynchronous call to `GetFeature` is similar, but like calling a local method asynchronously in a thread pool: + +```python +feature_future = stub.GetFeature.async(point, timeout_in_seconds) +feature = feature_future.result() +``` + +#### Response-streaming RPC + +Calling the response-streaming `ListFeatures` is similar to working with sequence types: + +```python +for feature in stub.ListFeatures(rectangle, timeout_in_seconds): +``` + +#### Request-streaming RPC + +Calling the request-streaming `RecordRoute` is similar to passing a sequence to a local method. Like the simple RPC above that also returns a single response, it can be called synchronously or asynchronously: + +```python +route_summary = stub.RecordRoute(point_sequence, timeout_in_seconds) +``` + +```python +route_summary_future = stub.RecordRoute.async(point_sequence, timeout_in_seconds) +route_summary = route_summary_future.result() +``` + +#### Bidirectional streaming RPC + +Calling the bidirectionally-streaming `RouteChat` has (as is the case on the service-side) a combination of the request-streaming and response-streaming semantics: + +```python +for received_route_note in stub.RouteChat(sent_routes, timeout_in_seconds): +``` + +## Try it out! + +Run the server, which will listen on port 50051: + +```shell +$ python route_guide_server.py +``` + +Run the client (in a different terminal): + +```shell +$ python route_guide_client.py +``` diff --git a/examples/python/route_guide/route_guide_client.py b/examples/python/route_guide/route_guide_client.py new file mode 100755 index 0000000000..078231543e --- /dev/null +++ b/examples/python/route_guide/route_guide_client.py @@ -0,0 +1,130 @@ +# 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. + +"""The Python implementation of the gRPC route guide client.""" + +import random +import time + +import route_guide_pb2 +import route_guide_resources + +_TIMEOUT_SECONDS = 30 + + +def make_route_note(message, latitude, longitude): + return route_guide_pb2.RouteNote( + message=message, + location=route_guide_pb2.Point(latitude=latitude, longitude=longitude)) + + +def guide_get_one_feature(stub, point): + feature = stub.GetFeature(point, _TIMEOUT_SECONDS) + if not feature.location: + print "Server returned incomplete feature" + return + + if feature.name: + print "Feature called %s at %s" % (feature.name, feature.location) + else: + print "Found no feature at %s" % feature.location + + +def guide_get_feature(stub): + guide_get_one_feature(stub, route_guide_pb2.Point(latitude=409146138, longitude=-746188906)) + guide_get_one_feature(stub, route_guide_pb2.Point(latitude=0, longitude=0)) + + +def guide_list_features(stub): + rect = route_guide_pb2.Rectangle( + lo=route_guide_pb2.Point( + latitude=400000000, longitude = -750000000), + hi=route_guide_pb2.Point( + latitude = 420000000, longitude = -730000000)) + print "Looking for features between 40, -75 and 42, -73" + + features = stub.ListFeatures(rect, _TIMEOUT_SECONDS) + + for feature in features: + print "Feature called %s at %s" % (feature.name, feature.location) + + +def generate_route(feature_list): + for _ in range(0, 10): + random_feature = feature_list[random.randint(0, len(feature_list) - 1)] + print "Visiting point %s" % random_feature.location + yield random_feature.location + time.sleep(random.uniform(0.5, 1.5)) + + +def guide_record_route(stub): + feature_list = route_guide_resources.read_route_guide_database() + + route_iter = generate_route(feature_list) + route_summary = stub.RecordRoute(route_iter, _TIMEOUT_SECONDS) + print "Finished trip with %s points " % route_summary.point_count + print "Passed %s features " % route_summary.feature_count + print "Travelled %s meters " % route_summary.distance + print "It took %s seconds " % route_summary.elapsed_time + + +def generate_messages(): + messages = [ + make_route_note("First message", 0, 0), + make_route_note("Second message", 0, 1), + make_route_note("Third message", 1, 0), + make_route_note("Fourth message", 0, 0), + make_route_note("Fifth message", 1, 0), + ] + for msg in messages: + print "Sending %s at %s" % (msg.message, msg.location) + yield msg + time.sleep(random.uniform(0.5, 1.0)) + + +def guide_route_chat(stub): + responses = stub.RouteChat(generate_messages(), _TIMEOUT_SECONDS) + for response in responses: + print "Received message %s at %s" % (response.message, response.location) + + +def run(): + with route_guide_pb2.early_adopter_create_RouteGuide_stub('localhost', 50051) as stub: + print "-------------- GetFeature --------------" + guide_get_feature(stub) + print "-------------- ListFeatures --------------" + guide_list_features(stub) + print "-------------- RecordRoute --------------" + guide_record_route(stub) + print "-------------- RouteChat --------------" + guide_route_chat(stub) + + +if __name__ == '__main__': + run() diff --git a/examples/python/route_guide/route_guide_db.json b/examples/python/route_guide/route_guide_db.json new file mode 100644 index 0000000000..9d6a980ab7 --- /dev/null +++ b/examples/python/route_guide/route_guide_db.json @@ -0,0 +1,601 @@ +[{ + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" +}, { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" +}, { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" +}, { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" +}, { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" +}, { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" +}, { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" +}, { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" +}, { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" +}, { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" +}, { + "location": { + "latitude": 415736605, + "longitude": -742847522 + }, + "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" +}, { + "location": { + "latitude": 413843930, + "longitude": -740501726 + }, + "name": "162 Merrill Road, Highland Mills, NY 10930, USA" +}, { + "location": { + "latitude": 410873075, + "longitude": -744459023 + }, + "name": "Clinton Road, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 412346009, + "longitude": -744026814 + }, + "name": "16 Old Brook Lane, Warwick, NY 10990, USA" +}, { + "location": { + "latitude": 402948455, + "longitude": -747903913 + }, + "name": "3 Drake Lane, Pennington, NJ 08534, USA" +}, { + "location": { + "latitude": 406337092, + "longitude": -740122226 + }, + "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" +}, { + "location": { + "latitude": 406421967, + "longitude": -747727624 + }, + "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" +}, { + "location": { + "latitude": 416318082, + "longitude": -749677716 + }, + "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" +}, { + "location": { + "latitude": 415301720, + "longitude": -748416257 + }, + "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" +}, { + "location": { + "latitude": 402647019, + "longitude": -747071791 + }, + "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" +}, { + "location": { + "latitude": 412567807, + "longitude": -741058078 + }, + "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" +}, { + "location": { + "latitude": 416855156, + "longitude": -744420597 + }, + "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" +}, { + "location": { + "latitude": 404663628, + "longitude": -744820157 + }, + "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" +}, { + "location": { + "latitude": 407113723, + "longitude": -749746483 + }, + "name": "" +}, { + "location": { + "latitude": 402133926, + "longitude": -743613249 + }, + "name": "" +}, { + "location": { + "latitude": 400273442, + "longitude": -741220915 + }, + "name": "" +}, { + "location": { + "latitude": 411236786, + "longitude": -744070769 + }, + "name": "" +}, { + "location": { + "latitude": 411633782, + "longitude": -746784970 + }, + "name": "211-225 Plains Road, Augusta, NJ 07822, USA" +}, { + "location": { + "latitude": 415830701, + "longitude": -742952812 + }, + "name": "" +}, { + "location": { + "latitude": 413447164, + "longitude": -748712898 + }, + "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" +}, { + "location": { + "latitude": 405047245, + "longitude": -749800722 + }, + "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" +}, { + "location": { + "latitude": 418858923, + "longitude": -746156790 + }, + "name": "" +}, { + "location": { + "latitude": 417951888, + "longitude": -748484944 + }, + "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" +}, { + "location": { + "latitude": 407033786, + "longitude": -743977337 + }, + "name": "26 East 3rd Street, New Providence, NJ 07974, USA" +}, { + "location": { + "latitude": 417548014, + "longitude": -740075041 + }, + "name": "" +}, { + "location": { + "latitude": 410395868, + "longitude": -744972325 + }, + "name": "" +}, { + "location": { + "latitude": 404615353, + "longitude": -745129803 + }, + "name": "" +}, { + "location": { + "latitude": 406589790, + "longitude": -743560121 + }, + "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" +}, { + "location": { + "latitude": 414653148, + "longitude": -740477477 + }, + "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" +}, { + "location": { + "latitude": 405957808, + "longitude": -743255336 + }, + "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" +}, { + "location": { + "latitude": 411733589, + "longitude": -741648093 + }, + "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" +}, { + "location": { + "latitude": 412676291, + "longitude": -742606606 + }, + "name": "1270 Lakes Road, Monroe, NY 10950, USA" +}, { + "location": { + "latitude": 409224445, + "longitude": -748286738 + }, + "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" +}, { + "location": { + "latitude": 406523420, + "longitude": -742135517 + }, + "name": "652 Garden Street, Elizabeth, NJ 07202, USA" +}, { + "location": { + "latitude": 401827388, + "longitude": -740294537 + }, + "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" +}, { + "location": { + "latitude": 410564152, + "longitude": -743685054 + }, + "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 408472324, + "longitude": -740726046 + }, + "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" +}, { + "location": { + "latitude": 412452168, + "longitude": -740214052 + }, + "name": "5 White Oak Lane, Stony Point, NY 10980, USA" +}, { + "location": { + "latitude": 409146138, + "longitude": -746188906 + }, + "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" +}, { + "location": { + "latitude": 404701380, + "longitude": -744781745 + }, + "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 409642566, + "longitude": -746017679 + }, + "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" +}, { + "location": { + "latitude": 408031728, + "longitude": -748645385 + }, + "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" +}, { + "location": { + "latitude": 413700272, + "longitude": -742135189 + }, + "name": "367 Prospect Road, Chester, NY 10918, USA" +}, { + "location": { + "latitude": 404310607, + "longitude": -740282632 + }, + "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" +}, { + "location": { + "latitude": 409319800, + "longitude": -746201391 + }, + "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" +}, { + "location": { + "latitude": 406685311, + "longitude": -742108603 + }, + "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" +}, { + "location": { + "latitude": 419018117, + "longitude": -749142781 + }, + "name": "43 Dreher Road, Roscoe, NY 12776, USA" +}, { + "location": { + "latitude": 412856162, + "longitude": -745148837 + }, + "name": "Swan Street, Pine Island, NY 10969, USA" +}, { + "location": { + "latitude": 416560744, + "longitude": -746721964 + }, + "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" +}, { + "location": { + "latitude": 405314270, + "longitude": -749836354 + }, + "name": "" +}, { + "location": { + "latitude": 414219548, + "longitude": -743327440 + }, + "name": "" +}, { + "location": { + "latitude": 415534177, + "longitude": -742900616 + }, + "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" +}, { + "location": { + "latitude": 406898530, + "longitude": -749127080 + }, + "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" +}, { + "location": { + "latitude": 407586880, + "longitude": -741670168 + }, + "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" +}, { + "location": { + "latitude": 400106455, + "longitude": -742870190 + }, + "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" +}, { + "location": { + "latitude": 400066188, + "longitude": -746793294 + }, + "name": "" +}, { + "location": { + "latitude": 418803880, + "longitude": -744102673 + }, + "name": "40 Mountain Road, Napanoch, NY 12458, USA" +}, { + "location": { + "latitude": 414204288, + "longitude": -747895140 + }, + "name": "" +}, { + "location": { + "latitude": 414777405, + "longitude": -740615601 + }, + "name": "" +}, { + "location": { + "latitude": 415464475, + "longitude": -747175374 + }, + "name": "48 North Road, Forestburgh, NY 12777, USA" +}, { + "location": { + "latitude": 404062378, + "longitude": -746376177 + }, + "name": "" +}, { + "location": { + "latitude": 405688272, + "longitude": -749285130 + }, + "name": "" +}, { + "location": { + "latitude": 400342070, + "longitude": -748788996 + }, + "name": "" +}, { + "location": { + "latitude": 401809022, + "longitude": -744157964 + }, + "name": "" +}, { + "location": { + "latitude": 404226644, + "longitude": -740517141 + }, + "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" +}, { + "location": { + "latitude": 410322033, + "longitude": -747871659 + }, + "name": "" +}, { + "location": { + "latitude": 407100674, + "longitude": -747742727 + }, + "name": "" +}, { + "location": { + "latitude": 418811433, + "longitude": -741718005 + }, + "name": "213 Bush Road, Stone Ridge, NY 12484, USA" +}, { + "location": { + "latitude": 415034302, + "longitude": -743850945 + }, + "name": "" +}, { + "location": { + "latitude": 411349992, + "longitude": -743694161 + }, + "name": "" +}, { + "location": { + "latitude": 404839914, + "longitude": -744759616 + }, + "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 414638017, + "longitude": -745957854 + }, + "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" +}, { + "location": { + "latitude": 412127800, + "longitude": -740173578 + }, + "name": "" +}, { + "location": { + "latitude": 401263460, + "longitude": -747964303 + }, + "name": "" +}, { + "location": { + "latitude": 412843391, + "longitude": -749086026 + }, + "name": "" +}, { + "location": { + "latitude": 418512773, + "longitude": -743067823 + }, + "name": "" +}, { + "location": { + "latitude": 404318328, + "longitude": -740835638 + }, + "name": "42-102 Main Street, Belford, NJ 07718, USA" +}, { + "location": { + "latitude": 419020746, + "longitude": -741172328 + }, + "name": "" +}, { + "location": { + "latitude": 404080723, + "longitude": -746119569 + }, + "name": "" +}, { + "location": { + "latitude": 401012643, + "longitude": -744035134 + }, + "name": "" +}, { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" +}, { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" +}, { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" +}, { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" +}, { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" +}, { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" +}, { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" +}, { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" +}, { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" +}, { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" +}] diff --git a/examples/python/route_guide/route_guide_pb2.py b/examples/python/route_guide/route_guide_pb2.py new file mode 100644 index 0000000000..2a4532bb75 --- /dev/null +++ b/examples/python/route_guide/route_guide_pb2.py @@ -0,0 +1,370 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: route_guide.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='route_guide.proto', + package='', + serialized_pb=_b('\n\x11route_guide.proto\",\n\x05Point\x12\x10\n\x08latitude\x18\x01 \x01(\x05\x12\x11\n\tlongitude\x18\x02 \x01(\x05\"3\n\tRectangle\x12\x12\n\x02lo\x18\x01 \x01(\x0b\x32\x06.Point\x12\x12\n\x02hi\x18\x02 \x01(\x0b\x32\x06.Point\"1\n\x07\x46\x65\x61ture\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x18\n\x08location\x18\x02 \x01(\x0b\x32\x06.Point\"6\n\tRouteNote\x12\x18\n\x08location\x18\x01 \x01(\x0b\x32\x06.Point\x12\x0f\n\x07message\x18\x02 \x01(\t\"b\n\x0cRouteSummary\x12\x13\n\x0bpoint_count\x18\x01 \x01(\x05\x12\x15\n\rfeature_count\x18\x02 \x01(\x05\x12\x10\n\x08\x64istance\x18\x03 \x01(\x05\x12\x14\n\x0c\x65lapsed_time\x18\x04 \x01(\x05\x32\xad\x01\n\nRouteGuide\x12 \n\nGetFeature\x12\x06.Point\x1a\x08.Feature\"\x00\x12(\n\x0cListFeatures\x12\n.Rectangle\x1a\x08.Feature\"\x00\x30\x01\x12(\n\x0bRecordRoute\x12\x06.Point\x1a\r.RouteSummary\"\x00(\x01\x12)\n\tRouteChat\x12\n.RouteNote\x1a\n.RouteNote\"\x00(\x01\x30\x01') +) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + + + + +_POINT = _descriptor.Descriptor( + name='Point', + full_name='Point', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='latitude', full_name='Point.latitude', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='longitude', full_name='Point.longitude', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=21, + serialized_end=65, +) + + +_RECTANGLE = _descriptor.Descriptor( + name='Rectangle', + full_name='Rectangle', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='lo', full_name='Rectangle.lo', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='hi', full_name='Rectangle.hi', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=67, + serialized_end=118, +) + + +_FEATURE = _descriptor.Descriptor( + name='Feature', + full_name='Feature', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='Feature.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='location', full_name='Feature.location', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=120, + serialized_end=169, +) + + +_ROUTENOTE = _descriptor.Descriptor( + name='RouteNote', + full_name='RouteNote', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='location', full_name='RouteNote.location', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='message', full_name='RouteNote.message', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=171, + serialized_end=225, +) + + +_ROUTESUMMARY = _descriptor.Descriptor( + name='RouteSummary', + full_name='RouteSummary', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='point_count', full_name='RouteSummary.point_count', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='feature_count', full_name='RouteSummary.feature_count', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='distance', full_name='RouteSummary.distance', index=2, + number=3, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='elapsed_time', full_name='RouteSummary.elapsed_time', index=3, + number=4, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=227, + serialized_end=325, +) + +_RECTANGLE.fields_by_name['lo'].message_type = _POINT +_RECTANGLE.fields_by_name['hi'].message_type = _POINT +_FEATURE.fields_by_name['location'].message_type = _POINT +_ROUTENOTE.fields_by_name['location'].message_type = _POINT +DESCRIPTOR.message_types_by_name['Point'] = _POINT +DESCRIPTOR.message_types_by_name['Rectangle'] = _RECTANGLE +DESCRIPTOR.message_types_by_name['Feature'] = _FEATURE +DESCRIPTOR.message_types_by_name['RouteNote'] = _ROUTENOTE +DESCRIPTOR.message_types_by_name['RouteSummary'] = _ROUTESUMMARY + +Point = _reflection.GeneratedProtocolMessageType('Point', (_message.Message,), dict( + DESCRIPTOR = _POINT, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:Point) + )) +_sym_db.RegisterMessage(Point) + +Rectangle = _reflection.GeneratedProtocolMessageType('Rectangle', (_message.Message,), dict( + DESCRIPTOR = _RECTANGLE, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:Rectangle) + )) +_sym_db.RegisterMessage(Rectangle) + +Feature = _reflection.GeneratedProtocolMessageType('Feature', (_message.Message,), dict( + DESCRIPTOR = _FEATURE, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:Feature) + )) +_sym_db.RegisterMessage(Feature) + +RouteNote = _reflection.GeneratedProtocolMessageType('RouteNote', (_message.Message,), dict( + DESCRIPTOR = _ROUTENOTE, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:RouteNote) + )) +_sym_db.RegisterMessage(RouteNote) + +RouteSummary = _reflection.GeneratedProtocolMessageType('RouteSummary', (_message.Message,), dict( + DESCRIPTOR = _ROUTESUMMARY, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:RouteSummary) + )) +_sym_db.RegisterMessage(RouteSummary) + + +import abc +from grpc._adapter import fore +from grpc._adapter import rear +from grpc.framework.assembly import implementations +from grpc.framework.assembly import utilities +class EarlyAdopterRouteGuideServicer(object): + """""" + __metaclass__ = abc.ABCMeta + @abc.abstractmethod + def GetFeature(self, request): + raise NotImplementedError() + @abc.abstractmethod + def ListFeatures(self, request): + raise NotImplementedError() + @abc.abstractmethod + def RecordRoute(self, request_iterator): + raise NotImplementedError() + @abc.abstractmethod + def RouteChat(self, request_iterator): + raise NotImplementedError() +class EarlyAdopterRouteGuideServer(object): + """""" + __metaclass__ = abc.ABCMeta + @abc.abstractmethod + def start(self): + raise NotImplementedError() + @abc.abstractmethod + def stop(self): + raise NotImplementedError() +class EarlyAdopterRouteGuideStub(object): + """""" + __metaclass__ = abc.ABCMeta + @abc.abstractmethod + def GetFeature(self, request): + raise NotImplementedError() + GetFeature.async = None + @abc.abstractmethod + def ListFeatures(self, request): + raise NotImplementedError() + ListFeatures.async = None + @abc.abstractmethod + def RecordRoute(self, request_iterator): + raise NotImplementedError() + RecordRoute.async = None + @abc.abstractmethod + def RouteChat(self, request_iterator): + raise NotImplementedError() + RouteChat.async = None +def early_adopter_create_RouteGuide_server(servicer, port, root_certificates, key_chain_pairs): + method_implementations = { + "GetFeature": utilities.unary_unary_inline(servicer.GetFeature), + "ListFeatures": utilities.unary_stream_inline(servicer.ListFeatures), + "RecordRoute": utilities.stream_unary_inline(servicer.RecordRoute), + "RouteChat": utilities.stream_stream_inline(servicer.RouteChat), + } + import route_guide_pb2 + import route_guide_pb2 + import route_guide_pb2 + import route_guide_pb2 + request_deserializers = { + "GetFeature": route_guide_pb2.Point.FromString, + "ListFeatures": route_guide_pb2.Rectangle.FromString, + "RecordRoute": route_guide_pb2.Point.FromString, + "RouteChat": route_guide_pb2.RouteNote.FromString, + } + response_serializers = { + "GetFeature": lambda x: x.SerializeToString(), + "ListFeatures": lambda x: x.SerializeToString(), + "RecordRoute": lambda x: x.SerializeToString(), + "RouteChat": lambda x: x.SerializeToString(), + } + link = fore.activated_fore_link(port, request_deserializers, response_serializers, root_certificates, key_chain_pairs) + return implementations.assemble_service(method_implementations, link) +def early_adopter_create_RouteGuide_stub(host, port): + method_implementations = { + "GetFeature": utilities.unary_unary_inline(None), + "ListFeatures": utilities.unary_stream_inline(None), + "RecordRoute": utilities.stream_unary_inline(None), + "RouteChat": utilities.stream_stream_inline(None), + } + import route_guide_pb2 + import route_guide_pb2 + import route_guide_pb2 + import route_guide_pb2 + response_deserializers = { + "GetFeature": route_guide_pb2.Feature.FromString, + "ListFeatures": route_guide_pb2.Feature.FromString, + "RecordRoute": route_guide_pb2.RouteSummary.FromString, + "RouteChat": route_guide_pb2.RouteNote.FromString, + } + request_serializers = { + "GetFeature": lambda x: x.SerializeToString(), + "ListFeatures": lambda x: x.SerializeToString(), + "RecordRoute": lambda x: x.SerializeToString(), + "RouteChat": lambda x: x.SerializeToString(), + } + link = rear.activated_rear_link(host, port, request_serializers, response_deserializers) + return implementations.assemble_dynamic_inline_stub(method_implementations, link) +# @@protoc_insertion_point(module_scope) diff --git a/examples/python/route_guide/route_guide_resources.py b/examples/python/route_guide/route_guide_resources.py new file mode 100755 index 0000000000..30c7711019 --- /dev/null +++ b/examples/python/route_guide/route_guide_resources.py @@ -0,0 +1,53 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Common resources used in the gRPC route guide example.""" + +import json + +import route_guide_pb2 + + +def read_route_guide_database(): + """Reads the route guide database. + + Returns: + The full contents of the route guide database as a sequence of + route_guide_pb2.Features. + """ + feature_list = [] + with open("route_guide_db.json") as route_guide_db_file: + for item in json.load(route_guide_db_file): + feature = route_guide_pb2.Feature( + name=item["name"], + location=route_guide_pb2.Point( + latitude=item["location"]["latitude"], + longitude=item["location"]["longitude"])) + feature_list.append(feature) + return feature_list diff --git a/examples/python/route_guide/route_guide_server.py b/examples/python/route_guide/route_guide_server.py new file mode 100644 index 0000000000..44bbacf5f3 --- /dev/null +++ b/examples/python/route_guide/route_guide_server.py @@ -0,0 +1,134 @@ +# 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. + +"""The Python implementation of the gRPC route guide server.""" + +import time +import math + +import route_guide_pb2 +import route_guide_resources + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +def get_feature(feature_db, point): + """Returns Feature at given location or None.""" + for feature in feature_db: + if feature.location == point: + return feature + return None + + +def get_distance(start, end): + """Distance between two points.""" + coord_factor = 10000000.0 + lat_1 = start.latitude / coord_factor + lat_2 = end.latitude / coord_factor + lon_1 = start.latitude / coord_factor + lon_2 = end.longitude / coord_factor + lat_rad_1 = math.radians(lat_1) + lat_rad_2 = math.radians(lat_2) + delta_lat_rad = math.radians(lat_2 - lat_1) + delta_lon_rad = math.radians(lon_2 - lon_1) + + a = (pow(math.sin(delta_lat_rad / 2), 2) + + (math.cos(lat_rad_1) * math.cos(lat_rad_2) * + pow(math.sin(delta_lon_rad / 2), 2))) + c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) + R = 6371000; # metres + return R * c; + +class RouteGuideServicer(route_guide_pb2.EarlyAdopterRouteGuideServicer): + """Provides methods that implement functionality of route guide server.""" + + def __init__(self): + self.db = route_guide_resources.read_route_guide_database() + + def GetFeature(self, request, context): + feature = get_feature(self.db, request) + if feature is None: + return route_guide_pb2.Feature(name="", location=request) + else: + return feature + + def ListFeatures(self, request, context): + left = min(request.lo.longitude, request.hi.longitude) + right = max(request.lo.longitude, request.hi.longitude) + top = max(request.lo.latitude, request.hi.latitude) + bottom = min(request.lo.latitude, request.hi.latitude) + for feature in self.db: + if (feature.location.longitude >= left and + feature.location.longitude <= right and + feature.location.latitude >= bottom and + feature.location.latitude <= top): + yield feature + + def RecordRoute(self, request_iterator, context): + point_count = 0 + feature_count = 0 + distance = 0.0 + prev_point = None + + start_time = time.time() + for point in request_iterator: + point_count += 1 + if get_feature(self.db, point): + feature_count += 1 + if prev_point: + distance += get_distance(prev_point, point) + prev_point = point + + elapsed_time = time.time() - start_time + return route_guide_pb2.RouteSummary(point_count=point_count, + feature_count=feature_count, + distance=int(distance), + elapsed_time=int(elapsed_time)) + + def RouteChat(self, request_iterator, context): + prev_notes = [] + for new_note in request_iterator: + for prev_note in prev_notes: + if prev_note.location == new_note.location: + yield prev_note + prev_notes.append(new_note) + + +def serve(): + server = route_guide_pb2.early_adopter_create_RouteGuide_server( + RouteGuideServicer(), 50051, None, None) + server.start() + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop() + +if __name__ == '__main__': + serve() diff --git a/examples/python/route_guide/run_client.sh b/examples/python/route_guide/run_client.sh new file mode 100755 index 0000000000..d2552c2858 --- /dev/null +++ b/examples/python/route_guide/run_client.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# This is where you have cloned out the https://github.com/grpc/grpc repository +# And built gRPC Python. +# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS +GRPC_ROOT=~/github/grpc + +$GRPC_ROOT/python2.7_virtual_environment/bin/python -B route_guide_client.py diff --git a/examples/python/route_guide/run_codegen.sh b/examples/python/route_guide/run_codegen.sh new file mode 100755 index 0000000000..689e0978de --- /dev/null +++ b/examples/python/route_guide/run_codegen.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Runs the protoc with gRPC plugin to generate protocol messages and gRPC stubs. +protoc -I . --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` route_guide.proto diff --git a/examples/python/route_guide/run_server.sh b/examples/python/route_guide/run_server.sh new file mode 100755 index 0000000000..8f759250c8 --- /dev/null +++ b/examples/python/route_guide/run_server.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# This is where you have cloned out the https://github.com/grpc/grpc repository +# And built gRPC Python. +# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS +GRPC_ROOT=~/github/grpc + +$GRPC_ROOT/python2.7_virtual_environment/bin/python -B route_guide_server.py diff --git a/examples/ruby/.gitignore b/examples/ruby/.gitignore new file mode 100644 index 0000000000..62fcb4fa94 --- /dev/null +++ b/examples/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/examples/ruby/Gemfile b/examples/ruby/Gemfile new file mode 100644 index 0000000000..65d3f0ad4a --- /dev/null +++ b/examples/ruby/Gemfile @@ -0,0 +1,6 @@ +# -*- ruby -*- +# encoding: utf-8 + +source 'https://rubygems.org/' + +gem 'grpc', :git => 'https://github.com/grpc/grpc.git', :submodules => true, glob: 'src/ruby/*.gemspec' diff --git a/examples/ruby/README.md b/examples/ruby/README.md new file mode 100644 index 0000000000..fecd8041e0 --- /dev/null +++ b/examples/ruby/README.md @@ -0,0 +1,61 @@ +gRPC in 3 minutes (Ruby) +======================== + +BACKGROUND +------------- +For this sample, we've already generated the server and client stubs from [helloworld.proto][] + +PREREQUISITES +------------- + +- Ruby 2.x +This requires Ruby 2.x, as the gRPC API surface uses keyword args. +If you don't have that installed locally, you can use [RVM][] to use Ruby 2.x for testing without upgrading the version of Ruby on your whole system. +RVM is also useful if you don't have the necessary privileges to update your system's Ruby. + + ```sh + $ # RVM installation as specified at https://rvm.io/rvm/install + $ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 + $ \curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2 + $ + $ # follow the instructions to ensure that your're using the latest stable version of Ruby + $ # and that the rvm command is installed + ``` +- *N.B* Make sure your run `source $HOME/.rvm/scripts/rvm` as instructed to complete the set-up of RVM. + +INSTALL +------- + +- Clone this repository +- Use bundler to install the example package's dependencies + + ```sh + $ # from this directory + $ gem install bundler # if you don't already have bundler available + $ bundle install + ``` + +Try it! +------- + +- Run the server + + ```sh + $ # from this directory + $ bundle exec ./greeter_server.rb & + ``` + +- Run the client + + ```sh + $ # from this directory + $ bundle exec ./greeter_client.rb + ``` + +Tutorial +-------- + +You can find a more detailed tutorial in [gRPC Basics: Ruby](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/README.md) + +[helloworld.proto]:https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto +[RVM]:https://www.rvm.io/ diff --git a/examples/ruby/greeter_client.rb b/examples/ruby/greeter_client.rb new file mode 100755 index 0000000000..e6cb4bad33 --- /dev/null +++ b/examples/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/examples/ruby/greeter_server.rb b/examples/ruby/greeter_server.rb new file mode 100755 index 0000000000..d4f9cf7d0f --- /dev/null +++ b/examples/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/examples/ruby/grpc-demo.gemspec b/examples/ruby/grpc-demo.gemspec new file mode 100644 index 0000000000..fa69eb20c1 --- /dev/null +++ b/examples/ruby/grpc-demo.gemspec @@ -0,0 +1,23 @@ +# -*- ruby -*- +# encoding: utf-8 + +Gem::Specification.new do |s| + s.name = 'grpc-demo' + s.version = '0.5.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 ruby/route_guide/*.rb`.split("\n").map do |f| + File.basename(f) + end + s.require_paths = ['lib'] + s.platform = Gem::Platform::RUBY + + s.add_dependency 'grpc', '~> 0.6' + + s.add_development_dependency 'bundler', '~> 1.7' +end diff --git a/examples/ruby/lib/helloworld.rb b/examples/ruby/lib/helloworld.rb new file mode 100644 index 0000000000..82bdd78e2a --- /dev/null +++ b/examples/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/examples/ruby/lib/helloworld_services.rb b/examples/ruby/lib/helloworld_services.rb new file mode 100644 index 0000000000..7da45ebc6b --- /dev/null +++ b/examples/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 diff --git a/examples/ruby/lib/route_guide.rb b/examples/ruby/lib/route_guide.rb new file mode 100644 index 0000000000..98bac8395c --- /dev/null +++ b/examples/ruby/lib/route_guide.rb @@ -0,0 +1,37 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: route_guide.proto + +require 'google/protobuf' + +Google::Protobuf::DescriptorPool.generated_pool.build do + add_message "examples.Point" do + optional :latitude, :int32, 1 + optional :longitude, :int32, 2 + end + add_message "examples.Rectangle" do + optional :lo, :message, 1, "examples.Point" + optional :hi, :message, 2, "examples.Point" + end + add_message "examples.Feature" do + optional :name, :string, 1 + optional :location, :message, 2, "examples.Point" + end + add_message "examples.RouteNote" do + optional :location, :message, 1, "examples.Point" + optional :message, :string, 2 + end + add_message "examples.RouteSummary" do + optional :point_count, :int32, 1 + optional :feature_count, :int32, 2 + optional :distance, :int32, 3 + optional :elapsed_time, :int32, 4 + end +end + +module Examples + Point = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.Point").msgclass + Rectangle = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.Rectangle").msgclass + Feature = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.Feature").msgclass + RouteNote = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.RouteNote").msgclass + RouteSummary = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.RouteSummary").msgclass +end diff --git a/examples/ruby/lib/route_guide_services.rb b/examples/ruby/lib/route_guide_services.rb new file mode 100644 index 0000000000..6e07653c42 --- /dev/null +++ b/examples/ruby/lib/route_guide_services.rb @@ -0,0 +1,27 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# Source: route_guide.proto for package 'examples' + +require 'grpc' +require 'route_guide' + +module Examples + module RouteGuide + + # TODO: add proto service documentation here + class Service + + include GRPC::GenericService + + self.marshal_class_method = :encode + self.unmarshal_class_method = :decode + self.service_name = 'examples.RouteGuide' + + rpc :GetFeature, Point, Feature + rpc :ListFeatures, Rectangle, stream(Feature) + rpc :RecordRoute, stream(Point), RouteSummary + rpc :RouteChat, stream(RouteNote), stream(RouteNote) + end + + Stub = Service.rpc_stub_class + end +end diff --git a/examples/ruby/route_guide/README.md b/examples/ruby/route_guide/README.md new file mode 100644 index 0000000000..d22874799f --- /dev/null +++ b/examples/ruby/route_guide/README.md @@ -0,0 +1,285 @@ +#gRPC Basics: Ruby + +This tutorial provides a basic Ruby programmer's introduction to working with gRPC. By walking through this example you'll learn how to: + +- Define a service in a .proto file. +- Generate server and client code using the protocol buffer compiler. +- Use the Ruby gRPC API to write a simple client and server for your service. + +It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. + +This isn't a comprehensive guide to using gRPC in Ruby: more reference documentation is coming soon. + +## Why use gRPC? + +Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. + +With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/ruby/route_guide](https://github.com/grpc/grpc-common/tree/master/ruby/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/ruby/route_guide`: +```shell +$ cd grpc-common/ruby/route_guide +``` + +You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Ruby quick start guide](https://github.com/grpc/grpc-common/tree/master/ruby). + + +## Defining the service + +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). + +To define a service, you specify a named `service` in your .proto file: + +```protobuf +service RouteGuide { + ... +} +``` + +Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: + +- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. +```protobuf + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} +``` + +- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. +```protobuf + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} +``` + +- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. +```protobuf + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} +``` + +- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. +```protobuf + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +``` + +Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: +```protobuf +// 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; +} +``` + + +## Generating client and server code + +Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC Ruby plugin. + +If you want to run this yourself, make sure you've installed protoc and followed the gRPC Ruby plugin [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): + +Once that's done, the following command can be used to generate the ruby code. + +```shell +$ protoc -I ../../protos --ruby_out=lib --grpc_out=lib --plugin=protoc-gen-grpc=`which grpc_ruby_plugin` ../../protos/route_guide.proto +``` + +Running this command regenerates the following files in the lib directory: +- `lib/route_guide.pb` defines a module `Examples::RouteGuide` + - This contain all the protocol buffer code to populate, serialize, and retrieve our request and response message types +- `lib/route_guide_services.pb`, extends `Examples::RouteGuide` with stub and service classes + - a class `Service` for use as a base class when defining RouteGuide service implementations + - a class `Stub` that can be used to access remote RouteGuide instances + + + +## Creating the server + +First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). + +There are two parts to making our `RouteGuide` service do its job: +- Implementing the service interface generated from our service definition: doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and return the service responses. + +You can find our example `RouteGuide` server in [grpc-common/ruby/route_guide/route_guide_server.rb](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/route_guide_server.rb). Let's take a closer look at how it works. + +### Implementing RouteGuide + +As you can see, our server has a `ServerImpl` class that extends the generated `RouteGuide::Service`: + +```ruby +# ServerImpl provides an implementation of the RouteGuide service. +class ServerImpl < RouteGuide::Service +``` + +`ServerImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. + +```ruby + def get_feature(point, _call) + name = @feature_db[{ + 'longitude' => point.longitude, + 'latitude' => point.latitude }] || '' + Feature.new(location: point, name: name) + end +``` + +The method is passed a _call for the RPC, the client's `Point` protocol buffer request, and returns a `Feature` protocol buffer. In the method we create the `Feature` with the appropriate information, and then `return` it. + +Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. + +```ruby +# in ServerImpl + + def list_features(rectangle, _call) + RectangleEnum.new(@feature_db, rectangle).each + end +``` + +As you can see, here the request object is a `Rectangle` in which our client wants to find `Feature`s, but instead of returning a simple response we need to return an [Enumerator](http://ruby-doc.org//core-2.2.0/Enumerator.html) that yields the responses. In the method, we use a helper class `RectangleEnum`, to act as an Enumerator implementation. + +Similarly, the client-side streaming method `record_route` uses an [Enumerable](http://ruby-doc.org//core-2.2.0/Enumerable.html), but here it's obtained from the call object, which we've ignored in the earlier examples. `call.each_remote_read` yields each message sent by the client in turn. + +```ruby + call.each_remote_read do |point| + ... + end +``` +Finally, let's look at our bidirectional streaming RPC `route_chat`. + +```ruby + def route_chat(notes) + q = EnumeratorQueue.new(self) + t = Thread.new do + begin + notes.each do |n| + ... + end + end + q = EnumeratorQueue.new(self) + ... + return q.each_item + end +``` + +Here the method receives an [Enumerable](http://ruby-doc.org//core-2.2.0/Enumerable.html), but also returns an [Enumerator](http://ruby-doc.org//core-2.2.0/Enumerator.html) that yields the responses. The implementation demonstrates how to set these up so that the requests and responses can be handled concurrently. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. + +### Starting the server + +Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: + +```ruby + s = GRPC::RpcServer.new + s.add_http2_port(port) + logger.info("... running insecurely on #{port}") + s.handle(ServerImpl.new(feature_db)) + s.run +``` +As you can see, we build and start our server using a `GRPC::RpcServer`. To do this, we: + +1. Create an instance of our service implementation class `ServerImpl`. +2. Specify the address and port we want to use to listen for client requests using the builder's `add_http2_port` method. +3. Register our service implementation with the `GRPC::RpcServer`. +4. Call `run` on the`GRPC::RpcServer` to create and start an RPC server for our service. + + +## Creating the client + +In this section, we'll look at creating a Ruby client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/ruby/route_guide/route_guide_client.rb](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/route_guide_client.rb). + +### Creating a stub + +To call service methods, we first need to create a *stub*. + +We use the `Stub` class of the `RouteGuide` module generated from our .proto. + +```ruby + stub = RouteGuide::Stub.new('localhost:50051') +``` + +### Calling service methods + +Now let's look at how we call our service methods. Note that the gRPC Ruby only provides *blocking/synchronous* versions of each method: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception. + +#### Simple RPC + +Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. + +```ruby +GET_FEATURE_POINTS = [ + Point.new(latitude: 409_146_138, longitude: -746_188_906), + Point.new(latitude: 0, longitude: 0) +] +.. + GET_FEATURE_POINTS.each do |pt| + resp = stub.get_feature(pt) + ... + p "- found '#{resp.name}' at #{pt.inspect}" + end +``` + +As you can see, we create and populate a request protocol buffer object (in our case `Point`), and create a response protocol buffer object for the server to fill in. Finally, we call the method on the stub, passing it the context, request, and response. If the method returns `OK`, then we can read the response information from the server from our response object. + + +#### Streaming RPCs + +Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `list_features`, which returns an `Enumerable` of `Features` + +```ruby + resps = stub.list_features(LIST_FEATURES_RECT) + resps.each do |r| + p "- found '#{r.name}' at #{r.location.inspect}" + end +``` + +The client-side streaming method `record_route` is similar, except there we pass the server an `Enumerable`. + +```ruby + ... + reqs = RandomRoute.new(features, points_on_route) + resp = stub.record_route(reqs.each, deadline) + ... +``` + +Finally, let's look at our bidirectional streaming RPC `route_chat`. In this case, we pass `Enumerable` to the method and get back an `Enumerable`. + +```ruby + resps = stub.route_chat(ROUTE_CHAT_NOTES) + resps.each { |r| p "received #{r.inspect}" } +``` + +Although it's not shown well by this example, each enumerable is independent of the other - both the client and server can read and write in any order — the streams operate completely independently. + +## Try it out! + +Build client and server: + +```shell +$ # from grpc-common/ruby +$ gem install bundler && bundle install +``` +Run the server, which will listen on port 50051: +```shell +$ # from grpc-common/ruby +$ bundle exec route_guide/route_guide_server.rb ../node/route_guide/route_guide_db.json & +``` +Run the client (in a different terminal): +```shell +$ # from grpc-common/ruby +$ bundle exec route_guide/route_guide_client.rb ../node/route_guide/route_guide_db.json & +``` + diff --git a/examples/ruby/route_guide/route_guide_client.rb b/examples/ruby/route_guide/route_guide_client.rb new file mode 100755 index 0000000000..181623a68a --- /dev/null +++ b/examples/ruby/route_guide/route_guide_client.rb @@ -0,0 +1,165 @@ +#!/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 Route Guide service. +# +# Usage: $ path/to/route_guide_client.rb path/to/route_guide_db.json & + +this_dir = File.expand_path(File.dirname(__FILE__)) +lib_dir = File.join(File.dirname(this_dir), 'lib') +$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) + +require 'grpc' +require 'route_guide_services' + +include Examples + +GET_FEATURE_POINTS = [ + Point.new(latitude: 409_146_138, longitude: -746_188_906), + Point.new(latitude: 0, longitude: 0) +] + +# runs a GetFeature rpc. +# +# - once with a point known to be present in the sample route database +# - once with a point that is not in the sample database +def run_get_feature(stub) + p 'GetFeature' + p '----------' + GET_FEATURE_POINTS.each do |pt| + resp = stub.get_feature(pt) + if resp.name != '' + p "- found '#{resp.name}' at #{pt.inspect}" + else + p "- found nothing at #{pt.inspect}" + end + end +end + +LIST_FEATURES_RECT = Rectangle.new( + lo: Point.new(latitude: 400_000_000, longitude: -750_000_000), + hi: Point.new(latitude: 420_000_000, longitude: -730_000_000)) + +# runs a ListFeatures rpc. +# +# - the rectangle to chosen to include most of the known features +# in the sample db. +def run_list_features(stub) + p 'ListFeatures' + p '------------' + resps = stub.list_features(LIST_FEATURES_RECT) + resps.each do |r| + p "- found '#{r.name}' at #{r.location.inspect}" + end +end + +# RandomRoute provides an Enumerable that yields a random 'route' of points +# from a list of Features. +class RandomRoute + def initialize(features, size) + @features = features + @size = size + end + + # yields a point, waiting between 0 and 1 seconds between each yield + # + # @return an Enumerable that yields a random point + def each + return enum_for(:each) unless block_given? + @size.times do + json_feature = @features[rand(0..@features.length)] + next if json_feature.nil? + location = json_feature['location'] + pt = Point.new( + Hash[location.each_pair.map { |k, v| [k.to_sym, v] }]) + p "- next point is #{pt.inspect}" + yield pt + sleep(rand(0..1)) + end + end +end + +# runs a RecordRoute rpc. +# +# - the rectangle to chosen to include most of the known features +# in the sample db. +def run_record_route(stub, features) + p 'RecordRoute' + p '-----------' + points_on_route = 10 # arbitrary + deadline = points_on_route # as delay b/w each is max 1 second + reqs = RandomRoute.new(features, points_on_route) + resp = stub.record_route(reqs.each, deadline) + p "summary: #{resp.inspect}" +end + +ROUTE_CHAT_NOTES = [ + RouteNote.new(message: 'doh - a deer', + location: Point.new(latitude: 0, longitude: 0)), + RouteNote.new(message: 'ray - a drop of golden sun', + location: Point.new(latitude: 0, longitude: 1)), + RouteNote.new(message: 'me - the name I call myself', + location: Point.new(latitude: 1, longitude: 0)), + RouteNote.new(message: 'fa - a longer way to run', + location: Point.new(latitude: 1, longitude: 1)), + RouteNote.new(message: 'soh - with needle and a thread', + location: Point.new(latitude: 0, longitude: 1)) +] + +# runs a RouteChat rpc. +# +# sends a canned set of route notes and prints out the responses. +def run_route_chat(stub) + p 'Route Chat' + p '----------' + # TODO: decouple sending and receiving, i.e have the response enumerator run + # on its own thread. + resps = stub.route_chat(ROUTE_CHAT_NOTES) + resps.each { |r| p "received #{r.inspect}" } +end + +def main + stub = RouteGuide::Stub.new('localhost:50051') + run_get_feature(stub) + run_list_features(stub) + run_route_chat(stub) + if ARGV.length == 0 + p 'no feature database; skipping record_route' + exit + end + raw_data = [] + File.open(ARGV[0]) do |f| + raw_data = MultiJson.load(f.read) + end + run_record_route(stub, raw_data) +end + +main diff --git a/examples/ruby/route_guide/route_guide_server.rb b/examples/ruby/route_guide/route_guide_server.rb new file mode 100755 index 0000000000..2b2b8084ef --- /dev/null +++ b/examples/ruby/route_guide/route_guide_server.rb @@ -0,0 +1,211 @@ +#!/usr/bin/env ruby +# -*- coding: utf-8 -*- + +# 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 Route Guide service. +# +# Usage: $ path/to/route_guide_server.rb path/to/route_guide_db.json & + +this_dir = File.expand_path(File.dirname(__FILE__)) +lib_dir = File.join(File.dirname(this_dir), 'lib') +$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) + +require 'grpc' +require 'multi_json' +require 'route_guide_services' + +include Examples +COORD_FACTOR = 1e7 +RADIUS = 637_100 + +# Determines the distance between two points. +def calculate_distance(point_a, point_b) + to_radians = proc { |x| x * Math::PI / 180 } + lat_a = point_a.latitude / COORD_FACTOR + lat_b = point_b.latitude / COORD_FACTOR + long_a = point_a.longitude / COORD_FACTOR + long_b = point_b.longitude / COORD_FACTOR + φ1 = to_radians.call(lat_a) + φ2 = to_radians.call(lat_b) + Δφ = to_radians.call(lat_a - lat_b) + Δλ = to_radians.call(long_a - long_b) + a = Math.sin(Δφ / 2)**2 + + Math.cos(φ1) * Math.cos(φ2) + + Math.sin(Δλ / 2)**2 + (2 * RADIUS * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))).to_i +end + +# RectangleEnum provides an Enumerator of the points in a feature_db within a +# given Rectangle. +class RectangleEnum + # @param [Hash] feature_db + # @param [Rectangle] bounds + def initialize(feature_db, bounds) + @feature_db = feature_db + @bounds = bounds + lats = [@bounds.lo.latitude, @bounds.hi.latitude] + longs = [@bounds.lo.longitude, @bounds.hi.longitude] + @lo_lat, @hi_lat = lats.min, lats.max + @lo_long, @hi_long = longs.min, longs.max + end + + # in? determines if location lies within the bounds of this instances + # Rectangle. + def in?(location) + location['longitude'] >= @lo_long && + location['longitude'] <= @hi_long && + location['latitude'] >= @lo_lat && + location['latitude'] <= @hi_lat + end + + # each yields the features in the instances feature_db that lie within the + # instance rectangle. + def each + return enum_for(:each) unless block_given? + @feature_db.each_pair do |location, name| + next unless in?(location) + next if name.nil? || name == '' + pt = Point.new( + Hash[location.each_pair.map { |k, v| [k.to_sym, v] }]) + yield Feature.new(location: pt, name: name) + end + end +end + +# A EnumeratorQueue wraps a Queue to yield the items added to it. +class EnumeratorQueue + extend Forwardable + def_delegators :@q, :push + + def initialize(sentinel) + @q = Queue.new + @sentinel = sentinel + @received_notes = {} + end + + def each_item + return enum_for(:each_item) unless block_given? + loop do + r = @q.pop + break if r.equal?(@sentinel) + fail r if r.is_a? Exception + yield r + end + end +end + +# ServerImpl provides an implementation of the RouteGuide service. +class ServerImpl < RouteGuide::Service + # @param [Hash] feature_db {location => name} + def initialize(feature_db) + @feature_db = feature_db + @received_notes = Hash.new { |h, k| h[k] = [] } + end + + def get_feature(point, _call) + name = @feature_db[{ + 'longitude' => point.longitude, + 'latitude' => point.latitude }] || '' + Feature.new(location: point, name: name) + end + + def list_features(rectangle, _call) + RectangleEnum.new(@feature_db, rectangle).each + end + + def record_route(call) + started, elapsed_time = 0, 0 + distance, count, features, last = 0, 0, 0, nil + call.each_remote_read do |point| + count += 1 + name = @feature_db[{ + 'longitude' => point.longitude, + 'latitude' => point.latitude }] || '' + features += 1 unless name == '' + if last.nil? + last = point + started = Time.now.to_i + next + end + elapsed_time = Time.now.to_i - started + distance += calculate_distance(point, last) + last = point + end + RouteSummary.new(point_count: count, + feature_count: features, + distance: distance, + elapsed_time: elapsed_time) + end + + def route_chat(notes) + q = EnumeratorQueue.new(self) + # run a separate thread that processes the incoming requests + t = Thread.new do + begin + notes.each do |n| + key = { + 'latitude' => n.location.latitude, + 'longitude' => n.location.longitude + } + earlier_msgs = @received_notes[key] + @received_notes[key] << n.message + # send back the earlier messages at this point + earlier_msgs.each do |r| + q.push(RouteNote.new(location: n.location, message: r)) + end + end + q.push(self) # signal completion + rescue StandardError => e + q.push(e) # signal completion via an error + end + end + q.each_item + end +end + +def main + if ARGV.length == 0 + fail 'Please specify the path to the route_guide json database' + end + raw_data = [] + File.open(ARGV[0]) do |f| + raw_data = MultiJson.load(f.read) + end + feature_db = Hash[raw_data.map { |x| [x['location'], x['name']] }] + port = '0.0.0.0:50051' + s = GRPC::RpcServer.new + s.add_http2_port(port) + GRPC.logger.info("... running insecurely on #{port}") + s.handle(ServerImpl.new(feature_db)) + s.run +end + +main diff --git a/grpc-common/LICENSE b/grpc-common/LICENSE deleted file mode 100644 index 05b6a757da..0000000000 --- a/grpc-common/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2015, grpc -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 grpc-common 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 HOLDER 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. - diff --git a/grpc-common/PATENTS b/grpc-common/PATENTS deleted file mode 100644 index 619f9dbfe6..0000000000 --- a/grpc-common/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the GRPC project. - -Google hereby grants to You a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable (except as stated in this section) -patent license to make, have made, use, offer to sell, sell, import, -transfer and otherwise run, modify and propagate the contents of this -implementation of GRPC, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of GRPC. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of GRPC or any code incorporated within this -implementation of GRPC constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of GRPC -shall terminate as of the date such litigation is filed. diff --git a/grpc-common/PROTOCOL-HTTP2.md b/grpc-common/PROTOCOL-HTTP2.md deleted file mode 100644 index d3fbb60d60..0000000000 --- a/grpc-common/PROTOCOL-HTTP2.md +++ /dev/null @@ -1,192 +0,0 @@ -# gRPC over HTTP2 - -## Introduction -This document serves as a detailed description for an implementation of gRPC carried over HTTP2 draft 17 framing. It assumes familiarity with the HTTP2 specification. - -## Protocol -Production rules are using ABNF syntax. - -### Outline - -The following is the general sequence of message atoms in a GRPC request & response message stream - -* Request → Request-Headers *Delimited-Message EOS -* Response → (Response-Headers *Delimited-Message Trailers) / Trailers-Only - - -### Requests - -* Request → Request-Headers *Delimited-Message EOS - -Request-Headers are delivered as HTTP2 headers in HEADERS + CONTINUATION frames. - -* **Request-Headers** → Call-Definition *Custom-Metadata -* **Call-Definition** → Method Scheme Path TE [Authority] [Timeout] [Content-Type] [Message-Type] [Message-Encoding] [Message-Accept-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_})] -* **Content-Coding** → “gzip” / “deflate” / “snappy” / {_custom_} -* **Message-Encoding** → “grpc-encoding” Content-Coding -* **Message-Accept-Encoding** → “grpc-accept-encoding” Content-Coding *("," Content-Coding) -* **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] [Message-Accept-Encoding] Content-Type *Custom-Metadata -* **Trailers-Only** → HTTP-Status Content-Type Trailers -* **Trailers** → Status [Status-Message] *Custom-Metadata -* **HTTP-Status** → “:status 200” -* **Status** → “grpc-status” -* **Status-Message** → “grpc-message” - -**Response-Headers** & **Trailers-Only** are each delivered in a single HTTP2 HEADERS frame block. Most responses are expected to have both headers and trailers but **Trailers-Only** is permitted for calls that produce an immediate error. Status must be sent in **Trailers** even if the status code is OK. - -For responses end-of-stream is indicated by the presence of the END_STREAM flag on the last received HEADERS frame that carries **Trailers**. - -Implementations should expect broken deployments to send non-200 HTTP status codes in responses as well as a variety of non-GRPC content-types and to omit **Status** & **Status-Message**. Implementations must synthesize a **Status** & **Status-Message** to propagate to the application layer when this occurs. - -####Example - -Sample unary-call showing HTTP2 framing sequence - -**Request** - -``` -HEADERS (flags = END_HEADERS) -:method = POST -:scheme = http -:path = /google.pubsub.v2.PublisherService/CreateTopic -:authority = pubsub.googleapis.com -grpc-timeout = 1S -content-type = application/grpc+proto -grpc-encoding = gzip -authorization = Bearer y235.wef315yfh138vh31hv93hv8h3v - -DATA (flags = END_STREAM) - -``` -**Response** -``` -HEADERS (flags = END_HEADERS) -:status = 200 -grpc-encoding = gzip - -DATA - - -HEADERS (flags = END_STREAM, END_HEADERS) -grpc-status = 0 # OK -trace-proto-bin = jher831yy13JHy3hc -``` -####User Agents - -While the protocol does not require a user-agent to function it is recommended that clients provide a structured user-agent string that provides a basic description of the calling library, version & platform to facilitate issue diagnosis in heterogeneous environments. The following structure is recommended to library developers -``` -User-Agent → “grpc-” Language ?(“-” Variant) “/” Version ?( “ (“ *(AdditionalProperty “;”) “)” ) -``` -E.g. - -``` -grpc-java/1.2.3 -grpc-ruby/1.2.3 -grpc-ruby-jruby/1.3.4 -grpc-java-android/0.9.1 (gingerbread/1.2.4; nexus5; tmobile) -``` -####HTTP2 Transport Mapping - -#####Stream Identification -All GRPC calls need to specify an internal ID. We will use HTTP2 stream-ids as call identifiers in this scheme. NOTE: These id’s are contextual to an open HTTP2 session and will not be unique within a given process that is handling more than one HTTP2 session nor can they be used as GUIDs. - -#####Data Frames -DATA frame boundaries have no relation to **Delimited-Message** boundaries and implementations should make no assumptions about their alignment. - -#####Errors - -When an application or runtime error occurs during an RPC a **Status** and **Status-Message** are delivered in **Trailers**. - -In some cases it is possible that the framing of the message stream has become corrupt and the RPC runtime will choose to use an **RST_STREAM** frame to indicate this state to its peer. RPC runtime implementations should interpret RST_STREAM as immediate full-closure of the stream and should propagate an error up to the calling application layer. - -The following mapping from RST_STREAM error codes to GRPC error codes is applied. - -HTTP2 Code|GRPC Code -----------|----------- -NO_ERROR(0)|INTERNAL - An explicit GRPC status of OK should have been sent but this might be used to aggressively lameduck in some scenarios. -PROTOCOL_ERROR(1)|INTERNAL -INTERNAL_ERROR(2)|INTERNAL -FLOW_CONTROL_ERROR(3)|INTERNAL -SETTINGS_TIMEOUT(4)|INTERNAL -STREAM_CLOSED|No mapping as there is no open stream to propagate to. Implementations should log. -FRAME_SIZE_ERROR|INTERNAL -REFUSED_STREAM|UNAVAILABLE - Indicates that no processing occurred and the request can be retried, possibly elsewhere. -CANCEL(8)|Mapped to call cancellation when sent by a client.Mapped to CANCELLED when sent by a server. Note that servers should only use this mechanism when they need to cancel a call but the payload byte sequence is incomplete. -COMPRESSION_ERROR|INTERNAL -CONNECT_ERROR|INTERNAL -ENHANCE_YOUR_CALM|RESOURCE_EXHAUSTED ...with additional error detail provided by runtime to indicate that the exhausted resource is bandwidth. -INADEQUATE_SECURITY| PERMISSION_DENIED … with additional detail indicating that permission was denied as protocol is not secure enough for call. - - -#####Security - -The HTTP2 specification mandates the use of TLS 1.2 or higher when TLS is used with HTTP2. It also places some additional constraints on the allowed ciphers in deployments to avoid known-problems as well as requiring SNI support. It is also expected that HTTP2 will be used in conjunction with proprietary transport security mechanisms about which the specification can make no meaningful recommendations. - -#####Connection Management -######GOAWAY Frame -Sent by servers to clients to indicate that they will no longer accept any new streams on the associated connections. This frame includes the id of the last successfully accepted stream by the server. Clients should consider any stream initiated after the last successfully accepted stream as UNAVAILABLE and retry the call elsewhere. Clients are free to continue working with the already accepted streams until they complete or the connection is terminated. - -Servers should send GOAWAY before terminating a connection to reliably inform clients which work has been accepted by the server and is being executed. - -######PING Frame -Both clients and servers can send a PING frame that the peer must respond to by precisely echoing what they received. This is used to assert that the connection is still live as well as providing a means to estimate end-to-end latency. If a server initiated PING does not receive a response within the deadline expected by the runtime all outstanding calls on the server will be closed with a CANCELLED status. An expired client initiated PING will cause all calls to be closed with an UNAVAILABLE status. Note that the frequency of PINGs is highly dependent on the network environment, implementations are free to adjust PING frequency based on network and application requirements. - -######Connection failure -If a detectable connection failure occurs on the client all calls will be closed with an UNAVAILABLE status. For servers open calls will be closed with a CANCELLED status. - - -### Appendix A - GRPC for Protobuf - -The service interfaces declared by protobuf are easily mapped onto GRPC by code generation extensions to protoc. The following defines the mapping to be used - - -* **Path** → / Service-Name / {_method name_} -* **Service-Name** → ?( {_proto package name_} "." ) {_service name_} -* **Message-Type** → {_fully qualified proto message name_} -* **Content-Type** → "application/grpc+proto" - - diff --git a/grpc-common/README.md b/grpc-common/README.md deleted file mode 100644 index 5939db3ab5..0000000000 --- a/grpc-common/README.md +++ /dev/null @@ -1,449 +0,0 @@ - -# Getting started - -Welcome to the developer documentation for gRPC, a language-neutral, -platform-neutral remote procedure call (RPC) system developed at Google. - -This document introduces you to gRPC with a quick overview and a simple -Hello World example. You'll find more tutorials and reference docs in this repository - more documentation is coming soon! - - -## Quick start -You can find quick start guides for each language, including installation instructions, examples, and tutorials here: -* [C++](https://github.com/grpc/grpc-common/tree/master/cpp) -* [Java](https://github.com/grpc/grpc-common/tree/master/java) -* [Go](https://github.com/grpc/grpc-common/tree/master/go) -* [Ruby](https://github.com/grpc/grpc-common/tree/master/ruby) -* [Node.js](https://github.com/grpc/grpc-common/tree/master/node) -* [Android Java](https://github.com/grpc/grpc-common/tree/master/java/android) -* [Python](https://github.com/grpc/grpc-common/tree/master/python/helloworld) -* [C#](https://github.com/grpc/grpc-common/tree/master/csharp) -* [Objective-C](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide) - -## What's in this repository? - -The `grpc-common` repository contains documentation, resources, and examples -for all gRPC users. You can find examples and instructions specific to your -favourite language in the relevant subdirectory. - -You can find out about the gRPC source code repositories in -[`grpc`](https://github.com/grpc/grpc). Each repository provides instructions -for building the appropriate libraries for your language. - - -## What is gRPC? - -In gRPC a *client* application can directly call -methods on a *server* application on a different machine as if it was a -local object, making it easier for you to create distributed applications and -services. As in many RPC systems, gRPC is based around the idea of defining -a *service*, specifying the methods that can be called remotely with their -parameters and return types. On the server side, the server implements this -interface and runs a gRPC server to handle client calls. On the client side, -the client has a *stub* that provides exactly the same methods as the server. - - - -gRPC clients and servers can run and talk to each other in a variety of -environments - from servers inside Google to your own desktop - and can -be written in any of gRPC's [supported languages](#quickstart). So, for -example, you can easily create a gRPC server in Java with clients in Go, -Python, or Ruby. In addition, the latest Google APIs will have gRPC versions -of their interfaces, letting you easily build Google functionality into -your applications. - - -### Working with protocol buffers - -By default gRPC uses *protocol buffers*, Google’s -mature open source mechanism for serializing structured data (although it -can be used with other data formats such as JSON). As you'll -see in our example below, you define gRPC services using *proto files*, -with method parameters and return types specified as protocol buffer message -types. You -can find out lots more about protocol buffers in the [Protocol Buffers -documentation](https://developers.google.com/protocol-buffers/docs/overview). - -#### Protocol buffer versions - -While protocol buffers have been available for open source users for some -time, our examples use a new flavour of protocol buffers called proto3, -which has a slightly simplified syntax, some useful new features, and supports -lots more languages. This is currently available as an alpha release in -Java, C++, Java_nano (Android Java), Python, and Ruby from [the protocol buffers Github -repo](https://github.com/google/protobuf/releases), as well as a Go language -generator from [the golang/protobuf Github repo](https://github.com/golang/protobuf), with more languages in development. You can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3), and see -the major differences from the current default version in the [release notes](https://github.com/google/protobuf/releases). More proto3 documentation is coming soon. - -In general, while you *can* use proto2 (the current default protocol buffers version), we recommend that you use proto3 with gRPC as it lets you use the full range of gRPC-supported languages, as well as avoiding compatibility -issues with proto2 clients talking to proto3 servers and vice versa. - - -## Hello gRPC! - -Now that you know a bit more about gRPC, the easiest way to see how it -works is to look at a simple example. Our Hello World walks you through the -construction of a simple gRPC client-server application, showing you how to: - -- Create a protocol buffers schema that defines a simple RPC service with -a single -Hello World method. -- Create a Java server that implements this interface. -- Create a Java client that accesses the Java server. -- Create a Go client that accesses -the same Java server. - -The complete code for the example is available in the `grpc-common` GitHub -repository. We use the Git versioning system for source code management: -however, you don't need to know anything about Git to follow along other -than how to install and run a few git commands. - -This is an introductory example rather than a comprehensive tutorial, so -don't worry if you're not a Go or -Java developer - the concepts are similar for all languages, and you can -find more implementations of our Hello World example in other languages (and full tutorials where available) in -the [language-specific folders](#quickstart) in this repository. Complete tutorials and -reference documentation for all gRPC languages are coming soon. - - -### Setup - -This section explains how to set up your local machine to work with -the example code. If you just want to read the example, you can go straight -to the [next step](#servicedef). - -#### Install Git - -You can download and install Git from http://git-scm.com/download. Once -installed you should have access to the git command line tool. The main -commands that you will need to use are: - -- git clone ... : clone a remote repository onto your local machine -- git checkout ... : check out a particular branch or a tagged version of -the code to hack on - -#### Install gRPC - -To build and install gRPC plugins and related tools: -- For Java, see the [Java quick start](https://github.com/grpc/grpc-java). -- For Go, see the [Go quick start](https://github.com/grpc/grpc-go). - -#### Get the source code - -The example code for our Java example lives in the `grpc-java` -GitHub repository. Clone this repository to your local machine by running the -following command: - - -``` -git clone https://github.com/grpc/grpc-java.git -``` - -Change your current directory to grpc-java/examples - -``` -cd grpc-java/examples -``` - - - - -### Defining a service - -The first step in creating our example is to define a *service*: an RPC -service specifies the methods that can be called remotely with their parameters -and return types. As you saw in the -[overview](#protocolbuffers) above, gRPC does this using [protocol -buffers](https://developers.google.com/protocol-buffers/docs/overview). We -use the protocol buffers interface definition language (IDL) to define our -service methods, and define the parameters and return -types as protocol buffer message types. Both the client and the -server use interface code generated from the service definition. - -Here's our example service definition, defined using protocol buffers IDL in -[helloworld.proto](https://github.com/grpc/grpc-java/tree/master/examples/src/main/proto). The `Greeter` -service has one method, `SayHello`, that lets the server receive a single -`HelloRequest` -message from the remote client containing the user's name, then send back -a greeting in a single `HelloReply`. This is the simplest type of RPC you -can specify in gRPC - you can find out about other types in the tutorial for your chosen language. - -```proto -syntax = "proto3"; - -option java_package = "io.grpc.examples"; - -package helloworld; - -// The greeter service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} - -``` - - -### Generating gRPC code - -Once we've defined our service, we use the protocol buffer compiler -`protoc` to generate the special client and server code we need to create -our application - right now we're going to generate Java code, though you -can generate gRPC code in any gRPC-supported language (as you'll see later -in this example). The generated code contains both stub code for clients to -use and an abstract interface for servers to implement, both with the method -defined in our `Greeter` service. - -(If you didn't install the gRPC plugins and protoc on your system and are just reading along with -the example, you can skip this step and move -onto the next one where we examine the generated code.) - -For simplicity, we've provided a [Gradle build file](https://github.com/grpc/grpc-java/blob/master/examples/build.gradle) with our Java examples that runs `protoc` for you with the appropriate plugin, input, and output: - -```shell -../gradlew build -``` - -This generates the following classes from our .proto, which contain all the generated code -we need to create our example: - -- `Helloworld.java`, which -has all the protocol buffer code to populate, serialize, and retrieve our -`HelloRequest` and `HelloReply` message types -- `GreeterGrpc.java`, which contains (along with some other useful code): - - an interface for `Greeter` servers to implement - - ```java - public static interface Greeter { - public void sayHello(io.grpc.examples.Helloworld.HelloRequest request, - io.grpc.stub.StreamObserver responseObserver); - } - ``` - - - _stub_ classes that clients can use to talk to a `Greeter` server. As you can see, they also implement the `Greeter` interface. - - ```java - public static class GreeterStub extends - io.grpc.stub.AbstractStub - implements Greeter { - ... - } - ``` - - -### Writing a server - -Now let's write some code! First we'll create a server application to implement -our service. Note that we're not going to go into a lot of detail about how -to create a server in this section. More detailed information will be in the -tutorial for your chosen language: check if there's one available yet in the relevant [quick start](#quickstart). - -Our server application has two classes: - -- a main server class that hosts the service implementation and allows access over the -network: [HelloWorldServer.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java). - - -- a simple service implementation class [GreeterImpl.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java#L51). - - -#### Service implementation - -[GreeterImpl.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java#L51) -actually implements our `Greeter` service's required behaviour. - -As you can see, the class `GreeterImpl` implements the interface -`GreeterGrpc.Greeter` that we [generated](#generating) from our proto -[IDL](https://github.com/grpc/grpc-java/tree/master/examples/src/main/proto) by implementing the method `sayHello`: - -```java - @Override - public void sayHello(HelloRequest req, StreamObserver responseObserver) { - HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build(); - responseObserver.onValue(reply); - responseObserver.onCompleted(); - } -``` -- `sayHello` takes two parameters: - - `HelloRequest`: the request - - `StreamObserver`: a response observer, which is - a special interface for the server to call with its response - -To return our response to the client and complete the call: - -1. We construct and populate a `HelloReply` response object with our exciting -message, as specified in our interface definition. -2. We return the `HelloReply` to the client and then specify that we've finished dealing with the RPC. - - -#### Server implementation - -[HelloWorldServer.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java) -shows the other main feature required to provide a gRPC service; making the service -implementation available from the network. - -```java - /* The port on which the server should run */ - private int port = 50051; - private ServerImpl server; - - private void start() throws Exception { - server = NettyServerBuilder.forPort(port) - .addService(GreeterGrpc.bindService(new GreeterImpl())) - .build().start(); - logger.info("Server started, listening on " + port); - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - // Use stderr here since the logger may have been reset by its JVM shutdown hook. - System.err.println("*** shutting down gRPC server since JVM is shutting down"); - HelloWorldServer.this.stop(); - System.err.println("*** server shut down"); - } - }); - } - -``` - -Here we create an appropriate gRPC server, binding the `Greeter` service -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. - - -### Writing a client - -Client-side gRPC is pretty simple. In this step, we'll use the generated code -to write a simple client that can access the `Greeter` server we created -in the [previous section](#server). You can see the complete client code in -[HelloWorldClient.java](https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldClient.java). - -Again, we're not going to go into much detail about how to implement a client; -we'll leave that for the tutorial. - -#### Connecting to the service - -First let's look at how we connect to the `Greeter` server. First we need -to create a gRPC channel, specifying the hostname and port of the server we -want to connect to. Then we use the channel to construct the stub instance. - - -```java - private final ChannelImpl channel; - private final GreeterGrpc.GreeterBlockingStub blockingStub; - - public HelloWorldClient(String host, int port) { - channel = - NettyChannelBuilder.forAddress(host, port).negotiationType(NegotiationType.PLAINTEXT) - .build(); - blockingStub = GreeterGrpc.newBlockingStub(channel); - } - -``` - -In this case, we create a blocking stub. This means that the RPC call waits -for the server to respond, and will either return a response or raise an -exception. gRPC Java has other kinds of stubs that make non-blocking calls -to the server, where the response is returned asynchronously. - -#### Calling an RPC - -Now we can contact the service and obtain a greeting: - -1. We construct and fill in a `HelloRequest` to send to the service. -2. We call the stub's `hello()` RPC with our request and get a `HelloReply` -back, from which we can get our greeting. - - -```java - HelloRequest req = HelloRequest.newBuilder().setName(name).build(); - HelloReply reply = blockingStub.sayHello(req); - -``` - - -### Try it out! - -Our [Gradle build file](https://github.com/grpc/grpc-java/blob/master/examples/build.gradle) simplifies building and running the examples. - -You can build and run the server from the `grpc-java` root folder with: - -```sh -$ ./gradlew :grpc-examples:helloWorldServer -``` - -and in another terminal window confirm that it receives a message. - -```sh -$ ./gradlew :grpc-examples:helloWorldClient -``` - -### 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 looked at Java code -generated from and implementing our `Greeter` service definition. However, -as you'll see if you look at the language-specific subdirectories -in this repository, we've also generated and implemented `Greeter` -in some of gRPC's other supported languages. Each service -and client uses interface code generated from the same proto -that we used for the Java example. - -So, for example, if we visit the [`go` example -directory](https://github.com/grpc/grpc-common/tree/master/go) and look at the -[`greeter_client`](https://github.com/grpc/grpc-common/blob/master/go/greeter_client/main.go), -we can see that like the Java client, it connects to a `Greeter` service -at `localhost:50051` and uses a stub to call the `SayHello` method with a -`HelloRequest`: - -```go -const ( - address = "localhost:50051" - defaultName = "world" -) - -func main() { - // Set up a connection to the server. - conn, err := grpc.Dial(address) - if err != nil { - log.Fatalf("did not connect: %v", err) - } - defer conn.Close() - c := pb.NewGreeterClient(conn) - - // Contact the server and print out its response. - name := defaultName - if len(os.Args) > 1 { - name = os.Args[1] - } - r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: - name}) - if err != nil { - log.Fatalf("could not greet: %v", err) - } - log.Printf("Greeting: %s", r.Message) -} -``` - - -If we run the Java server from earlier in another terminal window, we can -run the Go client and connect to it just like the Java client, even though -it's written in a different language. - -``` -$ greeter_client -``` -## Read more! - -- You can find links to language-specific tutorials, examples, and other docs in each language's [quick start](#quickstart). -- [gRPC Authentication Support](https://github.com/grpc/grpc-common/blob/master/grpc-auth-support.md) introduces authentication support in gRPC with supported mechanisms and examples. diff --git a/grpc-common/cpp/README.md b/grpc-common/cpp/README.md deleted file mode 100644 index e0a09ff8b8..0000000000 --- a/grpc-common/cpp/README.md +++ /dev/null @@ -1,65 +0,0 @@ -#gRPC in 3 minutes (C++) - -## Installation - -To install gRPC on your system, follow the instructions here: -[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). - -## Hello C++ gRPC! - -Here's how to build and run the C++ implementation of the [Hello World](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto) example used in [Getting started](https://github.com/grpc/grpc-common). - -The example code for this and our other examples lives in the `grpc-common` -GitHub repository. Clone this repository to your local machine by running the -following command: - - -```sh -$ git clone https://github.com/grpc/grpc-common.git -``` - -Change your current directory to grpc-common/cpp/helloworld - -```sh -$ cd grpc-common/cpp/helloworld/ -``` - - -### Generating gRPC code - -To generate the client and server side interfaces: - -```sh -$ make helloworld.grpc.pb.cc helloworld.pb.cc -``` -Which internally invokes the proto-compiler as: - -```sh -$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto -$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto -``` - -### Client and server implementations - -The client implementation is at [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). - -The server implementation is at [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). - -### Try it! -Build client and server: -```sh -$ make -``` -Run the server, which will listen on port 50051: -```sh -$ ./greeter_server -``` -Run the client (in a different terminal): -```sh -$ ./greeter_client -``` -If things go smoothly, you will see the "Greeter received: Hello world" in the client side output. - -## Tutorial - -You can find a more detailed tutorial in [gRPC Basics: C++](https://github.com/grpc/grpc-common/blob/master/cpp/cpptutorial.md) diff --git a/grpc-common/cpp/cpptutorial.md b/grpc-common/cpp/cpptutorial.md deleted file mode 100644 index c19b472744..0000000000 --- a/grpc-common/cpp/cpptutorial.md +++ /dev/null @@ -1,365 +0,0 @@ -#gRPC Basics: C++ - -This tutorial provides a basic C++ programmer's introduction to working with gRPC. By walking through this example you'll learn how to: - -- Define a service in a .proto file. -- Generate server and client code using the protocol buffer compiler. -- Use the C++ gRPC API to write a simple client and server for your service. - -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. - -This isn't a comprehensive guide to using gRPC in C++: more reference documentation is coming soon. - -## Why use gRPC? - -Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. - -With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. - -## Example code and setup - -The example code for our tutorial is in [grpc/grpc-common/cpp/route_guide](https://github.com/grpc/grpc-common/tree/master/cpp/route_guide). To download the example, clone the `grpc-common` repository by running the following command: -```shell -$ git clone https://github.com/grpc/grpc-common.git -``` - -Then change your current directory to `grpc-common/cpp/route_guide`: -```shell -$ cd grpc-common/cpp/route_guide -``` - -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the C++ quick start guide](https://github.com/grpc/grpc-common/tree/master/cpp). - - -## Defining the service - -Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). - -To define a service, you specify a named `service` in your .proto file: - -``` -service RouteGuide { - ... -} -``` - -Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: - -- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. -``` - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} -``` - -- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. -``` - // Obtains the Features available within the given Rectangle. Results are - // streamed rather than returned at once (e.g. in a response message with a - // repeated field), as the rectangle may cover a large area and contain a - // huge number of features. - rpc ListFeatures(Rectangle) returns (stream Feature) {} -``` - -- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a client-side streaming method by placing the `stream` keyword before the *request* type. -``` - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} -``` - -- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -``` - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -``` - -Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -``` -// 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; -} -``` - - -## Generating client and server code - -Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. - -For simplicity, we've provided a [makefile](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): - -```shell -$ make route_guide.grpc.pb.cc route_guide.pb.cc -``` - -which actually runs: - -```shell -$ protoc -I ../../protos --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ../../protos/route_guide.proto -$ protoc -I ../../protos --cpp_out=. ../../protos/route_guide.proto -``` - -Running this command generates the following files in your current directory: -- `route_guide.pb.h`, the header which declares your generated message classes -- `route_guide.pb.cc`, which contains the implementation of your message classes -- `route_guide.grpc.pb.h`, the header which declares your generated service classes -- `route_guide.grpc.pb.cc`, which contains the implementation of your service classes - -These contain: -- All the protocol buffer code to populate, serialize, and retrieve our request and response message types -- A class called `RouteGuide` that contains - - a remote interface type (or *stub*) for clients to call with the methods defined in the `RouteGuide` service. - - two abstract interfaces for servers to implement, also with the methods defined in the `RouteGuide` service. - - - -## Creating the server - -First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). - -There are two parts to making our `RouteGuide` service do its job: -- Implementing the service interface generated from our service definition: doing the actual "work" of our service. -- Running a gRPC server to listen for requests from clients and return the service responses. - -You can find our example `RouteGuide` server in [grpc-common/cpp/route_guide/route_guide_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_server.cc). Let's take a closer look at how it works. - -### Implementing RouteGuide - -As you can see, our server has a `RouteGuideImpl` class that implements the generated `RouteGuide::Service` interface: - -```cpp -class RouteGuideImpl final : public RouteGuide::Service { -... -} -``` -In this case we're implementing the *synchronous* version of `RouteGuide`, which provides our default gRPC server behaviour. It's also possible to implement an asynchronous interface, `RouteGuide::AsyncService`, which allows you to further customize your server's threading behaviour, though we won't look at this in this tutorial. - -`RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. - -```cpp - Status GetFeature(ServerContext* context, const Point* point, - Feature* feature) override { - feature->set_name(GetFeatureName(*point, feature_list_)); - feature->mutable_location()->CopyFrom(*point); - return Status::OK; - } -``` - -The method is passed a context object for the RPC, the client's `Point` protocol buffer request, and a `Feature` protocol buffer to fill in with the response information. In the method we populate the `Feature` with the appropriate information, and then `return` with an `OK` status to tell gRPC that we've finished dealing with the RPC and that the `Feature` can be returned to the client. - -Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. - -```cpp - Status ListFeatures(ServerContext* context, const Rectangle* rectangle, - ServerWriter* writer) override { - auto lo = rectangle->lo(); - auto hi = rectangle->hi(); - long left = std::min(lo.longitude(), hi.longitude()); - long right = std::max(lo.longitude(), hi.longitude()); - long top = std::max(lo.latitude(), hi.latitude()); - long bottom = std::min(lo.latitude(), hi.latitude()); - for (const Feature& f : feature_list_) { - if (f.location().longitude() >= left && - f.location().longitude() <= right && - f.location().latitude() >= bottom && - f.location().latitude() <= top) { - writer->Write(f); - } - } - return Status::OK; - } -``` - -As you can see, instead of getting simple request and response objects in our method parameters, this time we get a request object (the `Rectangle` in which our client wants to find `Feature`s) and a special `ServerWriter` object. In the method, we populate as many `Feature` objects as we need to return, writing them to the `ServerWriter` using its `Write()` method. Finally, as in our simple RPC, we `return Status::OK` to tell gRPC that we've finished writing responses. - -If you look at the client-side streaming method `RecordRoute` you'll see it's quite similar, except this time we get a `ServerReader` instead of a request object and a single response. We use the `ServerReader`s `Read()` method to repeatedly read in our client's requests to a request object (in this case a `Point`) until there are no more messages: the server needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. - -```cpp -while (stream->Read(&point)) { - ...//process client input -} -``` -Finally, let's look at our bidirectional streaming RPC `RouteChat()`. - -```cpp - Status RouteChat(ServerContext* context, - ServerReaderWriter* stream) override { - std::vector received_notes; - RouteNote note; - while (stream->Read(¬e)) { - for (const RouteNote& n : received_notes) { - if (n.location().latitude() == note.location().latitude() && - n.location().longitude() == note.location().longitude()) { - stream->Write(n); - } - } - received_notes.push_back(note); - } - - return Status::OK; - } -``` - -This time we get a `ServerReaderWriter` that can be used to read *and* write messages. The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. - -### Starting the server - -Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: - -```cpp -void RunServer(const std::string& db_path) { - std::string server_address("0.0.0.0:50051"); - RouteGuideImpl service(db_path); - - ServerBuilder builder; - builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); - builder.RegisterService(&service); - std::unique_ptr server(builder.BuildAndStart()); - std::cout << "Server listening on " << server_address << std::endl; - server->Wait(); -} -``` -As you can see, we build and start our server using a `ServerBuilder`. To do this, we: - -1. Create an instance of our service implementation class `RouteGuideImpl`. -2. Create an instance of the factory `ServerBuilder` class. -3. Specify the address and port we want to use to listen for client requests using the builder's `AddListeningPort()` method. -4. Register our service implementation with the builder. -5. Call `BuildAndStart()` on the builder to create and start an RPC server for our service. -5. Call `Wait()` on the server to do a blocking wait until process is killed or `Shutdown()` is called. - - -## Creating the client - -In this section, we'll look at creating a C++ client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/cpp/route_guide/route_guide_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_client.cc). - -### Creating a stub - -To call service methods, we first need to create a *stub*. - -First we need to create a gRPC *channel* for our stub, specifying the server address and port we want to connect to and any special channel arguments - in our case we'll use the default `ChannelArguments` and no SSL: - -```cpp -grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), ChannelArguments()); -``` - -Now we can use the channel to create our stub using the `NewStub` method provided in the `RouteGuide` class we generated from our .proto. - -```cpp - public: - RouteGuideClient(std::shared_ptr channel, const std::string& db) - : stub_(RouteGuide::NewStub(channel)) { - ... - } -``` - -### Calling service methods - -Now let's look at how we call our service methods. Note that in this tutorial we're calling the *blocking/synchronous* versions of each method: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception. - -#### Simple RPC - -Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. - -```cpp - Point point; - Feature feature; - point = MakePoint(409146138, -746188906); - GetOneFeature(point, &feature); - -... - - bool GetOneFeature(const Point& point, Feature* feature) { - ClientContext context; - Status status = stub_->GetFeature(&context, point, feature); - ... - } -``` - -As you can see, we create and populate a request protocol buffer object (in our case `Point`), and create a response protocol buffer object for the server to fill in. We also create a `ClientContext` object for our call - you can optionally set RPC configuration values on this object, such as deadlines, though for now we'll use the default settings. Note that you cannot reuse this object between calls. Finally, we call the method on the stub, passing it the context, request, and response. If the method returns `OK`, then we can read the response information from the server from our response object. - -```cpp - std::cout << "Found feature called " << feature->name() << " at " - << feature->location().latitude()/kCoordFactor_ << ", " - << feature->location().longitude()/kCoordFactor_ << std::endl; -``` - -#### Streaming RPCs - -Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: - -```cpp - std::unique_ptr > reader( - stub_->ListFeatures(&context, rect)); - while (reader->Read(&feature)) { - std::cout << "Found feature called " - << feature.name() << " at " - << feature.location().latitude()/kCoordFactor_ << ", " - << feature.location().longitude()/kCoordFactor_ << std::endl; - } - Status status = reader->Finish(); -``` - -Instead of passing the method a context, request, and response, we pass it a context and request and get a `ClientReader` object back. The client can use the `ClientReader` to read the server's responses. We use the `ClientReader`s `Read()` method to repeatedly read in the server's responses to a response protocol buffer object (in this case a `Feature`) until there are no more messages: the client needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. Finally, we call `Finish()` on the stream to complete the call and get our RPC status. - -The client-side streaming method `RecordRoute` is similar, except there we pass the method a context and response object and get back a `ClientWriter`. - -```cpp - std::unique_ptr > writer( - stub_->RecordRoute(&context, &stats)); - for (int i = 0; i < kPoints; i++) { - const Feature& f = feature_list_[feature_distribution(generator)]; - std::cout << "Visiting point " - << f.location().latitude()/kCoordFactor_ << ", " - << f.location().longitude()/kCoordFactor_ << std::endl; - if (!writer->Write(f.location())) { - // Broken stream. - break; - } - std::this_thread::sleep_for(std::chrono::milliseconds( - delay_distribution(generator))); - } - writer->WritesDone(); - Status status = writer->Finish(); - if (status.IsOk()) { - std::cout << "Finished trip with " << stats.point_count() << " points\n" - << "Passed " << stats.feature_count() << " features\n" - << "Travelled " << stats.distance() << " meters\n" - << "It took " << stats.elapsed_time() << " seconds" - << std::endl; - } else { - std::cout << "RecordRoute rpc failed." << std::endl; - } -``` - -Once we've finished writing our client's requests to the stream using `Write()`, we need to call `WritesDone()` on the stream to let gRPC know that we've finished writing, then `Finish()` to complete the call and get our RPC status. If the status is `OK`, our response object that we initially passed to `RecordRoute()` will be populated with the server's response. - -Finally, let's look at our bidirectional streaming RPC `RouteChat()`. In this case, we just pass a context to the method and get back a `ClientReaderWriter`, which we can use to both write and read messages. - -```cpp - std::shared_ptr > stream( - stub_->RouteChat(&context)); -``` - -The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. - -## Try it out! - -Build client and server: -```shell -$ make -``` -Run the server, which will listen on port 50051: -```shell -$ ./route_guide_server -``` -Run the client (in a different terminal): -```shell -$ ./route_guide_client -``` - diff --git a/grpc-common/cpp/helloworld/Makefile b/grpc-common/cpp/helloworld/Makefile deleted file mode 100644 index f2093afa05..0000000000 --- a/grpc-common/cpp/helloworld/Makefile +++ /dev/null @@ -1,119 +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. -# - -CXX = g++ -CPPFLAGS += -I/usr/local/include -pthread -CXXFLAGS += -std=c++11 -LDFLAGS += -L/usr/local/lib -lgrpc++_unsecure -lgrpc -lgpr -lprotobuf -lpthread -ldl -PROTOC = protoc -GRPC_CPP_PLUGIN = grpc_cpp_plugin -GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` - -PROTOS_PATH = ../../protos - -vpath %.proto $(PROTOS_PATH) - -all: system-check greeter_client greeter_server greeter_async_client greeter_async_server - -greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o - $(CXX) $^ $(LDFLAGS) -o $@ - -greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o - $(CXX) $^ $(LDFLAGS) -o $@ - -greeter_async_client: helloworld.pb.o helloworld.grpc.pb.o greeter_async_client.o - $(CXX) $^ $(LDFLAGS) -o $@ - -greeter_async_server: helloworld.pb.o helloworld.grpc.pb.o greeter_async_server.o - $(CXX) $^ $(LDFLAGS) -o $@ - -%.grpc.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< - -%.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< - -clean: - rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server greeter_async_client greeter_async_server - - -# The following is to test your system and ensure a smoother experience. -# They are by no means necessary to actually compile a grpc-enabled software. - -PROTOC_CMD = which $(PROTOC) -PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 -PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) -HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) -ifeq ($(HAS_PROTOC),true) -HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) -endif -HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) - -SYSTEM_OK = false -ifeq ($(HAS_VALID_PROTOC),true) -ifeq ($(HAS_PLUGIN),true) -SYSTEM_OK = true -endif -endif - -system-check: -ifneq ($(HAS_VALID_PROTOC),true) - @echo " DEPENDENCY ERROR" - @echo - @echo "You don't have protoc 3.0.0 installed in your path." - @echo "Please install Google protocol buffers 3.0.0 and its compiler." - @echo "You can find it here:" - @echo - @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-alpha-1" - @echo - @echo "Here is what I get when trying to evaluate your version of protoc:" - @echo - -$(PROTOC) --version - @echo - @echo -endif -ifneq ($(HAS_PLUGIN),true) - @echo " DEPENDENCY ERROR" - @echo - @echo "You don't have the grpc c++ protobuf plugin installed in your path." - @echo "Please install grpc. You can find it here:" - @echo - @echo " https://github.com/grpc/grpc" - @echo - @echo "Here is what I get when trying to detect if you have the plugin:" - @echo - -which $(GRPC_CPP_PLUGIN) - @echo - @echo -endif -ifneq ($(SYSTEM_OK),true) - @false -endif diff --git a/grpc-common/cpp/helloworld/README.md b/grpc-common/cpp/helloworld/README.md deleted file mode 100644 index c406051e80..0000000000 --- a/grpc-common/cpp/helloworld/README.md +++ /dev/null @@ -1,260 +0,0 @@ -# gRPC C++ Hello World Tutorial - -### Install gRPC -Make sure you have installed gRPC on your system. Follow the instructions here: -[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). - -### Get the tutorial source code - -The example code for this and our other examples lives in the `grpc-common` -GitHub repository. Clone this repository to your local machine by running the -following command: - - -```sh -$ git clone https://github.com/grpc/grpc-common.git -``` - -Change your current directory to grpc-common/cpp/helloworld - -```sh -$ cd grpc-common/cpp/helloworld/ -``` - -### Defining a service - -The first step in creating our example is to define a *service*: an RPC -service specifies the methods that can be called remotely with their parameters -and return types. As you saw in the -[overview](#protocolbuffers) above, gRPC does this using [protocol -buffers](https://developers.google.com/protocol-buffers/docs/overview). We -use the protocol buffers interface definition language (IDL) to define our -service methods, and define the parameters and return -types as protocol buffer message types. Both the client and the -server use interface code generated from the service definition. - -Here's our example service definition, defined using protocol buffers IDL in -[helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). The `Greeting` -service has one method, `hello`, that lets the server receive a single -`HelloRequest` -message from the remote client containing the user's name, then send back -a greeting in a single `HelloReply`. This is the simplest type of RPC you -can specify in gRPC - we'll look at some other types later in this document. - -``` -syntax = "proto3"; - -option java_package = "ex.grpc"; - -package helloworld; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} - -``` - - -### Generating gRPC code - -Once we've defined our service, we use the protocol buffer compiler -`protoc` to generate the special client and server code we need to create -our application. The generated code contains both stub code for clients to -use and an abstract interface for servers to implement, both with the method -defined in our `Greeting` service. - -To generate the client and server side interfaces: - -```sh -$ make helloworld.grpc.pb.cc helloworld.pb.cc -``` -Which internally invokes the proto-compiler as: - -```sh -$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto -$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto -``` - -### Writing a client - -- Create a channel. A channel is a logical connection to an endpoint. A gRPC - channel can be created with the target address, credentials to use and - arguments as follows - - ``` - auto channel = CreateChannel("localhost:50051", InsecureCredentials(), ChannelArguments()); - ``` - -- Create a stub. A stub implements the rpc methods of a service and in the - generated code, a method is provided to created a stub with a channel: - - ``` - auto stub = helloworld::Greeter::NewStub(channel); - ``` - -- Make a unary rpc, with `ClientContext` and request/response proto messages. - - ``` - ClientContext context; - HelloRequest request; - request.set_name("hello"); - HelloReply reply; - Status status = stub->SayHello(&context, request, &reply); - ``` - -- Check returned status and response. - - ``` - if (status.ok()) { - // check reply.message() - } else { - // rpc failed. - } - ``` - -For a working example, refer to [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). - -### Writing a server - -- Implement the service interface - - ``` - 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; - } - }; - - ``` - -- Build a server exporting the service - - ``` - GreeterServiceImpl service; - ServerBuilder builder; - builder.AddListeningPort("0.0.0.0:50051", grpc::InsecureServerCredentials()); - builder.RegisterService(&service); - std::unique_ptr server(builder.BuildAndStart()); - ``` - -For a working example, refer to [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). - -### Writing asynchronous client and server - -gRPC uses `CompletionQueue` API for asynchronous operations. The basic work flow -is -- bind a `CompletionQueue` to a rpc call -- do something like a read or write, present with a unique `void*` tag -- call `CompletionQueue::Next` to wait for operations to complete. If a tag - appears, it indicates that the corresponding operation is complete. - -#### Async client - -The channel and stub creation code is the same as the sync client. - -- Initiate the rpc and create a handle for the rpc. Bind the rpc to a - `CompletionQueue`. - - ``` - CompletionQueue cq; - auto rpc = stub->AsyncSayHello(&context, request, &cq); - ``` - -- Ask for reply and final status, with a unique tag - - ``` - Status status; - rpc->Finish(&reply, &status, (void*)1); - ``` - -- Wait for the completion queue to return the next tag. The reply and status are - ready once the tag passed into the corresponding `Finish()` call is returned. - - ``` - void* got_tag; - bool ok = false; - cq.Next(&got_tag, &ok); - if (ok && got_tag == (void*)1) { - // check reply and status - } - ``` - -For a working example, refer to [greeter_async_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_async_client.cc). - -#### Async server - -The server implementation requests a rpc call with a tag and then wait for the -completion queue to return the tag. The basic flow is - -- Build a server exporting the async service - - ``` - helloworld::Greeter::AsyncService service; - ServerBuilder builder; - builder.AddListeningPort("0.0.0.0:50051", InsecureServerCredentials()); - builder.RegisterAsyncService(&service); - auto cq = builder.AddCompletionQueue(); - auto server = builder.BuildAndStart(); - ``` - -- Request one rpc - - ``` - ServerContext context; - HelloRequest request; - ServerAsyncResponseWriter responder; - service.RequestSayHello(&context, &request, &responder, &cq, &cq, (void*)1); - ``` - -- Wait for the completion queue to return the tag. The context, request and - responder are ready once the tag is retrieved. - - ``` - HelloReply reply; - Status status; - void* got_tag; - bool ok = false; - cq.Next(&got_tag, &ok); - if (ok && got_tag == (void*)1) { - // set reply and status - responder.Finish(reply, status, (void*)2); - } - ``` - -- Wait for the completion queue to return the tag. The rpc is finished when the - tag is back. - - ``` - void* got_tag; - bool ok = false; - cq.Next(&got_tag, &ok); - if (ok && got_tag == (void*)2) { - // clean up - } - ``` - -To handle multiple rpcs, the async server creates an object `CallData` to -maintain the state of each rpc and use the address of it as the unique tag. For -simplicity the server only uses one completion queue for all events, and runs a -main loop in `HandleRpcs` to query the queue. - -For a working example, refer to [greeter_async_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_async_server.cc). - - - - diff --git a/grpc-common/cpp/helloworld/greeter_async_client.cc b/grpc-common/cpp/helloworld/greeter_async_client.cc deleted file mode 100644 index d99f89b135..0000000000 --- a/grpc-common/cpp/helloworld/greeter_async_client.cc +++ /dev/null @@ -1,98 +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. - * - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include "helloworld.grpc.pb.h" - -using grpc::Channel; -using grpc::ChannelArguments; -using grpc::ClientAsyncResponseReader; -using grpc::ClientContext; -using grpc::CompletionQueue; -using grpc::Status; -using helloworld::HelloRequest; -using helloworld::HelloReply; -using helloworld::Greeter; - -class GreeterClient { - public: - explicit GreeterClient(std::shared_ptr channel) - : stub_(Greeter::NewStub(channel)) {} - - std::string SayHello(const std::string& user) { - HelloRequest request; - request.set_name(user); - HelloReply reply; - ClientContext context; - CompletionQueue cq; - Status status; - - std::unique_ptr > rpc( - stub_->AsyncSayHello(&context, request, &cq)); - rpc->Finish(&reply, &status, (void*)1); - void* got_tag; - bool ok = false; - cq.Next(&got_tag, &ok); - GPR_ASSERT(ok); - GPR_ASSERT(got_tag == (void*)1); - - if (status.ok()) { - return reply.message(); - } else { - return "Rpc failed"; - } - } - - private: - std::unique_ptr stub_; -}; - -int main(int argc, char** argv) { - GreeterClient greeter(grpc::CreateChannel( - "localhost:50051", grpc::InsecureCredentials(), ChannelArguments())); - std::string user("world"); - std::string reply = greeter.SayHello(user); - std::cout << "Greeter received: " << reply << std::endl; - - return 0; -} diff --git a/grpc-common/cpp/helloworld/greeter_async_server.cc b/grpc-common/cpp/helloworld/greeter_async_server.cc deleted file mode 100644 index b8a0dbf0e2..0000000000 --- a/grpc-common/cpp/helloworld/greeter_async_server.cc +++ /dev/null @@ -1,136 +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. - * - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include "helloworld.grpc.pb.h" - -using grpc::Server; -using grpc::ServerAsyncResponseWriter; -using grpc::ServerBuilder; -using grpc::ServerContext; -using grpc::ServerCompletionQueue; -using grpc::Status; -using helloworld::HelloRequest; -using helloworld::HelloReply; -using helloworld::Greeter; - -class ServerImpl final { - public: - ~ServerImpl() { - server_->Shutdown(); - cq_->Shutdown(); - } - - // There is no shutdown handling in this code. - void Run() { - std::string server_address("0.0.0.0:50051"); - - ServerBuilder builder; - builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); - builder.RegisterAsyncService(&service_); - cq_ = builder.AddCompletionQueue(); - server_ = builder.BuildAndStart(); - std::cout << "Server listening on " << server_address << std::endl; - - HandleRpcs(); - } - - private: - class CallData { - public: - CallData(Greeter::AsyncService* service, ServerCompletionQueue* cq) - : service_(service), cq_(cq), responder_(&ctx_), status_(CREATE) { - Proceed(); - } - - void Proceed() { - if (status_ == CREATE) { - service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_, - this); - status_ = PROCESS; - } else if (status_ == PROCESS) { - new CallData(service_, cq_); - std::string prefix("Hello "); - reply_.set_message(prefix + request_.name()); - responder_.Finish(reply_, Status::OK, this); - status_ = FINISH; - } else { - delete this; - } - } - - private: - Greeter::AsyncService* service_; - ServerCompletionQueue* cq_; - ServerContext ctx_; - HelloRequest request_; - HelloReply reply_; - ServerAsyncResponseWriter responder_; - enum CallStatus { CREATE, PROCESS, FINISH }; - CallStatus status_; - }; - - // This can be run in multiple threads if needed. - void HandleRpcs() { - new CallData(&service_, cq_.get()); - void* tag; - bool ok; - while (true) { - cq_->Next(&tag, &ok); - GPR_ASSERT(ok); - static_cast(tag)->Proceed(); - } - } - - std::unique_ptr cq_; - Greeter::AsyncService service_; - std::unique_ptr server_; -}; - -int main(int argc, char** argv) { - ServerImpl server; - server.Run(); - - return 0; -} diff --git a/grpc-common/cpp/helloworld/greeter_client.cc b/grpc-common/cpp/helloworld/greeter_client.cc deleted file mode 100644 index dd0358ac95..0000000000 --- a/grpc-common/cpp/helloworld/greeter_client.cc +++ /dev/null @@ -1,85 +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. - * - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include "helloworld.grpc.pb.h" - -using grpc::Channel; -using grpc::ChannelArguments; -using grpc::ClientContext; -using grpc::Status; -using helloworld::HelloRequest; -using helloworld::HelloReply; -using helloworld::Greeter; - -class GreeterClient { - public: - GreeterClient(std::shared_ptr channel) - : stub_(Greeter::NewStub(channel)) {} - - std::string SayHello(const std::string& user) { - HelloRequest request; - request.set_name(user); - HelloReply reply; - ClientContext context; - - Status status = stub_->SayHello(&context, request, &reply); - if (status.ok()) { - return reply.message(); - } else { - return "Rpc failed"; - } - } - - private: - std::unique_ptr stub_; -}; - -int main(int argc, char** argv) { - GreeterClient greeter( - grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), - ChannelArguments())); - std::string user("world"); - std::string reply = greeter.SayHello(user); - std::cout << "Greeter received: " << reply << std::endl; - - return 0; -} diff --git a/grpc-common/cpp/helloworld/greeter_server.cc b/grpc-common/cpp/helloworld/greeter_server.cc deleted file mode 100644 index c1efdf563c..0000000000 --- a/grpc-common/cpp/helloworld/greeter_server.cc +++ /dev/null @@ -1,78 +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. - * - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include "helloworld.grpc.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.AddListeningPort(server_address, grpc::InsecureServerCredentials()); - builder.RegisterService(&service); - std::unique_ptr server(builder.BuildAndStart()); - std::cout << "Server listening on " << server_address << std::endl; - server->Wait(); -} - -int main(int argc, char** argv) { - RunServer(); - - return 0; -} diff --git a/grpc-common/cpp/route_guide/Makefile b/grpc-common/cpp/route_guide/Makefile deleted file mode 100644 index b906177af3..0000000000 --- a/grpc-common/cpp/route_guide/Makefile +++ /dev/null @@ -1,113 +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. -# - -CXX = g++ -CPPFLAGS += -I/usr/local/include -pthread -CXXFLAGS += -std=c++11 -LDFLAGS += -L/usr/local/lib -lgrpc++_unsecure -lgrpc -lgpr -lprotobuf -lpthread -ldl -PROTOC = protoc -GRPC_CPP_PLUGIN = grpc_cpp_plugin -GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` - -PROTOS_PATH = ../../protos - -vpath %.proto $(PROTOS_PATH) - -all: system-check route_guide_client route_guide_server - -route_guide_client: route_guide.pb.o route_guide.grpc.pb.o route_guide_client.o helper.o - $(CXX) $^ $(LDFLAGS) -o $@ - -route_guide_server: route_guide.pb.o route_guide.grpc.pb.o route_guide_server.o helper.o - $(CXX) $^ $(LDFLAGS) -o $@ - -%.grpc.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< - -%.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< - -clean: - rm -f *.o *.pb.cc *.pb.h route_guide_client route_guide_server - - -# The following is to test your system and ensure a smoother experience. -# They are by no means necessary to actually compile a grpc-enabled software. - -PROTOC_CMD = which $(PROTOC) -PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 -PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) -HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) -ifeq ($(HAS_PROTOC),true) -HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) -endif -HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) - -SYSTEM_OK = false -ifeq ($(HAS_VALID_PROTOC),true) -ifeq ($(HAS_PLUGIN),true) -SYSTEM_OK = true -endif -endif - -system-check: -ifneq ($(HAS_VALID_PROTOC),true) - @echo " DEPENDENCY ERROR" - @echo - @echo "You don't have protoc 3.0.0 installed in your path." - @echo "Please install Google protocol buffers 3.0.0 and its compiler." - @echo "You can find it here:" - @echo - @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-alpha-1" - @echo - @echo "Here is what I get when trying to evaluate your version of protoc:" - @echo - -$(PROTOC) --version - @echo - @echo -endif -ifneq ($(HAS_PLUGIN),true) - @echo " DEPENDENCY ERROR" - @echo - @echo "You don't have the grpc c++ protobuf plugin installed in your path." - @echo "Please install grpc. You can find it here:" - @echo - @echo " https://github.com/grpc/grpc" - @echo - @echo "Here is what I get when trying to detect if you have the plugin:" - @echo - -which $(GRPC_CPP_PLUGIN) - @echo - @echo -endif -ifneq ($(SYSTEM_OK),true) - @false -endif diff --git a/grpc-common/cpp/route_guide/helper.cc b/grpc-common/cpp/route_guide/helper.cc deleted file mode 100644 index c2415afdf7..0000000000 --- a/grpc-common/cpp/route_guide/helper.cc +++ /dev/null @@ -1,178 +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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include "route_guide.grpc.pb.h" - -namespace examples { - -std::string GetDbFileContent(int argc, char** argv) { - std::string db_path; - std::string arg_str("--db_path"); - if (argc > 1) { - std::string argv_1 = argv[1]; - size_t start_position = argv_1.find(arg_str); - if (start_position != std::string::npos) { - start_position += arg_str.size(); - if (argv_1[start_position] == ' ' || - argv_1[start_position] == '=') { - db_path = argv_1.substr(start_position + 1); - } - } - } else { - db_path = "route_guide_db.json"; - } - std::ifstream db_file(db_path); - if (!db_file.is_open()) { - std::cout << "Failed to open " << db_path << std::endl; - return ""; - } - std::stringstream db; - db << db_file.rdbuf(); - return db.str(); -} - -// A simple parser for the json db file. It requires the db file to have the -// exact form of [{"location": { "latitude": 123, "longitude": 456}, "name": -// "the name can be empty" }, { ... } ... The spaces will be stripped. -class Parser { - public: - explicit Parser(const std::string& db) : db_(db) { - // Remove all spaces. - db_.erase( - std::remove_if(db_.begin(), db_.end(), isspace), - db_.end()); - if (!Match("[")) { - SetFailedAndReturnFalse(); - } - } - - bool Finished() { - return current_ >= db_.size(); - } - - bool TryParseOne(Feature* feature) { - if (failed_ || Finished() || !Match("{")) { - return SetFailedAndReturnFalse(); - } - if (!Match(location_) || !Match("{") || !Match(latitude_)) { - return SetFailedAndReturnFalse(); - } - long temp = 0; - ReadLong(&temp); - feature->mutable_location()->set_latitude(temp); - if (!Match(",") || !Match(longitude_)) { - return SetFailedAndReturnFalse(); - } - ReadLong(&temp); - feature->mutable_location()->set_longitude(temp); - if (!Match("},") || !Match(name_) || !Match("\"")) { - return SetFailedAndReturnFalse(); - } - size_t name_start = current_; - while (current_ != db_.size() && db_[current_++] != '"') { - } - if (current_ == db_.size()) { - return SetFailedAndReturnFalse(); - } - feature->set_name(db_.substr(name_start, current_-name_start-1)); - if (!Match("},")) { - if (db_[current_ - 1] == ']' && current_ == db_.size()) { - return true; - } - return SetFailedAndReturnFalse(); - } - return true; - } - - private: - - bool SetFailedAndReturnFalse() { - failed_ = true; - return false; - } - - bool Match(const std::string& prefix) { - bool eq = db_.substr(current_, prefix.size()) == prefix; - current_ += prefix.size(); - return eq; - } - - void ReadLong(long* l) { - size_t start = current_; - while (current_ != db_.size() && db_[current_] != ',' && db_[current_] != '}') { - current_++; - } - // It will throw an exception if fails. - *l = std::stol(db_.substr(start, current_ - start)); - } - - bool failed_ = false; - std::string db_; - size_t current_ = 0; - const std::string location_ = "\"location\":"; - const std::string latitude_ = "\"latitude\":"; - const std::string longitude_ = "\"longitude\":"; - const std::string name_ = "\"name\":"; -}; - -void ParseDb(const std::string& db, std::vector* feature_list) { - feature_list->clear(); - std::string db_content(db); - db_content.erase( - std::remove_if(db_content.begin(), db_content.end(), isspace), - db_content.end()); - - Parser parser(db_content); - Feature feature; - while (!parser.Finished()) { - feature_list->push_back(Feature()); - if (!parser.TryParseOne(&feature_list->back())) { - std::cout << "Error parsing the db file"; - feature_list->clear(); - break; - } - } - std::cout << "DB parsed, loaded " << feature_list->size() - << " features." << std::endl; -} - - -} // namespace examples - diff --git a/grpc-common/cpp/route_guide/helper.h b/grpc-common/cpp/route_guide/helper.h deleted file mode 100644 index 65c93c1d34..0000000000 --- a/grpc-common/cpp/route_guide/helper.h +++ /dev/null @@ -1,50 +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. - * - */ - -#ifndef GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_ -#define GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_ - -#include -#include - -namespace examples { -class Feature; - -std::string GetDbFileContent(int argc, char** argv); - -void ParseDb(const std::string& db, std::vector* feature_list); - -} // namespace examples - -#endif // GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_ - diff --git a/grpc-common/cpp/route_guide/route_guide_client.cc b/grpc-common/cpp/route_guide/route_guide_client.cc deleted file mode 100644 index 814def27f3..0000000000 --- a/grpc-common/cpp/route_guide/route_guide_client.cc +++ /dev/null @@ -1,252 +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. - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include "helper.h" -#include "route_guide.grpc.pb.h" - -using grpc::Channel; -using grpc::ChannelArguments; -using grpc::ClientContext; -using grpc::ClientReader; -using grpc::ClientReaderWriter; -using grpc::ClientWriter; -using grpc::Status; -using examples::Point; -using examples::Feature; -using examples::Rectangle; -using examples::RouteSummary; -using examples::RouteNote; -using examples::RouteGuide; - -Point MakePoint(long latitude, long longitude) { - Point p; - p.set_latitude(latitude); - p.set_longitude(longitude); - return p; -} - -Feature MakeFeature(const std::string& name, - long latitude, long longitude) { - Feature f; - f.set_name(name); - f.mutable_location()->CopyFrom(MakePoint(latitude, longitude)); - return f; -} - -RouteNote MakeRouteNote(const std::string& message, - long latitude, long longitude) { - RouteNote n; - n.set_message(message); - n.mutable_location()->CopyFrom(MakePoint(latitude, longitude)); - return n; -} - -class RouteGuideClient { - public: - RouteGuideClient(std::shared_ptr channel, const std::string& db) - : stub_(RouteGuide::NewStub(channel)) { - examples::ParseDb(db, &feature_list_); - } - - void GetFeature() { - Point point; - Feature feature; - point = MakePoint(409146138, -746188906); - GetOneFeature(point, &feature); - point = MakePoint(0, 0); - GetOneFeature(point, &feature); - } - - void ListFeatures() { - examples::Rectangle rect; - Feature feature; - ClientContext context; - - rect.mutable_lo()->set_latitude(400000000); - rect.mutable_lo()->set_longitude(-750000000); - rect.mutable_hi()->set_latitude(420000000); - rect.mutable_hi()->set_longitude(-730000000); - std::cout << "Looking for features between 40, -75 and 42, -73" - << std::endl; - - std::unique_ptr > reader( - stub_->ListFeatures(&context, rect)); - while (reader->Read(&feature)) { - std::cout << "Found feature called " - << feature.name() << " at " - << feature.location().latitude()/kCoordFactor_ << ", " - << feature.location().longitude()/kCoordFactor_ << std::endl; - } - Status status = reader->Finish(); - if (status.ok()) { - std::cout << "ListFeatures rpc succeeded." << std::endl; - } else { - std::cout << "ListFeatures rpc failed." << std::endl; - } - } - - void RecordRoute() { - Point point; - RouteSummary stats; - ClientContext context; - const int kPoints = 10; - unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); - - std::default_random_engine generator(seed); - std::uniform_int_distribution feature_distribution( - 0, feature_list_.size() - 1); - std::uniform_int_distribution delay_distribution( - 500, 1500); - - std::unique_ptr > writer( - stub_->RecordRoute(&context, &stats)); - for (int i = 0; i < kPoints; i++) { - const Feature& f = feature_list_[feature_distribution(generator)]; - std::cout << "Visiting point " - << f.location().latitude()/kCoordFactor_ << ", " - << f.location().longitude()/kCoordFactor_ << std::endl; - if (!writer->Write(f.location())) { - // Broken stream. - break; - } - std::this_thread::sleep_for(std::chrono::milliseconds( - delay_distribution(generator))); - } - writer->WritesDone(); - Status status = writer->Finish(); - if (status.ok()) { - std::cout << "Finished trip with " << stats.point_count() << " points\n" - << "Passed " << stats.feature_count() << " features\n" - << "Travelled " << stats.distance() << " meters\n" - << "It took " << stats.elapsed_time() << " seconds" - << std::endl; - } else { - std::cout << "RecordRoute rpc failed." << std::endl; - } - } - - void RouteChat() { - ClientContext context; - - std::shared_ptr > stream( - stub_->RouteChat(&context)); - - std::thread writer([stream]() { - std::vector notes{ - MakeRouteNote("First message", 0, 0), - MakeRouteNote("Second message", 0, 1), - MakeRouteNote("Third message", 1, 0), - MakeRouteNote("Fourth message", 0, 0)}; - for (const RouteNote& note : notes) { - std::cout << "Sending message " << note.message() - << " at " << note.location().latitude() << ", " - << note.location().longitude() << std::endl; - stream->Write(note); - } - stream->WritesDone(); - }); - - RouteNote server_note; - while (stream->Read(&server_note)) { - std::cout << "Got message " << server_note.message() - << " at " << server_note.location().latitude() << ", " - << server_note.location().longitude() << std::endl; - } - writer.join(); - Status status = stream->Finish(); - if (!status.ok()) { - std::cout << "RouteChat rpc failed." << std::endl; - } - } - - private: - - bool GetOneFeature(const Point& point, Feature* feature) { - ClientContext context; - Status status = stub_->GetFeature(&context, point, feature); - if (!status.ok()) { - std::cout << "GetFeature rpc failed." << std::endl; - return false; - } - if (!feature->has_location()) { - std::cout << "Server returns incomplete feature." << std::endl; - return false; - } - if (feature->name().empty()) { - std::cout << "Found no feature at " - << feature->location().latitude()/kCoordFactor_ << ", " - << feature->location().longitude()/kCoordFactor_ << std::endl; - } else { - std::cout << "Found feature called " << feature->name() << " at " - << feature->location().latitude()/kCoordFactor_ << ", " - << feature->location().longitude()/kCoordFactor_ << std::endl; - } - return true; - } - - const float kCoordFactor_ = 10000000.0; - std::unique_ptr stub_; - std::vector feature_list_; -}; - -int main(int argc, char** argv) { - // Expect only arg: --db_path=path/to/route_guide_db.json. - std::string db = examples::GetDbFileContent(argc, argv); - RouteGuideClient guide( - grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), - ChannelArguments()), - db); - - std::cout << "-------------- GetFeature --------------" << std::endl; - guide.GetFeature(); - std::cout << "-------------- ListFeatures --------------" << std::endl; - guide.ListFeatures(); - std::cout << "-------------- RecordRoute --------------" << std::endl; - guide.RecordRoute(); - std::cout << "-------------- RouteChat --------------" << std::endl; - guide.RouteChat(); - - return 0; -} diff --git a/grpc-common/cpp/route_guide/route_guide_db.json b/grpc-common/cpp/route_guide/route_guide_db.json deleted file mode 100644 index 9d6a980ab7..0000000000 --- a/grpc-common/cpp/route_guide/route_guide_db.json +++ /dev/null @@ -1,601 +0,0 @@ -[{ - "location": { - "latitude": 407838351, - "longitude": -746143763 - }, - "name": "Patriots Path, Mendham, NJ 07945, USA" -}, { - "location": { - "latitude": 408122808, - "longitude": -743999179 - }, - "name": "101 New Jersey 10, Whippany, NJ 07981, USA" -}, { - "location": { - "latitude": 413628156, - "longitude": -749015468 - }, - "name": "U.S. 6, Shohola, PA 18458, USA" -}, { - "location": { - "latitude": 419999544, - "longitude": -740371136 - }, - "name": "5 Conners Road, Kingston, NY 12401, USA" -}, { - "location": { - "latitude": 414008389, - "longitude": -743951297 - }, - "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" -}, { - "location": { - "latitude": 419611318, - "longitude": -746524769 - }, - "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" -}, { - "location": { - "latitude": 406109563, - "longitude": -742186778 - }, - "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" -}, { - "location": { - "latitude": 416802456, - "longitude": -742370183 - }, - "name": "352 South Mountain Road, Wallkill, NY 12589, USA" -}, { - "location": { - "latitude": 412950425, - "longitude": -741077389 - }, - "name": "Bailey Turn Road, Harriman, NY 10926, USA" -}, { - "location": { - "latitude": 412144655, - "longitude": -743949739 - }, - "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" -}, { - "location": { - "latitude": 415736605, - "longitude": -742847522 - }, - "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" -}, { - "location": { - "latitude": 413843930, - "longitude": -740501726 - }, - "name": "162 Merrill Road, Highland Mills, NY 10930, USA" -}, { - "location": { - "latitude": 410873075, - "longitude": -744459023 - }, - "name": "Clinton Road, West Milford, NJ 07480, USA" -}, { - "location": { - "latitude": 412346009, - "longitude": -744026814 - }, - "name": "16 Old Brook Lane, Warwick, NY 10990, USA" -}, { - "location": { - "latitude": 402948455, - "longitude": -747903913 - }, - "name": "3 Drake Lane, Pennington, NJ 08534, USA" -}, { - "location": { - "latitude": 406337092, - "longitude": -740122226 - }, - "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" -}, { - "location": { - "latitude": 406421967, - "longitude": -747727624 - }, - "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" -}, { - "location": { - "latitude": 416318082, - "longitude": -749677716 - }, - "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" -}, { - "location": { - "latitude": 415301720, - "longitude": -748416257 - }, - "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" -}, { - "location": { - "latitude": 402647019, - "longitude": -747071791 - }, - "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" -}, { - "location": { - "latitude": 412567807, - "longitude": -741058078 - }, - "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" -}, { - "location": { - "latitude": 416855156, - "longitude": -744420597 - }, - "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" -}, { - "location": { - "latitude": 404663628, - "longitude": -744820157 - }, - "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" -}, { - "location": { - "latitude": 407113723, - "longitude": -749746483 - }, - "name": "" -}, { - "location": { - "latitude": 402133926, - "longitude": -743613249 - }, - "name": "" -}, { - "location": { - "latitude": 400273442, - "longitude": -741220915 - }, - "name": "" -}, { - "location": { - "latitude": 411236786, - "longitude": -744070769 - }, - "name": "" -}, { - "location": { - "latitude": 411633782, - "longitude": -746784970 - }, - "name": "211-225 Plains Road, Augusta, NJ 07822, USA" -}, { - "location": { - "latitude": 415830701, - "longitude": -742952812 - }, - "name": "" -}, { - "location": { - "latitude": 413447164, - "longitude": -748712898 - }, - "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" -}, { - "location": { - "latitude": 405047245, - "longitude": -749800722 - }, - "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" -}, { - "location": { - "latitude": 418858923, - "longitude": -746156790 - }, - "name": "" -}, { - "location": { - "latitude": 417951888, - "longitude": -748484944 - }, - "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" -}, { - "location": { - "latitude": 407033786, - "longitude": -743977337 - }, - "name": "26 East 3rd Street, New Providence, NJ 07974, USA" -}, { - "location": { - "latitude": 417548014, - "longitude": -740075041 - }, - "name": "" -}, { - "location": { - "latitude": 410395868, - "longitude": -744972325 - }, - "name": "" -}, { - "location": { - "latitude": 404615353, - "longitude": -745129803 - }, - "name": "" -}, { - "location": { - "latitude": 406589790, - "longitude": -743560121 - }, - "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" -}, { - "location": { - "latitude": 414653148, - "longitude": -740477477 - }, - "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" -}, { - "location": { - "latitude": 405957808, - "longitude": -743255336 - }, - "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" -}, { - "location": { - "latitude": 411733589, - "longitude": -741648093 - }, - "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" -}, { - "location": { - "latitude": 412676291, - "longitude": -742606606 - }, - "name": "1270 Lakes Road, Monroe, NY 10950, USA" -}, { - "location": { - "latitude": 409224445, - "longitude": -748286738 - }, - "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" -}, { - "location": { - "latitude": 406523420, - "longitude": -742135517 - }, - "name": "652 Garden Street, Elizabeth, NJ 07202, USA" -}, { - "location": { - "latitude": 401827388, - "longitude": -740294537 - }, - "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" -}, { - "location": { - "latitude": 410564152, - "longitude": -743685054 - }, - "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" -}, { - "location": { - "latitude": 408472324, - "longitude": -740726046 - }, - "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" -}, { - "location": { - "latitude": 412452168, - "longitude": -740214052 - }, - "name": "5 White Oak Lane, Stony Point, NY 10980, USA" -}, { - "location": { - "latitude": 409146138, - "longitude": -746188906 - }, - "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" -}, { - "location": { - "latitude": 404701380, - "longitude": -744781745 - }, - "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" -}, { - "location": { - "latitude": 409642566, - "longitude": -746017679 - }, - "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" -}, { - "location": { - "latitude": 408031728, - "longitude": -748645385 - }, - "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" -}, { - "location": { - "latitude": 413700272, - "longitude": -742135189 - }, - "name": "367 Prospect Road, Chester, NY 10918, USA" -}, { - "location": { - "latitude": 404310607, - "longitude": -740282632 - }, - "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" -}, { - "location": { - "latitude": 409319800, - "longitude": -746201391 - }, - "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" -}, { - "location": { - "latitude": 406685311, - "longitude": -742108603 - }, - "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" -}, { - "location": { - "latitude": 419018117, - "longitude": -749142781 - }, - "name": "43 Dreher Road, Roscoe, NY 12776, USA" -}, { - "location": { - "latitude": 412856162, - "longitude": -745148837 - }, - "name": "Swan Street, Pine Island, NY 10969, USA" -}, { - "location": { - "latitude": 416560744, - "longitude": -746721964 - }, - "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" -}, { - "location": { - "latitude": 405314270, - "longitude": -749836354 - }, - "name": "" -}, { - "location": { - "latitude": 414219548, - "longitude": -743327440 - }, - "name": "" -}, { - "location": { - "latitude": 415534177, - "longitude": -742900616 - }, - "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" -}, { - "location": { - "latitude": 406898530, - "longitude": -749127080 - }, - "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" -}, { - "location": { - "latitude": 407586880, - "longitude": -741670168 - }, - "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" -}, { - "location": { - "latitude": 400106455, - "longitude": -742870190 - }, - "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" -}, { - "location": { - "latitude": 400066188, - "longitude": -746793294 - }, - "name": "" -}, { - "location": { - "latitude": 418803880, - "longitude": -744102673 - }, - "name": "40 Mountain Road, Napanoch, NY 12458, USA" -}, { - "location": { - "latitude": 414204288, - "longitude": -747895140 - }, - "name": "" -}, { - "location": { - "latitude": 414777405, - "longitude": -740615601 - }, - "name": "" -}, { - "location": { - "latitude": 415464475, - "longitude": -747175374 - }, - "name": "48 North Road, Forestburgh, NY 12777, USA" -}, { - "location": { - "latitude": 404062378, - "longitude": -746376177 - }, - "name": "" -}, { - "location": { - "latitude": 405688272, - "longitude": -749285130 - }, - "name": "" -}, { - "location": { - "latitude": 400342070, - "longitude": -748788996 - }, - "name": "" -}, { - "location": { - "latitude": 401809022, - "longitude": -744157964 - }, - "name": "" -}, { - "location": { - "latitude": 404226644, - "longitude": -740517141 - }, - "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" -}, { - "location": { - "latitude": 410322033, - "longitude": -747871659 - }, - "name": "" -}, { - "location": { - "latitude": 407100674, - "longitude": -747742727 - }, - "name": "" -}, { - "location": { - "latitude": 418811433, - "longitude": -741718005 - }, - "name": "213 Bush Road, Stone Ridge, NY 12484, USA" -}, { - "location": { - "latitude": 415034302, - "longitude": -743850945 - }, - "name": "" -}, { - "location": { - "latitude": 411349992, - "longitude": -743694161 - }, - "name": "" -}, { - "location": { - "latitude": 404839914, - "longitude": -744759616 - }, - "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" -}, { - "location": { - "latitude": 414638017, - "longitude": -745957854 - }, - "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" -}, { - "location": { - "latitude": 412127800, - "longitude": -740173578 - }, - "name": "" -}, { - "location": { - "latitude": 401263460, - "longitude": -747964303 - }, - "name": "" -}, { - "location": { - "latitude": 412843391, - "longitude": -749086026 - }, - "name": "" -}, { - "location": { - "latitude": 418512773, - "longitude": -743067823 - }, - "name": "" -}, { - "location": { - "latitude": 404318328, - "longitude": -740835638 - }, - "name": "42-102 Main Street, Belford, NJ 07718, USA" -}, { - "location": { - "latitude": 419020746, - "longitude": -741172328 - }, - "name": "" -}, { - "location": { - "latitude": 404080723, - "longitude": -746119569 - }, - "name": "" -}, { - "location": { - "latitude": 401012643, - "longitude": -744035134 - }, - "name": "" -}, { - "location": { - "latitude": 404306372, - "longitude": -741079661 - }, - "name": "" -}, { - "location": { - "latitude": 403966326, - "longitude": -748519297 - }, - "name": "" -}, { - "location": { - "latitude": 405002031, - "longitude": -748407866 - }, - "name": "" -}, { - "location": { - "latitude": 409532885, - "longitude": -742200683 - }, - "name": "" -}, { - "location": { - "latitude": 416851321, - "longitude": -742674555 - }, - "name": "" -}, { - "location": { - "latitude": 406411633, - "longitude": -741722051 - }, - "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" -}, { - "location": { - "latitude": 413069058, - "longitude": -744597778 - }, - "name": "261 Van Sickle Road, Goshen, NY 10924, USA" -}, { - "location": { - "latitude": 418465462, - "longitude": -746859398 - }, - "name": "" -}, { - "location": { - "latitude": 411733222, - "longitude": -744228360 - }, - "name": "" -}, { - "location": { - "latitude": 410248224, - "longitude": -747127767 - }, - "name": "3 Hasta Way, Newton, NJ 07860, USA" -}] diff --git a/grpc-common/cpp/route_guide/route_guide_server.cc b/grpc-common/cpp/route_guide/route_guide_server.cc deleted file mode 100644 index b37539299a..0000000000 --- a/grpc-common/cpp/route_guide/route_guide_server.cc +++ /dev/null @@ -1,202 +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. - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include "helper.h" -#include "route_guide.grpc.pb.h" - -using grpc::Server; -using grpc::ServerBuilder; -using grpc::ServerContext; -using grpc::ServerReader; -using grpc::ServerReaderWriter; -using grpc::ServerWriter; -using grpc::Status; -using examples::Point; -using examples::Feature; -using examples::Rectangle; -using examples::RouteSummary; -using examples::RouteNote; -using examples::RouteGuide; -using std::chrono::system_clock; - - -float ConvertToRadians(float num) { - return num * 3.1415926 /180; -} - -float GetDistance(const Point& start, const Point& end) { - const float kCoordFactor = 10000000.0; - float lat_1 = start.latitude() / kCoordFactor; - float lat_2 = end.latitude() / kCoordFactor; - float lon_1 = start.longitude() / kCoordFactor; - float lon_2 = end.longitude() / kCoordFactor; - float lat_rad_1 = ConvertToRadians(lat_1); - float lat_rad_2 = ConvertToRadians(lat_2); - float delta_lat_rad = ConvertToRadians(lat_2-lat_1); - float delta_lon_rad = ConvertToRadians(lon_2-lon_1); - - float a = pow(sin(delta_lat_rad/2), 2) + cos(lat_rad_1) * cos(lat_rad_2) * - pow(sin(delta_lon_rad/2), 2); - float c = 2 * atan2(sqrt(a), sqrt(1-a)); - int R = 6371000; // metres - - return R * c; -} - -std::string GetFeatureName(const Point& point, - const std::vector& feature_list) { - for (const Feature& f : feature_list) { - if (f.location().latitude() == point.latitude() && - f.location().longitude() == point.longitude()) { - return f.name(); - } - } - return ""; -} - -class RouteGuideImpl final : public RouteGuide::Service { - public: - explicit RouteGuideImpl(const std::string& db) { - examples::ParseDb(db, &feature_list_); - } - - Status GetFeature(ServerContext* context, const Point* point, - Feature* feature) override { - feature->set_name(GetFeatureName(*point, feature_list_)); - feature->mutable_location()->CopyFrom(*point); - return Status::OK; - } - - Status ListFeatures(ServerContext* context, - const examples::Rectangle* rectangle, - ServerWriter* writer) override { - auto lo = rectangle->lo(); - auto hi = rectangle->hi(); - long left = (std::min)(lo.longitude(), hi.longitude()); - long right = (std::max)(lo.longitude(), hi.longitude()); - long top = (std::max)(lo.latitude(), hi.latitude()); - long bottom = (std::min)(lo.latitude(), hi.latitude()); - for (const Feature& f : feature_list_) { - if (f.location().longitude() >= left && - f.location().longitude() <= right && - f.location().latitude() >= bottom && - f.location().latitude() <= top) { - writer->Write(f); - } - } - return Status::OK; - } - - Status RecordRoute(ServerContext* context, ServerReader* reader, - RouteSummary* summary) override { - Point point; - int point_count = 0; - int feature_count = 0; - float distance = 0.0; - Point previous; - - system_clock::time_point start_time = system_clock::now(); - while (reader->Read(&point)) { - point_count++; - if (!GetFeatureName(point, feature_list_).empty()) { - feature_count++; - } - if (point_count != 1) { - distance += GetDistance(previous, point); - } - previous = point; - } - system_clock::time_point end_time = system_clock::now(); - summary->set_point_count(point_count); - summary->set_feature_count(feature_count); - summary->set_distance(static_cast(distance)); - auto secs = std::chrono::duration_cast( - end_time - start_time); - summary->set_elapsed_time(secs.count()); - - return Status::OK; - } - - Status RouteChat(ServerContext* context, - ServerReaderWriter* stream) override { - std::vector received_notes; - RouteNote note; - while (stream->Read(¬e)) { - for (const RouteNote& n : received_notes) { - if (n.location().latitude() == note.location().latitude() && - n.location().longitude() == note.location().longitude()) { - stream->Write(n); - } - } - received_notes.push_back(note); - } - - return Status::OK; - } - - private: - - std::vector feature_list_; -}; - -void RunServer(const std::string& db_path) { - std::string server_address("0.0.0.0:50051"); - RouteGuideImpl service(db_path); - - ServerBuilder builder; - builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); - builder.RegisterService(&service); - std::unique_ptr server(builder.BuildAndStart()); - std::cout << "Server listening on " << server_address << std::endl; - server->Wait(); -} - -int main(int argc, char** argv) { - // Expect only arg: --db_path=path/to/route_guide_db.json. - std::string db = examples::GetDbFileContent(argc, argv); - RunServer(db); - - return 0; -} diff --git a/grpc-common/csharp/.gitignore b/grpc-common/csharp/.gitignore deleted file mode 100644 index 585000ea2d..0000000000 --- a/grpc-common/csharp/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -bin/ -obj/ -packages/ -*.suo -*.userprefs diff --git a/grpc-common/csharp/.nuget/packages.config b/grpc-common/csharp/.nuget/packages.config deleted file mode 100644 index b14373069f..0000000000 --- a/grpc-common/csharp/.nuget/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/grpc-common/csharp/Greeter.sln b/grpc-common/csharp/Greeter.sln deleted file mode 100644 index 9430e94de9..0000000000 --- a/grpc-common/csharp/Greeter.sln +++ /dev/null @@ -1,42 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.31101.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Greeter", "Greeter\Greeter.csproj", "{724DFC8C-4B57-4C3F-811C-0463BE2A2829}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterServer", "GreeterServer\GreeterServer.csproj", "{A7706C84-92D2-4B7A-B779-76B64D2950EC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterClient", "GreeterClient\GreeterClient.csproj", "{ACCF4597-3748-4117-8633-1CB767F8CCC3}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{FF1EBE95-F20D-4C27-8A61-D0125F3C8152}" - ProjectSection(SolutionItems) = preProject - .nuget\packages.config = .nuget\packages.config - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Debug|Any CPU.Build.0 = Debug|Any CPU - {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Release|Any CPU.ActiveCfg = Release|Any CPU - {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Release|Any CPU.Build.0 = Release|Any CPU - {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Release|Any CPU.Build.0 = Release|Any CPU - {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution - StartupItem = Greeter\Greeter.csproj - EndGlobalSection -EndGlobal diff --git a/grpc-common/csharp/Greeter/.gitignore b/grpc-common/csharp/Greeter/.gitignore deleted file mode 100644 index 1746e3269e..0000000000 --- a/grpc-common/csharp/Greeter/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -bin -obj diff --git a/grpc-common/csharp/Greeter/Greeter.csproj b/grpc-common/csharp/Greeter/Greeter.csproj deleted file mode 100644 index b8f965dbd2..0000000000 --- a/grpc-common/csharp/Greeter/Greeter.csproj +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {724DFC8C-4B57-4C3F-811C-0463BE2A2829} - Library - Greeter - Greeter - v4.5 - 927432a0 - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - false - - - full - true - bin\Release - prompt - 4 - false - - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - - - False - ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll - - - - False - ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - - - ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll - - - - - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - \ No newline at end of file diff --git a/grpc-common/csharp/Greeter/Helloworld.cs b/grpc-common/csharp/Greeter/Helloworld.cs deleted file mode 100644 index 923a4271e9..0000000000 --- a/grpc-common/csharp/Greeter/Helloworld.cs +++ /dev/null @@ -1,617 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: helloworld.proto -#pragma warning disable 1591, 0612, 3021 -#region Designer generated code - -using pb = global::Google.ProtocolBuffers; -using pbc = global::Google.ProtocolBuffers.Collections; -using pbd = global::Google.ProtocolBuffers.Descriptors; -using scg = global::System.Collections.Generic; -namespace helloworld { - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public static partial class Helloworld { - - #region Extension registration - public static void RegisterAllExtensions(pb::ExtensionRegistry registry) { - } - #endregion - #region Static variables - internal static pbd::MessageDescriptor internal__static_helloworld_HelloRequest__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_helloworld_HelloRequest__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_helloworld_HelloReply__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_helloworld_HelloReply__FieldAccessorTable; - #endregion - #region Descriptor - public static pbd::FileDescriptor Descriptor { - get { return descriptor; } - } - private static pbd::FileDescriptor descriptor; - - static Helloworld() { - byte[] descriptorData = global::System.Convert.FromBase64String( - string.Concat( - "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz", - "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo", - "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl", - "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEISChBpby5ncnBjLmV4", - "YW1wbGVz")); - pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) { - descriptor = root; - internal__static_helloworld_HelloRequest__Descriptor = Descriptor.MessageTypes[0]; - internal__static_helloworld_HelloRequest__FieldAccessorTable = - new pb::FieldAccess.FieldAccessorTable(internal__static_helloworld_HelloRequest__Descriptor, - new string[] { "Name", }); - internal__static_helloworld_HelloReply__Descriptor = Descriptor.MessageTypes[1]; - internal__static_helloworld_HelloReply__FieldAccessorTable = - new pb::FieldAccess.FieldAccessorTable(internal__static_helloworld_HelloReply__Descriptor, - new string[] { "Message", }); - pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance(); - RegisterAllExtensions(registry); - return registry; - }; - pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData, - new pbd::FileDescriptor[] { - }, assigner); - } - #endregion - - } - #region Messages - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class HelloRequest : pb::GeneratedMessage { - private HelloRequest() { } - private static readonly HelloRequest defaultInstance = new HelloRequest().MakeReadOnly(); - private static readonly string[] _helloRequestFieldNames = new string[] { "name" }; - private static readonly uint[] _helloRequestFieldTags = new uint[] { 10 }; - public static HelloRequest DefaultInstance { - get { return defaultInstance; } - } - - public override HelloRequest DefaultInstanceForType { - get { return DefaultInstance; } - } - - protected override HelloRequest ThisMessage { - get { return this; } - } - - public static pbd::MessageDescriptor Descriptor { - get { return global::helloworld.Helloworld.internal__static_helloworld_HelloRequest__Descriptor; } - } - - protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { - get { return global::helloworld.Helloworld.internal__static_helloworld_HelloRequest__FieldAccessorTable; } - } - - public const int NameFieldNumber = 1; - private bool hasName; - private string name_ = ""; - public bool HasName { - get { return hasName; } - } - public string Name { - get { return name_; } - } - - public override bool IsInitialized { - get { - return true; - } - } - - public override void WriteTo(pb::ICodedOutputStream output) { - CalcSerializedSize(); - string[] field_names = _helloRequestFieldNames; - if (hasName) { - output.WriteString(1, field_names[0], Name); - } - UnknownFields.WriteTo(output); - } - - private int memoizedSerializedSize = -1; - public override int SerializedSize { - get { - int size = memoizedSerializedSize; - if (size != -1) return size; - return CalcSerializedSize(); - } - } - - private int CalcSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (hasName) { - size += pb::CodedOutputStream.ComputeStringSize(1, Name); - } - size += UnknownFields.SerializedSize; - memoizedSerializedSize = size; - return size; - } - public static HelloRequest ParseFrom(pb::ByteString data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static HelloRequest ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static HelloRequest ParseFrom(byte[] data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static HelloRequest ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static HelloRequest ParseFrom(global::System.IO.Stream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static HelloRequest ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - public static HelloRequest ParseDelimitedFrom(global::System.IO.Stream input) { - return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); - } - public static HelloRequest ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); - } - public static HelloRequest ParseFrom(pb::ICodedInputStream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static HelloRequest ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - private HelloRequest MakeReadOnly() { - return this; - } - - public static Builder CreateBuilder() { return new Builder(); } - public override Builder ToBuilder() { return CreateBuilder(this); } - public override Builder CreateBuilderForType() { return new Builder(); } - public static Builder CreateBuilder(HelloRequest prototype) { - return new Builder(prototype); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Builder : pb::GeneratedBuilder { - protected override Builder ThisBuilder { - get { return this; } - } - public Builder() { - result = DefaultInstance; - resultIsReadOnly = true; - } - internal Builder(HelloRequest cloneFrom) { - result = cloneFrom; - resultIsReadOnly = true; - } - - private bool resultIsReadOnly; - private HelloRequest result; - - private HelloRequest PrepareBuilder() { - if (resultIsReadOnly) { - HelloRequest original = result; - result = new HelloRequest(); - resultIsReadOnly = false; - MergeFrom(original); - } - return result; - } - - public override bool IsInitialized { - get { return result.IsInitialized; } - } - - protected override HelloRequest MessageBeingBuilt { - get { return PrepareBuilder(); } - } - - public override Builder Clear() { - result = DefaultInstance; - resultIsReadOnly = true; - return this; - } - - public override Builder Clone() { - if (resultIsReadOnly) { - return new Builder(result); - } else { - return new Builder().MergeFrom(result); - } - } - - public override pbd::MessageDescriptor DescriptorForType { - get { return global::helloworld.HelloRequest.Descriptor; } - } - - public override HelloRequest DefaultInstanceForType { - get { return global::helloworld.HelloRequest.DefaultInstance; } - } - - public override HelloRequest BuildPartial() { - if (resultIsReadOnly) { - return result; - } - resultIsReadOnly = true; - return result.MakeReadOnly(); - } - - public override Builder MergeFrom(pb::IMessage other) { - if (other is HelloRequest) { - return MergeFrom((HelloRequest) other); - } else { - base.MergeFrom(other); - return this; - } - } - - public override Builder MergeFrom(HelloRequest other) { - if (other == global::helloworld.HelloRequest.DefaultInstance) return this; - PrepareBuilder(); - if (other.HasName) { - Name = other.Name; - } - this.MergeUnknownFields(other.UnknownFields); - return this; - } - - public override Builder MergeFrom(pb::ICodedInputStream input) { - return MergeFrom(input, pb::ExtensionRegistry.Empty); - } - - public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - PrepareBuilder(); - pb::UnknownFieldSet.Builder unknownFields = null; - uint tag; - string field_name; - while (input.ReadTag(out tag, out field_name)) { - if(tag == 0 && field_name != null) { - int field_ordinal = global::System.Array.BinarySearch(_helloRequestFieldNames, field_name, global::System.StringComparer.Ordinal); - if(field_ordinal >= 0) - tag = _helloRequestFieldTags[field_ordinal]; - else { - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - continue; - } - } - switch (tag) { - case 0: { - throw pb::InvalidProtocolBufferException.InvalidTag(); - } - default: { - if (pb::WireFormat.IsEndGroupTag(tag)) { - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - break; - } - case 10: { - result.hasName = input.ReadString(ref result.name_); - break; - } - } - } - - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - - - public bool HasName { - get { return result.hasName; } - } - public string Name { - get { return result.Name; } - set { SetName(value); } - } - public Builder SetName(string value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasName = true; - result.name_ = value; - return this; - } - public Builder ClearName() { - PrepareBuilder(); - result.hasName = false; - result.name_ = ""; - return this; - } - } - static HelloRequest() { - object.ReferenceEquals(global::helloworld.Helloworld.Descriptor, null); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class HelloReply : pb::GeneratedMessage { - private HelloReply() { } - private static readonly HelloReply defaultInstance = new HelloReply().MakeReadOnly(); - private static readonly string[] _helloReplyFieldNames = new string[] { "message" }; - private static readonly uint[] _helloReplyFieldTags = new uint[] { 10 }; - public static HelloReply DefaultInstance { - get { return defaultInstance; } - } - - public override HelloReply DefaultInstanceForType { - get { return DefaultInstance; } - } - - protected override HelloReply ThisMessage { - get { return this; } - } - - public static pbd::MessageDescriptor Descriptor { - get { return global::helloworld.Helloworld.internal__static_helloworld_HelloReply__Descriptor; } - } - - protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { - get { return global::helloworld.Helloworld.internal__static_helloworld_HelloReply__FieldAccessorTable; } - } - - public const int MessageFieldNumber = 1; - private bool hasMessage; - private string message_ = ""; - public bool HasMessage { - get { return hasMessage; } - } - public string Message { - get { return message_; } - } - - public override bool IsInitialized { - get { - return true; - } - } - - public override void WriteTo(pb::ICodedOutputStream output) { - CalcSerializedSize(); - string[] field_names = _helloReplyFieldNames; - if (hasMessage) { - output.WriteString(1, field_names[0], Message); - } - UnknownFields.WriteTo(output); - } - - private int memoizedSerializedSize = -1; - public override int SerializedSize { - get { - int size = memoizedSerializedSize; - if (size != -1) return size; - return CalcSerializedSize(); - } - } - - private int CalcSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (hasMessage) { - size += pb::CodedOutputStream.ComputeStringSize(1, Message); - } - size += UnknownFields.SerializedSize; - memoizedSerializedSize = size; - return size; - } - public static HelloReply ParseFrom(pb::ByteString data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static HelloReply ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static HelloReply ParseFrom(byte[] data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static HelloReply ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static HelloReply ParseFrom(global::System.IO.Stream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static HelloReply ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - public static HelloReply ParseDelimitedFrom(global::System.IO.Stream input) { - return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); - } - public static HelloReply ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); - } - public static HelloReply ParseFrom(pb::ICodedInputStream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static HelloReply ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - private HelloReply MakeReadOnly() { - return this; - } - - public static Builder CreateBuilder() { return new Builder(); } - public override Builder ToBuilder() { return CreateBuilder(this); } - public override Builder CreateBuilderForType() { return new Builder(); } - public static Builder CreateBuilder(HelloReply prototype) { - return new Builder(prototype); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Builder : pb::GeneratedBuilder { - protected override Builder ThisBuilder { - get { return this; } - } - public Builder() { - result = DefaultInstance; - resultIsReadOnly = true; - } - internal Builder(HelloReply cloneFrom) { - result = cloneFrom; - resultIsReadOnly = true; - } - - private bool resultIsReadOnly; - private HelloReply result; - - private HelloReply PrepareBuilder() { - if (resultIsReadOnly) { - HelloReply original = result; - result = new HelloReply(); - resultIsReadOnly = false; - MergeFrom(original); - } - return result; - } - - public override bool IsInitialized { - get { return result.IsInitialized; } - } - - protected override HelloReply MessageBeingBuilt { - get { return PrepareBuilder(); } - } - - public override Builder Clear() { - result = DefaultInstance; - resultIsReadOnly = true; - return this; - } - - public override Builder Clone() { - if (resultIsReadOnly) { - return new Builder(result); - } else { - return new Builder().MergeFrom(result); - } - } - - public override pbd::MessageDescriptor DescriptorForType { - get { return global::helloworld.HelloReply.Descriptor; } - } - - public override HelloReply DefaultInstanceForType { - get { return global::helloworld.HelloReply.DefaultInstance; } - } - - public override HelloReply BuildPartial() { - if (resultIsReadOnly) { - return result; - } - resultIsReadOnly = true; - return result.MakeReadOnly(); - } - - public override Builder MergeFrom(pb::IMessage other) { - if (other is HelloReply) { - return MergeFrom((HelloReply) other); - } else { - base.MergeFrom(other); - return this; - } - } - - public override Builder MergeFrom(HelloReply other) { - if (other == global::helloworld.HelloReply.DefaultInstance) return this; - PrepareBuilder(); - if (other.HasMessage) { - Message = other.Message; - } - this.MergeUnknownFields(other.UnknownFields); - return this; - } - - public override Builder MergeFrom(pb::ICodedInputStream input) { - return MergeFrom(input, pb::ExtensionRegistry.Empty); - } - - public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - PrepareBuilder(); - pb::UnknownFieldSet.Builder unknownFields = null; - uint tag; - string field_name; - while (input.ReadTag(out tag, out field_name)) { - if(tag == 0 && field_name != null) { - int field_ordinal = global::System.Array.BinarySearch(_helloReplyFieldNames, field_name, global::System.StringComparer.Ordinal); - if(field_ordinal >= 0) - tag = _helloReplyFieldTags[field_ordinal]; - else { - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - continue; - } - } - switch (tag) { - case 0: { - throw pb::InvalidProtocolBufferException.InvalidTag(); - } - default: { - if (pb::WireFormat.IsEndGroupTag(tag)) { - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - break; - } - case 10: { - result.hasMessage = input.ReadString(ref result.message_); - break; - } - } - } - - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - - - public bool HasMessage { - get { return result.hasMessage; } - } - public string Message { - get { return result.Message; } - set { SetMessage(value); } - } - public Builder SetMessage(string value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasMessage = true; - result.message_ = value; - return this; - } - public Builder ClearMessage() { - PrepareBuilder(); - result.hasMessage = false; - result.message_ = ""; - return this; - } - } - static HelloReply() { - object.ReferenceEquals(global::helloworld.Helloworld.Descriptor, null); - } - } - - #endregion - -} - -#endregion Designer generated code diff --git a/grpc-common/csharp/Greeter/HelloworldGrpc.cs b/grpc-common/csharp/Greeter/HelloworldGrpc.cs deleted file mode 100644 index 1ca9d2899b..0000000000 --- a/grpc-common/csharp/Greeter/HelloworldGrpc.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: helloworld.proto -#region Designer generated code - -using System; -using System.Threading; -using System.Threading.Tasks; -using Grpc.Core; - -namespace helloworld { - public static class Greeter - { - static readonly string __ServiceName = "helloworld.Greeter"; - - static readonly Marshaller __Marshaller_HelloRequest = Marshallers.Create((arg) => arg.ToByteArray(), global::helloworld.HelloRequest.ParseFrom); - static readonly Marshaller __Marshaller_HelloReply = Marshallers.Create((arg) => arg.ToByteArray(), global::helloworld.HelloReply.ParseFrom); - - static readonly Method __Method_SayHello = new Method( - MethodType.Unary, - "SayHello", - __Marshaller_HelloRequest, - __Marshaller_HelloReply); - - // client-side stub interface - public interface IGreeterClient - { - global::helloworld.HelloReply SayHello(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)); - Task SayHelloAsync(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)); - } - - // server-side interface - public interface IGreeter - { - Task SayHello(ServerCallContext context, global::helloworld.HelloRequest request); - } - - // client stub - public class GreeterClient : AbstractStub, IGreeterClient - { - public GreeterClient(Channel channel) : this(channel, StubConfiguration.Default) - { - } - public GreeterClient(Channel channel, StubConfiguration config) : base(channel, config) - { - } - public global::helloworld.HelloReply SayHello(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)) - { - var call = CreateCall(__ServiceName, __Method_SayHello); - return Calls.BlockingUnaryCall(call, request, token); - } - public Task SayHelloAsync(global::helloworld.HelloRequest request, CancellationToken token = default(CancellationToken)) - { - var call = CreateCall(__ServiceName, __Method_SayHello); - return Calls.AsyncUnaryCall(call, request, token); - } - } - - // creates service definition that can be registered with a server - public static ServerServiceDefinition BindService(IGreeter serviceImpl) - { - return ServerServiceDefinition.CreateBuilder(__ServiceName) - .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build(); - } - - // creates a new client stub - public static IGreeterClient NewStub(Channel channel) - { - return new GreeterClient(channel); - } - - // creates a new client stub - public static IGreeterClient NewStub(Channel channel, StubConfiguration config) - { - return new GreeterClient(channel, config); - } - } -} -#endregion diff --git a/grpc-common/csharp/Greeter/Properties/AssemblyInfo.cs b/grpc-common/csharp/Greeter/Properties/AssemblyInfo.cs deleted file mode 100644 index b9d0dc264d..0000000000 --- a/grpc-common/csharp/Greeter/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. -[assembly: AssemblyTitle("Greeter")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("jtattermusch")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. -[assembly: AssemblyVersion("1.0.*")] -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/grpc-common/csharp/Greeter/packages.config b/grpc-common/csharp/Greeter/packages.config deleted file mode 100644 index 5922553bc3..0000000000 --- a/grpc-common/csharp/Greeter/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/grpc-common/csharp/Greeter/protos/helloworld.proto b/grpc-common/csharp/Greeter/protos/helloworld.proto deleted file mode 100644 index e02ebd94e7..0000000000 --- a/grpc-common/csharp/Greeter/protos/helloworld.proto +++ /dev/null @@ -1,52 +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. - -// TODO(jtattermusch): as of now, C# protobufs don't officially support -// proto3. -syntax = "proto2"; - -option java_package = "io.grpc.examples"; - -package helloworld; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - optional string name = 1; -} - -// The response message containing the greetings -message HelloReply { - optional string message = 1; -} diff --git a/grpc-common/csharp/GreeterClient/.gitignore b/grpc-common/csharp/GreeterClient/.gitignore deleted file mode 100644 index 1746e3269e..0000000000 --- a/grpc-common/csharp/GreeterClient/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -bin -obj diff --git a/grpc-common/csharp/GreeterClient/GreeterClient.csproj b/grpc-common/csharp/GreeterClient/GreeterClient.csproj deleted file mode 100644 index 59b768af01..0000000000 --- a/grpc-common/csharp/GreeterClient/GreeterClient.csproj +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {ACCF4597-3748-4117-8633-1CB767F8CCC3} - Exe - GreeterClient - GreeterClient - v4.5 - 985ca8be - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - - - full - true - bin\Release - prompt - 4 - true - - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - - - False - ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll - - - - False - ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - - - ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll - - - - - - - - - - {724DFC8C-4B57-4C3F-811C-0463BE2A2829} - Greeter - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - \ No newline at end of file diff --git a/grpc-common/csharp/GreeterClient/Program.cs b/grpc-common/csharp/GreeterClient/Program.cs deleted file mode 100644 index 61c29762b1..0000000000 --- a/grpc-common/csharp/GreeterClient/Program.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using Grpc.Core; -using helloworld; - -namespace GreeterClient -{ - class ClientMainClass - { - public static void Main(string[] args) - { - GrpcEnvironment.Initialize(); - - using (Channel channel = new Channel("127.0.0.1:50051")) - { - var client = Greeter.NewStub(channel); - String user = "you"; - - var reply = client.SayHello(new HelloRequest.Builder { Name = user }.Build()); - Console.WriteLine("Greeting: " + reply.Message); - } - - GrpcEnvironment.Shutdown(); - } - } -} diff --git a/grpc-common/csharp/GreeterClient/Properties/AssemblyInfo.cs b/grpc-common/csharp/GreeterClient/Properties/AssemblyInfo.cs deleted file mode 100644 index 1422e952d8..0000000000 --- a/grpc-common/csharp/GreeterClient/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. -[assembly: AssemblyTitle("GreeterClient")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("jtattermusch")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. -[assembly: AssemblyVersion("1.0.*")] -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/grpc-common/csharp/GreeterClient/packages.config b/grpc-common/csharp/GreeterClient/packages.config deleted file mode 100644 index 5922553bc3..0000000000 --- a/grpc-common/csharp/GreeterClient/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/grpc-common/csharp/GreeterServer/.gitignore b/grpc-common/csharp/GreeterServer/.gitignore deleted file mode 100644 index 1746e3269e..0000000000 --- a/grpc-common/csharp/GreeterServer/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -bin -obj diff --git a/grpc-common/csharp/GreeterServer/GreeterServer.csproj b/grpc-common/csharp/GreeterServer/GreeterServer.csproj deleted file mode 100644 index cd50d6cd52..0000000000 --- a/grpc-common/csharp/GreeterServer/GreeterServer.csproj +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {A7706C84-92D2-4B7A-B779-76B64D2950EC} - Exe - GreeterServer - GreeterServer - v4.5 - a1eeb1d8 - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - - - full - true - bin\Release - prompt - 4 - true - - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - - - False - ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll - - - - False - ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - - - ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll - - - - - - - - - - {724DFC8C-4B57-4C3F-811C-0463BE2A2829} - Greeter - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - \ No newline at end of file diff --git a/grpc-common/csharp/GreeterServer/Program.cs b/grpc-common/csharp/GreeterServer/Program.cs deleted file mode 100644 index 9482797c3b..0000000000 --- a/grpc-common/csharp/GreeterServer/Program.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Threading.Tasks; -using Grpc.Core; -using helloworld; - -namespace GreeterServer -{ - class GreeterImpl : Greeter.IGreeter - { - // Server side handler of the SayHello RPC - public Task SayHello(ServerCallContext context, HelloRequest request) - { - var reply = new HelloReply.Builder { Message = "Hello " + request.Name }.Build(); - return Task.FromResult(reply); - } - } - - class ServerMainClass - { - public static void Main(string[] args) - { - GrpcEnvironment.Initialize(); - - Server server = new Server(); - server.AddServiceDefinition(Greeter.BindService(new GreeterImpl())); - int port = server.AddListeningPort("localhost", 50051); - server.Start(); - - Console.WriteLine("Greeter server listening on port " + port); - Console.WriteLine("Press any key to stop the server..."); - Console.ReadKey(); - - server.ShutdownAsync().Wait(); - GrpcEnvironment.Shutdown(); - } - } -} diff --git a/grpc-common/csharp/GreeterServer/Properties/AssemblyInfo.cs b/grpc-common/csharp/GreeterServer/Properties/AssemblyInfo.cs deleted file mode 100644 index f8a8d521d8..0000000000 --- a/grpc-common/csharp/GreeterServer/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. -[assembly: AssemblyTitle("GreeterServer")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("jtattermusch")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. -[assembly: AssemblyVersion("1.0.*")] -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/grpc-common/csharp/GreeterServer/packages.config b/grpc-common/csharp/GreeterServer/packages.config deleted file mode 100644 index 5922553bc3..0000000000 --- a/grpc-common/csharp/GreeterServer/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/grpc-common/csharp/README.md b/grpc-common/csharp/README.md deleted file mode 100644 index 77d1aaf2e6..0000000000 --- a/grpc-common/csharp/README.md +++ /dev/null @@ -1,72 +0,0 @@ -gRPC in 3 minutes (C#) -======================== - -BACKGROUND -------------- -For this sample, we've already generated the server and client stubs from `helloworld.proto`. -Example projects depend on NuGet packages `Grpc` and `Google.ProtocolBuffers` which have been already added to the project for you. - -PREREQUISITES -------------- -**Windows** -- .NET 4.5+ -- VS 2013 (with NuGet plugin installed) - -**Linux (Mono)** -- Mono -- Monodevelop 5.9 with NuGet Add-in installed (older versions might work) - -**MacOS (Mono)** -- Xamarin Studio (with NuGet plugin installed) - -BUILD -------- - -**Windows** -- Clone this repository. - -- Open solution `Greeter.sln` with Visual Studio - -- Build the solution (this will automatically download NuGet dependencies) - -**Linux (Mono)** -- Clone this repository. - -- Install gRPC C Core using instructions in https://github.com/grpc/homebrew-grpc - -- gRPC C# depends on native shared library `libgrpc_csharp_ext.so`. To make it visible - to Mono runtime, follow instructions in [Using gRPC C# on Linux](https://github.com/grpc/grpc/tree/master/src/csharp#usage-linux-mono) - -- Open solution `Greeter.sln` in MonoDevelop (you need to manually restore dependencies by using `mono nuget.exe restore` if you don't have NuGet add-in) - -- Build the solution. - -**MacOS (Mono)** -- See [Using gRPC C# on MacOS](https://github.com/grpc/grpc/tree/master/src/csharp#usage-macos-mono) for more info - on MacOS support. - -Try it! -------- - -- Run the server - - ``` - > cd GreeterServer/bin/Debug - > GreeterServer.exe - ``` - -- Run the client - - ``` - > cd GreeterClient/bin/Debug - > GreeterClient.exe - ``` - -You can also run the server and client directly from Visual Studio. - -On Linux or Mac, use `mono GreeterServer.exe` and `mono GreeterClient.exe` to run the server and client. - -Tutorial --------- - -You can find a more detailed tutorial in [gRPC Basics: C#](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/README.md) diff --git a/grpc-common/csharp/route_guide/.gitignore b/grpc-common/csharp/route_guide/.gitignore deleted file mode 100644 index 585000ea2d..0000000000 --- a/grpc-common/csharp/route_guide/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -bin/ -obj/ -packages/ -*.suo -*.userprefs diff --git a/grpc-common/csharp/route_guide/.nuget/packages.config b/grpc-common/csharp/route_guide/.nuget/packages.config deleted file mode 100644 index b14373069f..0000000000 --- a/grpc-common/csharp/route_guide/.nuget/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/README.md b/grpc-common/csharp/route_guide/README.md deleted file mode 100644 index 35c6024bcf..0000000000 --- a/grpc-common/csharp/route_guide/README.md +++ /dev/null @@ -1,409 +0,0 @@ -#gRPC Basics: C# # - -This tutorial provides a basic C# programmer's introduction to working with gRPC. By walking through this example you'll learn how to: - -- Define a service in a .proto file. -- Generate server and client code using the protocol buffer compiler. -- Use the C# gRPC API to write a simple client and server for your service. - -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial only uses the proto2 version of the protocol buffers language, as proto3 support for C# is not ready yet (see [protobuf C# README](https://github.com/google/protobuf/tree/master/csharp#proto2--proto3)). - -This isn't a comprehensive guide to using gRPC in C#: more reference documentation is coming soon. - -## Why use gRPC? - -Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. - -With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. - -## Example code and setup - -The example code for our tutorial is in [grpc/grpc-common/csharp/route_guide](https://github.com/grpc/grpc-common/tree/master/csharp/route_guide). To download the example, clone the `grpc-common` repository by running the following command: -```shell -$ git clone https://github.com/google/grpc-common.git -``` - -All the files for this tutorial are in the directory `grpc-common/csharp/route_guide`. -Open the solution `grpc-common/csharp/route_guide/RouteGuide.sln` from Visual Studio (or Monodevelop on Linux). - -On Windows, you should not need to do anything besides opening the solution. All the needed dependencies will be restored -for you automatically by the `Grpc` NuGet package upon building the solution. - -On Linux (or MacOS), you will first need to install protobuf and gRPC C Core using Linuxbrew (or Homebrew) tool in order to be -able to generate the server and client interface code and run the examples. Follow the instructions for [Linux](https://github.com/grpc/grpc/tree/master/src/csharp#usage-linux-mono) or [MacOS](https://github.com/grpc/grpc/tree/master/src/csharp#usage-macos-mono). - -## Defining the service - -Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/csharp/route_guide/RouteGuide/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/sharp/route_guide/RouteGuide/protos/route_guide.proto). - -To define a service, you specify a named `service` in your .proto file: - -```protobuf -service RouteGuide { - ... -} -``` - -Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: - -- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. -```protobuf - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} -``` - -- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. -```protobuf - // Obtains the Features available within the given Rectangle. Results are - // streamed rather than returned at once (e.g. in a response message with a - // repeated field), as the rectangle may cover a large area and contain a - // huge number of features. - rpc ListFeatures(Rectangle) returns (stream Feature) {} -``` - -- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. -```protobuf - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} -``` - -- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -```protobuf - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -``` - -Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -```protobuf -// 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; -} -``` - - -## Generating client and server code - -Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C# plugin. - -If you want to run this yourself, make sure you've installed protoc and gRPC C# plugin. The instructions vary based on your OS: -- For Windows, the `Grpc.Tools` NuGet package contains the binaries you will need to generate the code. -- For Linux, make sure you've [installed gRPC C Core using Linuxbrew](https://github.com/grpc/grpc/tree/master/src/csharp#usage-linux-mono) -- For MacOS, make sure you've [installed gRPC C Core using Homebrew](https://github.com/grpc/grpc/tree/master/src/csharp#usage-macos-mono) - -Once that's done, the following command can be used to generate the C# code. - -To generate the code on Windows, we use `protoc.exe` and `grpc_csharp_plugin.exe` binaries that are shipped with the `Grpc.Tools` NuGet package under the `tools` directory. -Normally you would need to add the `Grpc.Tools` package to the solution yourself, but in this tutorial it has been already done for you. Following command should be run from the `csharp/route_guide` directory: -``` -> packages\Grpc.Tools.0.5.1\tools\protoc -I RouteGuide/protos --csharp_out=RouteGuide --grpc_out=RouteGuide --plugin=protoc-gen-grpc=packages\Grpc.Tools.0.5.1\tools\grpc_csharp_plugin.exe RouteGuide/protos/route_guide.proto -``` - -On Linux/MacOS, we rely on `protoc` and `grpc_csharp_plugin` being installed by Linuxbrew/Homebrew. Run this command from the route_guide directory: -```shell -$ protoc -I RouteGuide/protos --csharp_out=RouteGuide --grpc_out=RouteGuide --plugin=protoc-gen-grpc=`which grpc_csharp_plugin` RouteGuide/protos/route_guide.proto -``` - -Running one of the previous commands regenerates the following files in the RouteGuide directory: -- `RouteGuide/RouteGuide.cs` defines a namespace `examples` - - This contains all the protocol buffer code to populate, serialize, and retrieve our request and response message types -- `RouteGuide/RouteGuideGrpc.cs`, provides stub and service classes - - an interface `RouteGuide.IRouteGuide` to inherit from when defining RouteGuide service implementations - - a class `RouteGuide.RouteGuideClient` that can be used to access remote RouteGuide instances - - - -## Creating the server - -First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). - -There are two parts to making our `RouteGuide` service do its job: -- Implementing the service interface generated from our service definition: doing the actual "work" of our service. -- Running a gRPC server to listen for requests from clients and return the service responses. - -You can find our example `RouteGuide` server in [grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/RouteGuideServer/RouteGuideServerImpl.cs). Let's take a closer look at how it works. - -### Implementing RouteGuide - -As you can see, our server has a `RouteGuideImpl` class that implements the generated `RouteGuide.IRouteGuide`: - -```csharp -// RouteGuideImpl provides an implementation of the RouteGuide service. -public class RouteGuideImpl : RouteGuide.IRouteGuide -``` - -#### Simple RPC - -`RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. - -```csharp - public Task GetFeature(Grpc.Core.ServerCallContext context, Point request) - { - return Task.FromResult(CheckFeature(request)); - } -``` - -The method is passed a context for the RPC (which is empty in the alpha release), the client's `Point` protocol buffer request, and returns a `Feature` protocol buffer. In the method we create the `Feature` with the appropriate information, and then return it. To allow asynchronous -implementation, the method returns `Task` rather than just `Feature`. You are free to perform your computations synchronously and return -the result once you've finished, just as we do in the example. - -#### Server-side streaming RPC - -Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature` protocol buffers to our client. - -```csharp - // in RouteGuideImpl - public async Task ListFeatures(Grpc.Core.ServerCallContext context, Rectangle request, - Grpc.Core.IServerStreamWriter responseStream) - { - int left = Math.Min(request.Lo.Longitude, request.Hi.Longitude); - int right = Math.Max(request.Lo.Longitude, request.Hi.Longitude); - int top = Math.Max(request.Lo.Latitude, request.Hi.Latitude); - int bottom = Math.Min(request.Lo.Latitude, request.Hi.Latitude); - - foreach (var feature in features) - { - if (!RouteGuideUtil.Exists(feature)) - { - continue; - } - - int lat = feature.Location.Latitude; - int lon = feature.Location.Longitude; - if (lon >= left && lon <= right && lat >= bottom && lat <= top) - { - await responseStream.WriteAsync(feature); - } - } - } -``` - -As you can see, here the request object is a `Rectangle` in which our client wants to find `Feature`s, but instead of returning a simple response we need to write responses to an asynchronous stream `IServerStreamWriter` using async method `WriteAsync`. - -#### Client-side streaming RPC - -Similarly, the client-side streaming method `RecordRoute` uses an [IAsyncEnumerator](https://github.com/Reactive-Extensions/Rx.NET/blob/master/Ix.NET/Source/System.Interactive.Async/IAsyncEnumerator.cs), to read the stream of requests using the async method `MoveNext` and the `Current` property. - -```csharp - public async Task RecordRoute(Grpc.Core.ServerCallContext context, - Grpc.Core.IAsyncStreamReader requestStream) - { - int pointCount = 0; - int featureCount = 0; - int distance = 0; - Point previous = null; - var stopwatch = new Stopwatch(); - stopwatch.Start(); - - while (await requestStream.MoveNext()) - { - var point = requestStream.Current; - pointCount++; - if (RouteGuideUtil.Exists(CheckFeature(point))) - { - featureCount++; - } - if (previous != null) - { - distance += (int) CalcDistance(previous, point); - } - previous = point; - } - - stopwatch.Stop(); - return RouteSummary.CreateBuilder().SetPointCount(pointCount) - .SetFeatureCount(featureCount).SetDistance(distance) - .SetElapsedTime((int) (stopwatch.ElapsedMilliseconds / 1000)).Build(); - } -``` - -#### Bidirectional streaming RPC - -Finally, let's look at our bidirectional streaming RPC `RouteChat`. - -```csharp - public async Task RouteChat(Grpc.Core.ServerCallContext context, - Grpc.Core.IAsyncStreamReader requestStream, Grpc.Core.IServerStreamWriter responseStream) - { - while (await requestStream.MoveNext()) - { - var note = requestStream.Current; - List notes = GetOrCreateNotes(note.Location); - - List prevNotes; - lock (notes) - { - prevNotes = new List(notes); - } - - foreach (var prevNote in prevNotes) - { - await responseStream.WriteAsync(prevNote); - } - - lock (notes) - { - notes.Add(note); - } - } - } -``` - -Here the method receives both `requestStream` and `responseStream` arguments. Reading the requests is done the same way as in the client-side streaming method `RecordRoute`. Writing the responses is done the same way as in the server-side streaming method `ListFeatures`. - -### Starting the server - -Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: - -```csharp -var features = RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile); -GrpcEnvironment.Initialize(); - -Server server = new Server(); -server.AddServiceDefinition(RouteGuide.BindService(new RouteGuideImpl(features))); -int port = server.AddListeningPort("localhost", 50052); -server.Start(); - -Console.WriteLine("RouteGuide server listening on port " + port); -Console.WriteLine("Press any key to stop the server..."); -Console.ReadKey(); - -server.ShutdownAsync().Wait(); -GrpcEnvironment.Shutdown(); -``` -As you can see, we build and start our server using `Grpc.Core.Server` class. To do this, we: - -1. Create an instance of `Grpc.Core.Server`. -1. Create an instance of our service implementation class `RouteGuideImpl`. -3. Register our service implementation with the server using the `AddServiceDefinition` method and the generated method `RouteGuide.BindService`. -2. Specify the address and port we want to use to listen for client requests using the `AddListeningPort` method. -4. Call `Start` on the server instance to start an RPC server for our service. - - -## Creating the client - -In this section, we'll look at creating a C# client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/csharp/route_guide/RouteGuideClient/Program.cs](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/RouteGuideClient/Program.cs). - -### Creating a stub - -To call service methods, we first need to create a *stub*. - -First, we need to create a gRPC client channel that will connect to gRPC server. Then, we use the `RouteGuide.NewStub` method of the `RouteGuide` class generated from our .proto. - -```csharp -GrpcEnvironment.Initialize(); - -using (Channel channel = new Channel("127.0.0.1:50052")) -{ - var client = RouteGuide.NewStub(channel); - - // YOUR CODE GOES HERE -} - -GrpcEnvironment.Shutdown(); -``` - -### Calling service methods - -Now let's look at how we call our service methods. gRPC C# provides asynchronous versions of each of the supported method types. For convenience, -gRPC C# also provides a synchronous method stub, but only for simple (single request/single response) RPCs. - -#### Simple RPC - -Calling the simple RPC `GetFeature` in a synchronous way is nearly as straightforward as calling a local method. - -```csharp -Point request = Point.CreateBuilder().SetLatitude(409146138).SetLongitude(-746188906).Build(); -Feature feature = client.GetFeature(request); -``` - -As you can see, we create and populate a request protocol buffer object (in our case `Point`), and call the desired method on the client object, passing it the request. If the RPC finishes with success, the response protocol buffer (in our case `Feature`) will be returned. Otherwise, an exception of type `RpcException` will be thrown, indicating the status code of the problem. - -Alternatively, if you are in async context, you can call an asynchronous version of the method (and use `await` keyword to await the result): -```csharp -Point request = Point.CreateBuilder().SetLatitude(409146138).SetLongitude(-746188906).Build(); -Feature feature = await client.GetFeatureAsync(request); -``` - -#### Streaming RPCs - -Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. The difference with respect to simple call is that the client methods return an instance of a call object, that provides access to request/response streams and/or asynchronous result (depending on the streaming type you are using). - -Here's where we call the server-side streaming method `ListFeatures`, which has property `ReponseStream` of type `IAsyncEnumerator` - -```csharp -using (var call = client.ListFeatures(request)) -{ - while (await call.ResponseStream.MoveNext()) - { - Feature feature = call.ResponseStream.Current; - Console.WriteLine("Received " + feature.ToString()); - } -} -``` - -The client-side streaming method `RecordRoute` is similar, except we use the property `RequestStream` to write the requests one by one using `WriteAsync` and eventually signal that no more request will be send using `CompleteAsync`. The method result can be obtained through the property -`Result`. -```csharp -using (var call = client.RecordRoute()) -{ - foreach (var point in points) - { - await call.RequestStream.WriteAsync(point); - } - await call.RequestStream.CompleteAsync(); - - RouteSummary summary = await call.Result; -} -``` - -Finally, let's look at our bidirectional streaming RPC `RouteChat`. In this case, we write the request to `RequestStream` and receive the responses from `ResponseStream`. As you can see from the example, the streams are independent of each other. - -```csharp - using (var call = client.RouteChat()) - { - var responseReaderTask = Task.Run(async () => - { - while (await call.ResponseStream.MoveNext()) - { - var note = call.ResponseStream.Current; - Console.WriteLine("Received " + note); - } - }); - - foreach (RouteNote request in requests) - { - await call.RequestStream.WriteAsync(request); - } - await call.RequestStream.CompleteAsync(); - await responseReaderTask; -} -``` - -## Try it out! - -Build client and server: - -Open the solution `grpc-common/csharp/route_guide/RouteGuide.sln` from Visual Studio (or Monodevelop on Linux) and hit "Build". - -Run the server, which will listen on port 50052: -``` -> cd RouteGuideServer/bin/Debug -> RouteGuideServer.exe -``` - -Run the client (in a different terminal): -``` -> cd RouteGuideClient/bin/Debug -> RouteGuideClient.exe -``` - -You can also run the server and client directly from Visual Studio. - -On Linux or Mac, use `mono RouteGuideServer.exe` and `mono RouteGuideClient.exe` to run the server and client. diff --git a/grpc-common/csharp/route_guide/RouteGuide.sln b/grpc-common/csharp/route_guide/RouteGuide.sln deleted file mode 100644 index 0b79fdc5ca..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuide.sln +++ /dev/null @@ -1,39 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.31101.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuide", "RouteGuide\RouteGuide.csproj", "{49954D9C-5F17-4662-96B2-73BE833DD81A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideClient", "RouteGuideClient\RouteGuideClient.csproj", "{D47BE663-4DE3-4206-B7A8-EA3FA066DADC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideServer", "RouteGuideServer\RouteGuideServer.csproj", "{4B7C7794-BE24-4477-ACE7-18259EB73D27}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2F6B184B-A576-4F21-AF2E-27E73D1FC96E}" - ProjectSection(SolutionItems) = preProject - .nuget\packages.config = .nuget\packages.config - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {49954D9C-5F17-4662-96B2-73BE833DD81A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {49954D9C-5F17-4662-96B2-73BE833DD81A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {49954D9C-5F17-4662-96B2-73BE833DD81A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {49954D9C-5F17-4662-96B2-73BE833DD81A}.Release|Any CPU.Build.0 = Release|Any CPU - {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Release|Any CPU.Build.0 = Release|Any CPU - {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4B7C7794-BE24-4477-ACE7-18259EB73D27}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/grpc-common/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs b/grpc-common/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs deleted file mode 100644 index 9c3441e42f..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("RouteGuide")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("RouteGuide")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("ef6b85bc-ac27-46de-8714-a658236cc6fb")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/grpc-common/csharp/route_guide/RouteGuide/RouteGuide.cs b/grpc-common/csharp/route_guide/RouteGuide/RouteGuide.cs deleted file mode 100644 index 80508bcd3f..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuide/RouteGuide.cs +++ /dev/null @@ -1,1873 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: route_guide.proto -#pragma warning disable 1591, 0612, 3021 -#region Designer generated code - -using pb = global::Google.ProtocolBuffers; -using pbc = global::Google.ProtocolBuffers.Collections; -using pbd = global::Google.ProtocolBuffers.Descriptors; -using scg = global::System.Collections.Generic; -namespace examples { - - namespace Proto { - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public static partial class RouteGuide { - - #region Extension registration - public static void RegisterAllExtensions(pb::ExtensionRegistry registry) { - } - #endregion - #region Static variables - internal static pbd::MessageDescriptor internal__static_examples_Point__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_Point__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_examples_Rectangle__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_Rectangle__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_examples_Feature__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_Feature__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_examples_RouteNote__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_RouteNote__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_examples_RouteSummary__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_examples_RouteSummary__FieldAccessorTable; - #endregion - #region Descriptor - public static pbd::FileDescriptor Descriptor { - get { return descriptor; } - } - private static pbd::FileDescriptor descriptor; - - static RouteGuide() { - byte[] descriptorData = global::System.Convert.FromBase64String( - string.Concat( - "ChFyb3V0ZV9ndWlkZS5wcm90bxIIZXhhbXBsZXMiLAoFUG9pbnQSEAoIbGF0", - "aXR1ZGUYASABKAUSEQoJbG9uZ2l0dWRlGAIgASgFIkUKCVJlY3RhbmdsZRIb", - "CgJsbxgBIAEoCzIPLmV4YW1wbGVzLlBvaW50EhsKAmhpGAIgASgLMg8uZXhh", - "bXBsZXMuUG9pbnQiOgoHRmVhdHVyZRIMCgRuYW1lGAEgASgJEiEKCGxvY2F0", - "aW9uGAIgASgLMg8uZXhhbXBsZXMuUG9pbnQiPwoJUm91dGVOb3RlEiEKCGxv", - "Y2F0aW9uGAEgASgLMg8uZXhhbXBsZXMuUG9pbnQSDwoHbWVzc2FnZRgCIAEo", - "CSJiCgxSb3V0ZVN1bW1hcnkSEwoLcG9pbnRfY291bnQYASABKAUSFQoNZmVh", - "dHVyZV9jb3VudBgCIAEoBRIQCghkaXN0YW5jZRgDIAEoBRIUCgxlbGFwc2Vk", - "X3RpbWUYBCABKAUy9QEKClJvdXRlR3VpZGUSMgoKR2V0RmVhdHVyZRIPLmV4", - "YW1wbGVzLlBvaW50GhEuZXhhbXBsZXMuRmVhdHVyZSIAEjoKDExpc3RGZWF0", - "dXJlcxITLmV4YW1wbGVzLlJlY3RhbmdsZRoRLmV4YW1wbGVzLkZlYXR1cmUi", - "ADABEjoKC1JlY29yZFJvdXRlEg8uZXhhbXBsZXMuUG9pbnQaFi5leGFtcGxl", - "cy5Sb3V0ZVN1bW1hcnkiACgBEjsKCVJvdXRlQ2hhdBITLmV4YW1wbGVzLlJv", - "dXRlTm90ZRoTLmV4YW1wbGVzLlJvdXRlTm90ZSIAKAEwAQ==")); - pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) { - descriptor = root; - internal__static_examples_Point__Descriptor = Descriptor.MessageTypes[0]; - internal__static_examples_Point__FieldAccessorTable = - new pb::FieldAccess.FieldAccessorTable(internal__static_examples_Point__Descriptor, - new string[] { "Latitude", "Longitude", }); - internal__static_examples_Rectangle__Descriptor = Descriptor.MessageTypes[1]; - internal__static_examples_Rectangle__FieldAccessorTable = - new pb::FieldAccess.FieldAccessorTable(internal__static_examples_Rectangle__Descriptor, - new string[] { "Lo", "Hi", }); - internal__static_examples_Feature__Descriptor = Descriptor.MessageTypes[2]; - internal__static_examples_Feature__FieldAccessorTable = - new pb::FieldAccess.FieldAccessorTable(internal__static_examples_Feature__Descriptor, - new string[] { "Name", "Location", }); - internal__static_examples_RouteNote__Descriptor = Descriptor.MessageTypes[3]; - internal__static_examples_RouteNote__FieldAccessorTable = - new pb::FieldAccess.FieldAccessorTable(internal__static_examples_RouteNote__Descriptor, - new string[] { "Location", "Message", }); - internal__static_examples_RouteSummary__Descriptor = Descriptor.MessageTypes[4]; - internal__static_examples_RouteSummary__FieldAccessorTable = - new pb::FieldAccess.FieldAccessorTable(internal__static_examples_RouteSummary__Descriptor, - new string[] { "PointCount", "FeatureCount", "Distance", "ElapsedTime", }); - pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance(); - RegisterAllExtensions(registry); - return registry; - }; - pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData, - new pbd::FileDescriptor[] { - }, assigner); - } - #endregion - - } - } - #region Messages - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Point : pb::GeneratedMessage { - private Point() { } - private static readonly Point defaultInstance = new Point().MakeReadOnly(); - private static readonly string[] _pointFieldNames = new string[] { "latitude", "longitude" }; - private static readonly uint[] _pointFieldTags = new uint[] { 8, 16 }; - public static Point DefaultInstance { - get { return defaultInstance; } - } - - public override Point DefaultInstanceForType { - get { return DefaultInstance; } - } - - protected override Point ThisMessage { - get { return this; } - } - - public static pbd::MessageDescriptor Descriptor { - get { return global::examples.Proto.RouteGuide.internal__static_examples_Point__Descriptor; } - } - - protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { - get { return global::examples.Proto.RouteGuide.internal__static_examples_Point__FieldAccessorTable; } - } - - public const int LatitudeFieldNumber = 1; - private bool hasLatitude; - private int latitude_; - public bool HasLatitude { - get { return hasLatitude; } - } - public int Latitude { - get { return latitude_; } - } - - public const int LongitudeFieldNumber = 2; - private bool hasLongitude; - private int longitude_; - public bool HasLongitude { - get { return hasLongitude; } - } - public int Longitude { - get { return longitude_; } - } - - public override bool IsInitialized { - get { - return true; - } - } - - public override void WriteTo(pb::ICodedOutputStream output) { - CalcSerializedSize(); - string[] field_names = _pointFieldNames; - if (hasLatitude) { - output.WriteInt32(1, field_names[0], Latitude); - } - if (hasLongitude) { - output.WriteInt32(2, field_names[1], Longitude); - } - UnknownFields.WriteTo(output); - } - - private int memoizedSerializedSize = -1; - public override int SerializedSize { - get { - int size = memoizedSerializedSize; - if (size != -1) return size; - return CalcSerializedSize(); - } - } - - private int CalcSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (hasLatitude) { - size += pb::CodedOutputStream.ComputeInt32Size(1, Latitude); - } - if (hasLongitude) { - size += pb::CodedOutputStream.ComputeInt32Size(2, Longitude); - } - size += UnknownFields.SerializedSize; - memoizedSerializedSize = size; - return size; - } - public static Point ParseFrom(pb::ByteString data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static Point ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static Point ParseFrom(byte[] data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static Point ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static Point ParseFrom(global::System.IO.Stream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static Point ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - public static Point ParseDelimitedFrom(global::System.IO.Stream input) { - return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); - } - public static Point ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); - } - public static Point ParseFrom(pb::ICodedInputStream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static Point ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - private Point MakeReadOnly() { - return this; - } - - public static Builder CreateBuilder() { return new Builder(); } - public override Builder ToBuilder() { return CreateBuilder(this); } - public override Builder CreateBuilderForType() { return new Builder(); } - public static Builder CreateBuilder(Point prototype) { - return new Builder(prototype); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Builder : pb::GeneratedBuilder { - protected override Builder ThisBuilder { - get { return this; } - } - public Builder() { - result = DefaultInstance; - resultIsReadOnly = true; - } - internal Builder(Point cloneFrom) { - result = cloneFrom; - resultIsReadOnly = true; - } - - private bool resultIsReadOnly; - private Point result; - - private Point PrepareBuilder() { - if (resultIsReadOnly) { - Point original = result; - result = new Point(); - resultIsReadOnly = false; - MergeFrom(original); - } - return result; - } - - public override bool IsInitialized { - get { return result.IsInitialized; } - } - - protected override Point MessageBeingBuilt { - get { return PrepareBuilder(); } - } - - public override Builder Clear() { - result = DefaultInstance; - resultIsReadOnly = true; - return this; - } - - public override Builder Clone() { - if (resultIsReadOnly) { - return new Builder(result); - } else { - return new Builder().MergeFrom(result); - } - } - - public override pbd::MessageDescriptor DescriptorForType { - get { return global::examples.Point.Descriptor; } - } - - public override Point DefaultInstanceForType { - get { return global::examples.Point.DefaultInstance; } - } - - public override Point BuildPartial() { - if (resultIsReadOnly) { - return result; - } - resultIsReadOnly = true; - return result.MakeReadOnly(); - } - - public override Builder MergeFrom(pb::IMessage other) { - if (other is Point) { - return MergeFrom((Point) other); - } else { - base.MergeFrom(other); - return this; - } - } - - public override Builder MergeFrom(Point other) { - if (other == global::examples.Point.DefaultInstance) return this; - PrepareBuilder(); - if (other.HasLatitude) { - Latitude = other.Latitude; - } - if (other.HasLongitude) { - Longitude = other.Longitude; - } - this.MergeUnknownFields(other.UnknownFields); - return this; - } - - public override Builder MergeFrom(pb::ICodedInputStream input) { - return MergeFrom(input, pb::ExtensionRegistry.Empty); - } - - public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - PrepareBuilder(); - pb::UnknownFieldSet.Builder unknownFields = null; - uint tag; - string field_name; - while (input.ReadTag(out tag, out field_name)) { - if(tag == 0 && field_name != null) { - int field_ordinal = global::System.Array.BinarySearch(_pointFieldNames, field_name, global::System.StringComparer.Ordinal); - if(field_ordinal >= 0) - tag = _pointFieldTags[field_ordinal]; - else { - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - continue; - } - } - switch (tag) { - case 0: { - throw pb::InvalidProtocolBufferException.InvalidTag(); - } - default: { - if (pb::WireFormat.IsEndGroupTag(tag)) { - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - break; - } - case 8: { - result.hasLatitude = input.ReadInt32(ref result.latitude_); - break; - } - case 16: { - result.hasLongitude = input.ReadInt32(ref result.longitude_); - break; - } - } - } - - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - - - public bool HasLatitude { - get { return result.hasLatitude; } - } - public int Latitude { - get { return result.Latitude; } - set { SetLatitude(value); } - } - public Builder SetLatitude(int value) { - PrepareBuilder(); - result.hasLatitude = true; - result.latitude_ = value; - return this; - } - public Builder ClearLatitude() { - PrepareBuilder(); - result.hasLatitude = false; - result.latitude_ = 0; - return this; - } - - public bool HasLongitude { - get { return result.hasLongitude; } - } - public int Longitude { - get { return result.Longitude; } - set { SetLongitude(value); } - } - public Builder SetLongitude(int value) { - PrepareBuilder(); - result.hasLongitude = true; - result.longitude_ = value; - return this; - } - public Builder ClearLongitude() { - PrepareBuilder(); - result.hasLongitude = false; - result.longitude_ = 0; - return this; - } - } - static Point() { - object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Rectangle : pb::GeneratedMessage { - private Rectangle() { } - private static readonly Rectangle defaultInstance = new Rectangle().MakeReadOnly(); - private static readonly string[] _rectangleFieldNames = new string[] { "hi", "lo" }; - private static readonly uint[] _rectangleFieldTags = new uint[] { 18, 10 }; - public static Rectangle DefaultInstance { - get { return defaultInstance; } - } - - public override Rectangle DefaultInstanceForType { - get { return DefaultInstance; } - } - - protected override Rectangle ThisMessage { - get { return this; } - } - - public static pbd::MessageDescriptor Descriptor { - get { return global::examples.Proto.RouteGuide.internal__static_examples_Rectangle__Descriptor; } - } - - protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { - get { return global::examples.Proto.RouteGuide.internal__static_examples_Rectangle__FieldAccessorTable; } - } - - public const int LoFieldNumber = 1; - private bool hasLo; - private global::examples.Point lo_; - public bool HasLo { - get { return hasLo; } - } - public global::examples.Point Lo { - get { return lo_ ?? global::examples.Point.DefaultInstance; } - } - - public const int HiFieldNumber = 2; - private bool hasHi; - private global::examples.Point hi_; - public bool HasHi { - get { return hasHi; } - } - public global::examples.Point Hi { - get { return hi_ ?? global::examples.Point.DefaultInstance; } - } - - public override bool IsInitialized { - get { - return true; - } - } - - public override void WriteTo(pb::ICodedOutputStream output) { - CalcSerializedSize(); - string[] field_names = _rectangleFieldNames; - if (hasLo) { - output.WriteMessage(1, field_names[1], Lo); - } - if (hasHi) { - output.WriteMessage(2, field_names[0], Hi); - } - UnknownFields.WriteTo(output); - } - - private int memoizedSerializedSize = -1; - public override int SerializedSize { - get { - int size = memoizedSerializedSize; - if (size != -1) return size; - return CalcSerializedSize(); - } - } - - private int CalcSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (hasLo) { - size += pb::CodedOutputStream.ComputeMessageSize(1, Lo); - } - if (hasHi) { - size += pb::CodedOutputStream.ComputeMessageSize(2, Hi); - } - size += UnknownFields.SerializedSize; - memoizedSerializedSize = size; - return size; - } - public static Rectangle ParseFrom(pb::ByteString data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static Rectangle ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static Rectangle ParseFrom(byte[] data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static Rectangle ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static Rectangle ParseFrom(global::System.IO.Stream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static Rectangle ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - public static Rectangle ParseDelimitedFrom(global::System.IO.Stream input) { - return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); - } - public static Rectangle ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); - } - public static Rectangle ParseFrom(pb::ICodedInputStream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static Rectangle ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - private Rectangle MakeReadOnly() { - return this; - } - - public static Builder CreateBuilder() { return new Builder(); } - public override Builder ToBuilder() { return CreateBuilder(this); } - public override Builder CreateBuilderForType() { return new Builder(); } - public static Builder CreateBuilder(Rectangle prototype) { - return new Builder(prototype); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Builder : pb::GeneratedBuilder { - protected override Builder ThisBuilder { - get { return this; } - } - public Builder() { - result = DefaultInstance; - resultIsReadOnly = true; - } - internal Builder(Rectangle cloneFrom) { - result = cloneFrom; - resultIsReadOnly = true; - } - - private bool resultIsReadOnly; - private Rectangle result; - - private Rectangle PrepareBuilder() { - if (resultIsReadOnly) { - Rectangle original = result; - result = new Rectangle(); - resultIsReadOnly = false; - MergeFrom(original); - } - return result; - } - - public override bool IsInitialized { - get { return result.IsInitialized; } - } - - protected override Rectangle MessageBeingBuilt { - get { return PrepareBuilder(); } - } - - public override Builder Clear() { - result = DefaultInstance; - resultIsReadOnly = true; - return this; - } - - public override Builder Clone() { - if (resultIsReadOnly) { - return new Builder(result); - } else { - return new Builder().MergeFrom(result); - } - } - - public override pbd::MessageDescriptor DescriptorForType { - get { return global::examples.Rectangle.Descriptor; } - } - - public override Rectangle DefaultInstanceForType { - get { return global::examples.Rectangle.DefaultInstance; } - } - - public override Rectangle BuildPartial() { - if (resultIsReadOnly) { - return result; - } - resultIsReadOnly = true; - return result.MakeReadOnly(); - } - - public override Builder MergeFrom(pb::IMessage other) { - if (other is Rectangle) { - return MergeFrom((Rectangle) other); - } else { - base.MergeFrom(other); - return this; - } - } - - public override Builder MergeFrom(Rectangle other) { - if (other == global::examples.Rectangle.DefaultInstance) return this; - PrepareBuilder(); - if (other.HasLo) { - MergeLo(other.Lo); - } - if (other.HasHi) { - MergeHi(other.Hi); - } - this.MergeUnknownFields(other.UnknownFields); - return this; - } - - public override Builder MergeFrom(pb::ICodedInputStream input) { - return MergeFrom(input, pb::ExtensionRegistry.Empty); - } - - public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - PrepareBuilder(); - pb::UnknownFieldSet.Builder unknownFields = null; - uint tag; - string field_name; - while (input.ReadTag(out tag, out field_name)) { - if(tag == 0 && field_name != null) { - int field_ordinal = global::System.Array.BinarySearch(_rectangleFieldNames, field_name, global::System.StringComparer.Ordinal); - if(field_ordinal >= 0) - tag = _rectangleFieldTags[field_ordinal]; - else { - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - continue; - } - } - switch (tag) { - case 0: { - throw pb::InvalidProtocolBufferException.InvalidTag(); - } - default: { - if (pb::WireFormat.IsEndGroupTag(tag)) { - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - break; - } - case 10: { - global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); - if (result.hasLo) { - subBuilder.MergeFrom(Lo); - } - input.ReadMessage(subBuilder, extensionRegistry); - Lo = subBuilder.BuildPartial(); - break; - } - case 18: { - global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); - if (result.hasHi) { - subBuilder.MergeFrom(Hi); - } - input.ReadMessage(subBuilder, extensionRegistry); - Hi = subBuilder.BuildPartial(); - break; - } - } - } - - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - - - public bool HasLo { - get { return result.hasLo; } - } - public global::examples.Point Lo { - get { return result.Lo; } - set { SetLo(value); } - } - public Builder SetLo(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasLo = true; - result.lo_ = value; - return this; - } - public Builder SetLo(global::examples.Point.Builder builderForValue) { - pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); - PrepareBuilder(); - result.hasLo = true; - result.lo_ = builderForValue.Build(); - return this; - } - public Builder MergeLo(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - if (result.hasLo && - result.lo_ != global::examples.Point.DefaultInstance) { - result.lo_ = global::examples.Point.CreateBuilder(result.lo_).MergeFrom(value).BuildPartial(); - } else { - result.lo_ = value; - } - result.hasLo = true; - return this; - } - public Builder ClearLo() { - PrepareBuilder(); - result.hasLo = false; - result.lo_ = null; - return this; - } - - public bool HasHi { - get { return result.hasHi; } - } - public global::examples.Point Hi { - get { return result.Hi; } - set { SetHi(value); } - } - public Builder SetHi(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasHi = true; - result.hi_ = value; - return this; - } - public Builder SetHi(global::examples.Point.Builder builderForValue) { - pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); - PrepareBuilder(); - result.hasHi = true; - result.hi_ = builderForValue.Build(); - return this; - } - public Builder MergeHi(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - if (result.hasHi && - result.hi_ != global::examples.Point.DefaultInstance) { - result.hi_ = global::examples.Point.CreateBuilder(result.hi_).MergeFrom(value).BuildPartial(); - } else { - result.hi_ = value; - } - result.hasHi = true; - return this; - } - public Builder ClearHi() { - PrepareBuilder(); - result.hasHi = false; - result.hi_ = null; - return this; - } - } - static Rectangle() { - object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Feature : pb::GeneratedMessage { - private Feature() { } - private static readonly Feature defaultInstance = new Feature().MakeReadOnly(); - private static readonly string[] _featureFieldNames = new string[] { "location", "name" }; - private static readonly uint[] _featureFieldTags = new uint[] { 18, 10 }; - public static Feature DefaultInstance { - get { return defaultInstance; } - } - - public override Feature DefaultInstanceForType { - get { return DefaultInstance; } - } - - protected override Feature ThisMessage { - get { return this; } - } - - public static pbd::MessageDescriptor Descriptor { - get { return global::examples.Proto.RouteGuide.internal__static_examples_Feature__Descriptor; } - } - - protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { - get { return global::examples.Proto.RouteGuide.internal__static_examples_Feature__FieldAccessorTable; } - } - - public const int NameFieldNumber = 1; - private bool hasName; - private string name_ = ""; - public bool HasName { - get { return hasName; } - } - public string Name { - get { return name_; } - } - - public const int LocationFieldNumber = 2; - private bool hasLocation; - private global::examples.Point location_; - public bool HasLocation { - get { return hasLocation; } - } - public global::examples.Point Location { - get { return location_ ?? global::examples.Point.DefaultInstance; } - } - - public override bool IsInitialized { - get { - return true; - } - } - - public override void WriteTo(pb::ICodedOutputStream output) { - CalcSerializedSize(); - string[] field_names = _featureFieldNames; - if (hasName) { - output.WriteString(1, field_names[1], Name); - } - if (hasLocation) { - output.WriteMessage(2, field_names[0], Location); - } - UnknownFields.WriteTo(output); - } - - private int memoizedSerializedSize = -1; - public override int SerializedSize { - get { - int size = memoizedSerializedSize; - if (size != -1) return size; - return CalcSerializedSize(); - } - } - - private int CalcSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (hasName) { - size += pb::CodedOutputStream.ComputeStringSize(1, Name); - } - if (hasLocation) { - size += pb::CodedOutputStream.ComputeMessageSize(2, Location); - } - size += UnknownFields.SerializedSize; - memoizedSerializedSize = size; - return size; - } - public static Feature ParseFrom(pb::ByteString data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static Feature ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static Feature ParseFrom(byte[] data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static Feature ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static Feature ParseFrom(global::System.IO.Stream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static Feature ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - public static Feature ParseDelimitedFrom(global::System.IO.Stream input) { - return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); - } - public static Feature ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); - } - public static Feature ParseFrom(pb::ICodedInputStream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static Feature ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - private Feature MakeReadOnly() { - return this; - } - - public static Builder CreateBuilder() { return new Builder(); } - public override Builder ToBuilder() { return CreateBuilder(this); } - public override Builder CreateBuilderForType() { return new Builder(); } - public static Builder CreateBuilder(Feature prototype) { - return new Builder(prototype); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Builder : pb::GeneratedBuilder { - protected override Builder ThisBuilder { - get { return this; } - } - public Builder() { - result = DefaultInstance; - resultIsReadOnly = true; - } - internal Builder(Feature cloneFrom) { - result = cloneFrom; - resultIsReadOnly = true; - } - - private bool resultIsReadOnly; - private Feature result; - - private Feature PrepareBuilder() { - if (resultIsReadOnly) { - Feature original = result; - result = new Feature(); - resultIsReadOnly = false; - MergeFrom(original); - } - return result; - } - - public override bool IsInitialized { - get { return result.IsInitialized; } - } - - protected override Feature MessageBeingBuilt { - get { return PrepareBuilder(); } - } - - public override Builder Clear() { - result = DefaultInstance; - resultIsReadOnly = true; - return this; - } - - public override Builder Clone() { - if (resultIsReadOnly) { - return new Builder(result); - } else { - return new Builder().MergeFrom(result); - } - } - - public override pbd::MessageDescriptor DescriptorForType { - get { return global::examples.Feature.Descriptor; } - } - - public override Feature DefaultInstanceForType { - get { return global::examples.Feature.DefaultInstance; } - } - - public override Feature BuildPartial() { - if (resultIsReadOnly) { - return result; - } - resultIsReadOnly = true; - return result.MakeReadOnly(); - } - - public override Builder MergeFrom(pb::IMessage other) { - if (other is Feature) { - return MergeFrom((Feature) other); - } else { - base.MergeFrom(other); - return this; - } - } - - public override Builder MergeFrom(Feature other) { - if (other == global::examples.Feature.DefaultInstance) return this; - PrepareBuilder(); - if (other.HasName) { - Name = other.Name; - } - if (other.HasLocation) { - MergeLocation(other.Location); - } - this.MergeUnknownFields(other.UnknownFields); - return this; - } - - public override Builder MergeFrom(pb::ICodedInputStream input) { - return MergeFrom(input, pb::ExtensionRegistry.Empty); - } - - public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - PrepareBuilder(); - pb::UnknownFieldSet.Builder unknownFields = null; - uint tag; - string field_name; - while (input.ReadTag(out tag, out field_name)) { - if(tag == 0 && field_name != null) { - int field_ordinal = global::System.Array.BinarySearch(_featureFieldNames, field_name, global::System.StringComparer.Ordinal); - if(field_ordinal >= 0) - tag = _featureFieldTags[field_ordinal]; - else { - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - continue; - } - } - switch (tag) { - case 0: { - throw pb::InvalidProtocolBufferException.InvalidTag(); - } - default: { - if (pb::WireFormat.IsEndGroupTag(tag)) { - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - break; - } - case 10: { - result.hasName = input.ReadString(ref result.name_); - break; - } - case 18: { - global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); - if (result.hasLocation) { - subBuilder.MergeFrom(Location); - } - input.ReadMessage(subBuilder, extensionRegistry); - Location = subBuilder.BuildPartial(); - break; - } - } - } - - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - - - public bool HasName { - get { return result.hasName; } - } - public string Name { - get { return result.Name; } - set { SetName(value); } - } - public Builder SetName(string value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasName = true; - result.name_ = value; - return this; - } - public Builder ClearName() { - PrepareBuilder(); - result.hasName = false; - result.name_ = ""; - return this; - } - - public bool HasLocation { - get { return result.hasLocation; } - } - public global::examples.Point Location { - get { return result.Location; } - set { SetLocation(value); } - } - public Builder SetLocation(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasLocation = true; - result.location_ = value; - return this; - } - public Builder SetLocation(global::examples.Point.Builder builderForValue) { - pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); - PrepareBuilder(); - result.hasLocation = true; - result.location_ = builderForValue.Build(); - return this; - } - public Builder MergeLocation(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - if (result.hasLocation && - result.location_ != global::examples.Point.DefaultInstance) { - result.location_ = global::examples.Point.CreateBuilder(result.location_).MergeFrom(value).BuildPartial(); - } else { - result.location_ = value; - } - result.hasLocation = true; - return this; - } - public Builder ClearLocation() { - PrepareBuilder(); - result.hasLocation = false; - result.location_ = null; - return this; - } - } - static Feature() { - object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class RouteNote : pb::GeneratedMessage { - private RouteNote() { } - private static readonly RouteNote defaultInstance = new RouteNote().MakeReadOnly(); - private static readonly string[] _routeNoteFieldNames = new string[] { "location", "message" }; - private static readonly uint[] _routeNoteFieldTags = new uint[] { 10, 18 }; - public static RouteNote DefaultInstance { - get { return defaultInstance; } - } - - public override RouteNote DefaultInstanceForType { - get { return DefaultInstance; } - } - - protected override RouteNote ThisMessage { - get { return this; } - } - - public static pbd::MessageDescriptor Descriptor { - get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteNote__Descriptor; } - } - - protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { - get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteNote__FieldAccessorTable; } - } - - public const int LocationFieldNumber = 1; - private bool hasLocation; - private global::examples.Point location_; - public bool HasLocation { - get { return hasLocation; } - } - public global::examples.Point Location { - get { return location_ ?? global::examples.Point.DefaultInstance; } - } - - public const int MessageFieldNumber = 2; - private bool hasMessage; - private string message_ = ""; - public bool HasMessage { - get { return hasMessage; } - } - public string Message { - get { return message_; } - } - - public override bool IsInitialized { - get { - return true; - } - } - - public override void WriteTo(pb::ICodedOutputStream output) { - CalcSerializedSize(); - string[] field_names = _routeNoteFieldNames; - if (hasLocation) { - output.WriteMessage(1, field_names[0], Location); - } - if (hasMessage) { - output.WriteString(2, field_names[1], Message); - } - UnknownFields.WriteTo(output); - } - - private int memoizedSerializedSize = -1; - public override int SerializedSize { - get { - int size = memoizedSerializedSize; - if (size != -1) return size; - return CalcSerializedSize(); - } - } - - private int CalcSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (hasLocation) { - size += pb::CodedOutputStream.ComputeMessageSize(1, Location); - } - if (hasMessage) { - size += pb::CodedOutputStream.ComputeStringSize(2, Message); - } - size += UnknownFields.SerializedSize; - memoizedSerializedSize = size; - return size; - } - public static RouteNote ParseFrom(pb::ByteString data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static RouteNote ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static RouteNote ParseFrom(byte[] data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static RouteNote ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static RouteNote ParseFrom(global::System.IO.Stream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static RouteNote ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - public static RouteNote ParseDelimitedFrom(global::System.IO.Stream input) { - return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); - } - public static RouteNote ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); - } - public static RouteNote ParseFrom(pb::ICodedInputStream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static RouteNote ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - private RouteNote MakeReadOnly() { - return this; - } - - public static Builder CreateBuilder() { return new Builder(); } - public override Builder ToBuilder() { return CreateBuilder(this); } - public override Builder CreateBuilderForType() { return new Builder(); } - public static Builder CreateBuilder(RouteNote prototype) { - return new Builder(prototype); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Builder : pb::GeneratedBuilder { - protected override Builder ThisBuilder { - get { return this; } - } - public Builder() { - result = DefaultInstance; - resultIsReadOnly = true; - } - internal Builder(RouteNote cloneFrom) { - result = cloneFrom; - resultIsReadOnly = true; - } - - private bool resultIsReadOnly; - private RouteNote result; - - private RouteNote PrepareBuilder() { - if (resultIsReadOnly) { - RouteNote original = result; - result = new RouteNote(); - resultIsReadOnly = false; - MergeFrom(original); - } - return result; - } - - public override bool IsInitialized { - get { return result.IsInitialized; } - } - - protected override RouteNote MessageBeingBuilt { - get { return PrepareBuilder(); } - } - - public override Builder Clear() { - result = DefaultInstance; - resultIsReadOnly = true; - return this; - } - - public override Builder Clone() { - if (resultIsReadOnly) { - return new Builder(result); - } else { - return new Builder().MergeFrom(result); - } - } - - public override pbd::MessageDescriptor DescriptorForType { - get { return global::examples.RouteNote.Descriptor; } - } - - public override RouteNote DefaultInstanceForType { - get { return global::examples.RouteNote.DefaultInstance; } - } - - public override RouteNote BuildPartial() { - if (resultIsReadOnly) { - return result; - } - resultIsReadOnly = true; - return result.MakeReadOnly(); - } - - public override Builder MergeFrom(pb::IMessage other) { - if (other is RouteNote) { - return MergeFrom((RouteNote) other); - } else { - base.MergeFrom(other); - return this; - } - } - - public override Builder MergeFrom(RouteNote other) { - if (other == global::examples.RouteNote.DefaultInstance) return this; - PrepareBuilder(); - if (other.HasLocation) { - MergeLocation(other.Location); - } - if (other.HasMessage) { - Message = other.Message; - } - this.MergeUnknownFields(other.UnknownFields); - return this; - } - - public override Builder MergeFrom(pb::ICodedInputStream input) { - return MergeFrom(input, pb::ExtensionRegistry.Empty); - } - - public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - PrepareBuilder(); - pb::UnknownFieldSet.Builder unknownFields = null; - uint tag; - string field_name; - while (input.ReadTag(out tag, out field_name)) { - if(tag == 0 && field_name != null) { - int field_ordinal = global::System.Array.BinarySearch(_routeNoteFieldNames, field_name, global::System.StringComparer.Ordinal); - if(field_ordinal >= 0) - tag = _routeNoteFieldTags[field_ordinal]; - else { - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - continue; - } - } - switch (tag) { - case 0: { - throw pb::InvalidProtocolBufferException.InvalidTag(); - } - default: { - if (pb::WireFormat.IsEndGroupTag(tag)) { - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - break; - } - case 10: { - global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder(); - if (result.hasLocation) { - subBuilder.MergeFrom(Location); - } - input.ReadMessage(subBuilder, extensionRegistry); - Location = subBuilder.BuildPartial(); - break; - } - case 18: { - result.hasMessage = input.ReadString(ref result.message_); - break; - } - } - } - - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - - - public bool HasLocation { - get { return result.hasLocation; } - } - public global::examples.Point Location { - get { return result.Location; } - set { SetLocation(value); } - } - public Builder SetLocation(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasLocation = true; - result.location_ = value; - return this; - } - public Builder SetLocation(global::examples.Point.Builder builderForValue) { - pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue"); - PrepareBuilder(); - result.hasLocation = true; - result.location_ = builderForValue.Build(); - return this; - } - public Builder MergeLocation(global::examples.Point value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - if (result.hasLocation && - result.location_ != global::examples.Point.DefaultInstance) { - result.location_ = global::examples.Point.CreateBuilder(result.location_).MergeFrom(value).BuildPartial(); - } else { - result.location_ = value; - } - result.hasLocation = true; - return this; - } - public Builder ClearLocation() { - PrepareBuilder(); - result.hasLocation = false; - result.location_ = null; - return this; - } - - public bool HasMessage { - get { return result.hasMessage; } - } - public string Message { - get { return result.Message; } - set { SetMessage(value); } - } - public Builder SetMessage(string value) { - pb::ThrowHelper.ThrowIfNull(value, "value"); - PrepareBuilder(); - result.hasMessage = true; - result.message_ = value; - return this; - } - public Builder ClearMessage() { - PrepareBuilder(); - result.hasMessage = false; - result.message_ = ""; - return this; - } - } - static RouteNote() { - object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class RouteSummary : pb::GeneratedMessage { - private RouteSummary() { } - private static readonly RouteSummary defaultInstance = new RouteSummary().MakeReadOnly(); - private static readonly string[] _routeSummaryFieldNames = new string[] { "distance", "elapsed_time", "feature_count", "point_count" }; - private static readonly uint[] _routeSummaryFieldTags = new uint[] { 24, 32, 16, 8 }; - public static RouteSummary DefaultInstance { - get { return defaultInstance; } - } - - public override RouteSummary DefaultInstanceForType { - get { return DefaultInstance; } - } - - protected override RouteSummary ThisMessage { - get { return this; } - } - - public static pbd::MessageDescriptor Descriptor { - get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteSummary__Descriptor; } - } - - protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { - get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteSummary__FieldAccessorTable; } - } - - public const int PointCountFieldNumber = 1; - private bool hasPointCount; - private int pointCount_; - public bool HasPointCount { - get { return hasPointCount; } - } - public int PointCount { - get { return pointCount_; } - } - - public const int FeatureCountFieldNumber = 2; - private bool hasFeatureCount; - private int featureCount_; - public bool HasFeatureCount { - get { return hasFeatureCount; } - } - public int FeatureCount { - get { return featureCount_; } - } - - public const int DistanceFieldNumber = 3; - private bool hasDistance; - private int distance_; - public bool HasDistance { - get { return hasDistance; } - } - public int Distance { - get { return distance_; } - } - - public const int ElapsedTimeFieldNumber = 4; - private bool hasElapsedTime; - private int elapsedTime_; - public bool HasElapsedTime { - get { return hasElapsedTime; } - } - public int ElapsedTime { - get { return elapsedTime_; } - } - - public override bool IsInitialized { - get { - return true; - } - } - - public override void WriteTo(pb::ICodedOutputStream output) { - CalcSerializedSize(); - string[] field_names = _routeSummaryFieldNames; - if (hasPointCount) { - output.WriteInt32(1, field_names[3], PointCount); - } - if (hasFeatureCount) { - output.WriteInt32(2, field_names[2], FeatureCount); - } - if (hasDistance) { - output.WriteInt32(3, field_names[0], Distance); - } - if (hasElapsedTime) { - output.WriteInt32(4, field_names[1], ElapsedTime); - } - UnknownFields.WriteTo(output); - } - - private int memoizedSerializedSize = -1; - public override int SerializedSize { - get { - int size = memoizedSerializedSize; - if (size != -1) return size; - return CalcSerializedSize(); - } - } - - private int CalcSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (hasPointCount) { - size += pb::CodedOutputStream.ComputeInt32Size(1, PointCount); - } - if (hasFeatureCount) { - size += pb::CodedOutputStream.ComputeInt32Size(2, FeatureCount); - } - if (hasDistance) { - size += pb::CodedOutputStream.ComputeInt32Size(3, Distance); - } - if (hasElapsedTime) { - size += pb::CodedOutputStream.ComputeInt32Size(4, ElapsedTime); - } - size += UnknownFields.SerializedSize; - memoizedSerializedSize = size; - return size; - } - public static RouteSummary ParseFrom(pb::ByteString data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static RouteSummary ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static RouteSummary ParseFrom(byte[] data) { - return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); - } - public static RouteSummary ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); - } - public static RouteSummary ParseFrom(global::System.IO.Stream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static RouteSummary ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - public static RouteSummary ParseDelimitedFrom(global::System.IO.Stream input) { - return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); - } - public static RouteSummary ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { - return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); - } - public static RouteSummary ParseFrom(pb::ICodedInputStream input) { - return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); - } - public static RouteSummary ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); - } - private RouteSummary MakeReadOnly() { - return this; - } - - public static Builder CreateBuilder() { return new Builder(); } - public override Builder ToBuilder() { return CreateBuilder(this); } - public override Builder CreateBuilderForType() { return new Builder(); } - public static Builder CreateBuilder(RouteSummary prototype) { - return new Builder(prototype); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Builder : pb::GeneratedBuilder { - protected override Builder ThisBuilder { - get { return this; } - } - public Builder() { - result = DefaultInstance; - resultIsReadOnly = true; - } - internal Builder(RouteSummary cloneFrom) { - result = cloneFrom; - resultIsReadOnly = true; - } - - private bool resultIsReadOnly; - private RouteSummary result; - - private RouteSummary PrepareBuilder() { - if (resultIsReadOnly) { - RouteSummary original = result; - result = new RouteSummary(); - resultIsReadOnly = false; - MergeFrom(original); - } - return result; - } - - public override bool IsInitialized { - get { return result.IsInitialized; } - } - - protected override RouteSummary MessageBeingBuilt { - get { return PrepareBuilder(); } - } - - public override Builder Clear() { - result = DefaultInstance; - resultIsReadOnly = true; - return this; - } - - public override Builder Clone() { - if (resultIsReadOnly) { - return new Builder(result); - } else { - return new Builder().MergeFrom(result); - } - } - - public override pbd::MessageDescriptor DescriptorForType { - get { return global::examples.RouteSummary.Descriptor; } - } - - public override RouteSummary DefaultInstanceForType { - get { return global::examples.RouteSummary.DefaultInstance; } - } - - public override RouteSummary BuildPartial() { - if (resultIsReadOnly) { - return result; - } - resultIsReadOnly = true; - return result.MakeReadOnly(); - } - - public override Builder MergeFrom(pb::IMessage other) { - if (other is RouteSummary) { - return MergeFrom((RouteSummary) other); - } else { - base.MergeFrom(other); - return this; - } - } - - public override Builder MergeFrom(RouteSummary other) { - if (other == global::examples.RouteSummary.DefaultInstance) return this; - PrepareBuilder(); - if (other.HasPointCount) { - PointCount = other.PointCount; - } - if (other.HasFeatureCount) { - FeatureCount = other.FeatureCount; - } - if (other.HasDistance) { - Distance = other.Distance; - } - if (other.HasElapsedTime) { - ElapsedTime = other.ElapsedTime; - } - this.MergeUnknownFields(other.UnknownFields); - return this; - } - - public override Builder MergeFrom(pb::ICodedInputStream input) { - return MergeFrom(input, pb::ExtensionRegistry.Empty); - } - - public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { - PrepareBuilder(); - pb::UnknownFieldSet.Builder unknownFields = null; - uint tag; - string field_name; - while (input.ReadTag(out tag, out field_name)) { - if(tag == 0 && field_name != null) { - int field_ordinal = global::System.Array.BinarySearch(_routeSummaryFieldNames, field_name, global::System.StringComparer.Ordinal); - if(field_ordinal >= 0) - tag = _routeSummaryFieldTags[field_ordinal]; - else { - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - continue; - } - } - switch (tag) { - case 0: { - throw pb::InvalidProtocolBufferException.InvalidTag(); - } - default: { - if (pb::WireFormat.IsEndGroupTag(tag)) { - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - if (unknownFields == null) { - unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); - } - ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); - break; - } - case 8: { - result.hasPointCount = input.ReadInt32(ref result.pointCount_); - break; - } - case 16: { - result.hasFeatureCount = input.ReadInt32(ref result.featureCount_); - break; - } - case 24: { - result.hasDistance = input.ReadInt32(ref result.distance_); - break; - } - case 32: { - result.hasElapsedTime = input.ReadInt32(ref result.elapsedTime_); - break; - } - } - } - - if (unknownFields != null) { - this.UnknownFields = unknownFields.Build(); - } - return this; - } - - - public bool HasPointCount { - get { return result.hasPointCount; } - } - public int PointCount { - get { return result.PointCount; } - set { SetPointCount(value); } - } - public Builder SetPointCount(int value) { - PrepareBuilder(); - result.hasPointCount = true; - result.pointCount_ = value; - return this; - } - public Builder ClearPointCount() { - PrepareBuilder(); - result.hasPointCount = false; - result.pointCount_ = 0; - return this; - } - - public bool HasFeatureCount { - get { return result.hasFeatureCount; } - } - public int FeatureCount { - get { return result.FeatureCount; } - set { SetFeatureCount(value); } - } - public Builder SetFeatureCount(int value) { - PrepareBuilder(); - result.hasFeatureCount = true; - result.featureCount_ = value; - return this; - } - public Builder ClearFeatureCount() { - PrepareBuilder(); - result.hasFeatureCount = false; - result.featureCount_ = 0; - return this; - } - - public bool HasDistance { - get { return result.hasDistance; } - } - public int Distance { - get { return result.Distance; } - set { SetDistance(value); } - } - public Builder SetDistance(int value) { - PrepareBuilder(); - result.hasDistance = true; - result.distance_ = value; - return this; - } - public Builder ClearDistance() { - PrepareBuilder(); - result.hasDistance = false; - result.distance_ = 0; - return this; - } - - public bool HasElapsedTime { - get { return result.hasElapsedTime; } - } - public int ElapsedTime { - get { return result.ElapsedTime; } - set { SetElapsedTime(value); } - } - public Builder SetElapsedTime(int value) { - PrepareBuilder(); - result.hasElapsedTime = true; - result.elapsedTime_ = value; - return this; - } - public Builder ClearElapsedTime() { - PrepareBuilder(); - result.hasElapsedTime = false; - result.elapsedTime_ = 0; - return this; - } - } - static RouteSummary() { - object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null); - } - } - - #endregion - -} - -#endregion Designer generated code diff --git a/grpc-common/csharp/route_guide/RouteGuide/RouteGuide.csproj b/grpc-common/csharp/route_guide/RouteGuide/RouteGuide.csproj deleted file mode 100644 index 8358974aac..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuide/RouteGuide.csproj +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - Debug - AnyCPU - {49954D9C-5F17-4662-96B2-73BE833DD81A} - Library - Properties - RouteGuide - RouteGuide - v4.5 - 512 - 214cccda - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - - - False - ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll - - - False - ..\packages\Newtonsoft.Json.7.0.1-beta2\lib\net45\Newtonsoft.Json.dll - - - - False - ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - - - - ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll - - - - - - - - - - - - - - - - - - PreserveNewest - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - - \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs b/grpc-common/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs deleted file mode 100644 index c4b3900dca..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs +++ /dev/null @@ -1,123 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: route_guide.proto -#region Designer generated code - -using System; -using System.Threading; -using System.Threading.Tasks; -using Grpc.Core; - -namespace examples { - public static class RouteGuide - { - static readonly string __ServiceName = "examples.RouteGuide"; - - static readonly Marshaller __Marshaller_Point = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.Point.ParseFrom); - static readonly Marshaller __Marshaller_Feature = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.Feature.ParseFrom); - static readonly Marshaller __Marshaller_Rectangle = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.Rectangle.ParseFrom); - static readonly Marshaller __Marshaller_RouteSummary = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.RouteSummary.ParseFrom); - static readonly Marshaller __Marshaller_RouteNote = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.RouteNote.ParseFrom); - - static readonly Method __Method_GetFeature = new Method( - MethodType.Unary, - "GetFeature", - __Marshaller_Point, - __Marshaller_Feature); - - static readonly Method __Method_ListFeatures = new Method( - MethodType.ServerStreaming, - "ListFeatures", - __Marshaller_Rectangle, - __Marshaller_Feature); - - static readonly Method __Method_RecordRoute = new Method( - MethodType.ClientStreaming, - "RecordRoute", - __Marshaller_Point, - __Marshaller_RouteSummary); - - static readonly Method __Method_RouteChat = new Method( - MethodType.DuplexStreaming, - "RouteChat", - __Marshaller_RouteNote, - __Marshaller_RouteNote); - - // client-side stub interface - public interface IRouteGuideClient - { - global::examples.Feature GetFeature(global::examples.Point request, CancellationToken token = default(CancellationToken)); - Task GetFeatureAsync(global::examples.Point request, CancellationToken token = default(CancellationToken)); - AsyncServerStreamingCall ListFeatures(global::examples.Rectangle request, CancellationToken token = default(CancellationToken)); - AsyncClientStreamingCall RecordRoute(CancellationToken token = default(CancellationToken)); - AsyncDuplexStreamingCall RouteChat(CancellationToken token = default(CancellationToken)); - } - - // server-side interface - public interface IRouteGuide - { - Task GetFeature(ServerCallContext context, global::examples.Point request); - Task ListFeatures(ServerCallContext context, global::examples.Rectangle request, IServerStreamWriter responseStream); - Task RecordRoute(ServerCallContext context, IAsyncStreamReader requestStream); - Task RouteChat(ServerCallContext context, IAsyncStreamReader requestStream, IServerStreamWriter responseStream); - } - - // client stub - public class RouteGuideClient : AbstractStub, IRouteGuideClient - { - public RouteGuideClient(Channel channel) : this(channel, StubConfiguration.Default) - { - } - public RouteGuideClient(Channel channel, StubConfiguration config) : base(channel, config) - { - } - public global::examples.Feature GetFeature(global::examples.Point request, CancellationToken token = default(CancellationToken)) - { - var call = CreateCall(__ServiceName, __Method_GetFeature); - return Calls.BlockingUnaryCall(call, request, token); - } - public Task GetFeatureAsync(global::examples.Point request, CancellationToken token = default(CancellationToken)) - { - var call = CreateCall(__ServiceName, __Method_GetFeature); - return Calls.AsyncUnaryCall(call, request, token); - } - public AsyncServerStreamingCall ListFeatures(global::examples.Rectangle request, CancellationToken token = default(CancellationToken)) - { - var call = CreateCall(__ServiceName, __Method_ListFeatures); - return Calls.AsyncServerStreamingCall(call, request, token); - } - public AsyncClientStreamingCall RecordRoute(CancellationToken token = default(CancellationToken)) - { - var call = CreateCall(__ServiceName, __Method_RecordRoute); - return Calls.AsyncClientStreamingCall(call, token); - } - public AsyncDuplexStreamingCall RouteChat(CancellationToken token = default(CancellationToken)) - { - var call = CreateCall(__ServiceName, __Method_RouteChat); - return Calls.AsyncDuplexStreamingCall(call, token); - } - } - - // creates service definition that can be registered with a server - public static ServerServiceDefinition BindService(IRouteGuide serviceImpl) - { - return ServerServiceDefinition.CreateBuilder(__ServiceName) - .AddMethod(__Method_GetFeature, serviceImpl.GetFeature) - .AddMethod(__Method_ListFeatures, serviceImpl.ListFeatures) - .AddMethod(__Method_RecordRoute, serviceImpl.RecordRoute) - .AddMethod(__Method_RouteChat, serviceImpl.RouteChat).Build(); - } - - // creates a new client stub - public static IRouteGuideClient NewStub(Channel channel) - { - return new RouteGuideClient(channel); - } - - // creates a new client stub - public static IRouteGuideClient NewStub(Channel channel, StubConfiguration config) - { - return new RouteGuideClient(channel, config); - } - } -} -#endregion diff --git a/grpc-common/csharp/route_guide/RouteGuide/RouteGuideUtil.cs b/grpc-common/csharp/route_guide/RouteGuide/RouteGuideUtil.cs deleted file mode 100644 index 6fb8b1e28a..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuide/RouteGuideUtil.cs +++ /dev/null @@ -1,67 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace examples -{ - public static class RouteGuideUtil - { - public const string DefaultFeaturesFile = "route_guide_db.json"; - - private const double CoordFactor = 1e7; - - /// - /// Indicates whether the given feature exists (i.e. has a valid name). - /// - public static bool Exists(Feature feature) - { - return feature != null && (feature.Name.Length != 0); - } - - public static double GetLatitude(Point point) - { - return point.Latitude / CoordFactor; - } - - public static double GetLongitude(Point point) - { - return point.Longitude / CoordFactor; - } - - /// - /// Parses features from a JSON file. - /// - public static List ParseFeatures(string filename) - { - var features = new List(); - var jsonFeatures = JsonConvert.DeserializeObject>(File.ReadAllText(filename)); - - - foreach(var jsonFeature in jsonFeatures) - { - features.Add(Feature.CreateBuilder().SetName(jsonFeature.name).SetLocation( - Point.CreateBuilder() - .SetLongitude(jsonFeature.location.longitude) - .SetLatitude(jsonFeature.location.latitude).Build()).Build()); - } - return features; - } - - private class JsonFeature - { - public string name; - public JsonLocation location; - } - - private class JsonLocation - { - public int longitude; - public int latitude; - } - } -} diff --git a/grpc-common/csharp/route_guide/RouteGuide/packages.config b/grpc-common/csharp/route_guide/RouteGuide/packages.config deleted file mode 100644 index 79abe0aa65..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuide/packages.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuide/protos/route_guide.proto b/grpc-common/csharp/route_guide/RouteGuide/protos/route_guide.proto deleted file mode 100644 index f4110b5515..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuide/protos/route_guide.proto +++ /dev/null @@ -1,123 +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. - -// TODO(jtattermusch): as of now, C# protobufs don't officially support -// proto3. -syntax = "proto2"; - -package examples; - -// Interface exported by the server. -service RouteGuide { - // A simple RPC. - // - // Obtains the feature at a given position. - // - // A feature with an empty name is returned if there's no feature at the given - // position. - rpc GetFeature(Point) returns (Feature) {} - - // A server-to-client streaming RPC. - // - // Obtains the Features available within the given Rectangle. Results are - // streamed rather than returned at once (e.g. in a response message with a - // repeated field), as the rectangle may cover a large area and contain a - // huge number of features. - rpc ListFeatures(Rectangle) returns (stream Feature) {} - - // A client-to-server streaming RPC. - // - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} - - // A Bidirectional streaming RPC. - // - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -} - -// Points are represented as latitude-longitude pairs in the E7 representation -// (degrees multiplied by 10**7 and rounded to the nearest integer). -// Latitudes should be in the range +/- 90 degrees and longitude should be in -// the range +/- 180 degrees (inclusive). -message Point { - optional int32 latitude = 1; - optional int32 longitude = 2; -} - -// A latitude-longitude rectangle, represented as two diagonally opposite -// points "lo" and "hi". -message Rectangle { - // One corner of the rectangle. - optional Point lo = 1; - - // The other corner of the rectangle. - optional Point hi = 2; -} - -// A feature names something at a given point. -// -// If a feature could not be named, the name is empty. -message Feature { - // The name of the feature. - optional string name = 1; - - // The point where the feature is detected. - optional Point location = 2; -} - -// A RouteNote is a message sent while at a given point. -message RouteNote { - // The location from which the message is sent. - optional Point location = 1; - - // The message to be sent. - optional string message = 2; -} - -// A RouteSummary is received in response to a RecordRoute rpc. -// -// It contains the number of individual points received, the number of -// detected features, and the total distance covered as the cumulative sum of -// the distance between each point. -message RouteSummary { - // The number of points received. - optional int32 point_count = 1; - - // The number of known features passed while traversing the route. - optional int32 feature_count = 2; - - // The distance covered in metres. - optional int32 distance = 3; - - // The duration of the traversal in seconds. - optional int32 elapsed_time = 4; -} diff --git a/grpc-common/csharp/route_guide/RouteGuide/route_guide_db.json b/grpc-common/csharp/route_guide/RouteGuide/route_guide_db.json deleted file mode 100644 index 209f016259..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuide/route_guide_db.json +++ /dev/null @@ -1,601 +0,0 @@ -[{ - "location": { - "latitude": 407838351, - "longitude": -746143763 - }, - "name": "Patriots Path, Mendham, NJ 07945, USA" -}, { - "location": { - "latitude": 408122808, - "longitude": -743999179 - }, - "name": "101 New Jersey 10, Whippany, NJ 07981, USA" -}, { - "location": { - "latitude": 413628156, - "longitude": -749015468 - }, - "name": "U.S. 6, Shohola, PA 18458, USA" -}, { - "location": { - "latitude": 419999544, - "longitude": -740371136 - }, - "name": "5 Conners Road, Kingston, NY 12401, USA" -}, { - "location": { - "latitude": 414008389, - "longitude": -743951297 - }, - "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" -}, { - "location": { - "latitude": 419611318, - "longitude": -746524769 - }, - "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" -}, { - "location": { - "latitude": 406109563, - "longitude": -742186778 - }, - "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" -}, { - "location": { - "latitude": 416802456, - "longitude": -742370183 - }, - "name": "352 South Mountain Road, Wallkill, NY 12589, USA" -}, { - "location": { - "latitude": 412950425, - "longitude": -741077389 - }, - "name": "Bailey Turn Road, Harriman, NY 10926, USA" -}, { - "location": { - "latitude": 412144655, - "longitude": -743949739 - }, - "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" -}, { - "location": { - "latitude": 415736605, - "longitude": -742847522 - }, - "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" -}, { - "location": { - "latitude": 413843930, - "longitude": -740501726 - }, - "name": "162 Merrill Road, Highland Mills, NY 10930, USA" -}, { - "location": { - "latitude": 410873075, - "longitude": -744459023 - }, - "name": "Clinton Road, West Milford, NJ 07480, USA" -}, { - "location": { - "latitude": 412346009, - "longitude": -744026814 - }, - "name": "16 Old Brook Lane, Warwick, NY 10990, USA" -}, { - "location": { - "latitude": 402948455, - "longitude": -747903913 - }, - "name": "3 Drake Lane, Pennington, NJ 08534, USA" -}, { - "location": { - "latitude": 406337092, - "longitude": -740122226 - }, - "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" -}, { - "location": { - "latitude": 406421967, - "longitude": -747727624 - }, - "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" -}, { - "location": { - "latitude": 416318082, - "longitude": -749677716 - }, - "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" -}, { - "location": { - "latitude": 415301720, - "longitude": -748416257 - }, - "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" -}, { - "location": { - "latitude": 402647019, - "longitude": -747071791 - }, - "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" -}, { - "location": { - "latitude": 412567807, - "longitude": -741058078 - }, - "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" -}, { - "location": { - "latitude": 416855156, - "longitude": -744420597 - }, - "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" -}, { - "location": { - "latitude": 404663628, - "longitude": -744820157 - }, - "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" -}, { - "location": { - "latitude": 407113723, - "longitude": -749746483 - }, - "name": "" -}, { - "location": { - "latitude": 402133926, - "longitude": -743613249 - }, - "name": "" -}, { - "location": { - "latitude": 400273442, - "longitude": -741220915 - }, - "name": "" -}, { - "location": { - "latitude": 411236786, - "longitude": -744070769 - }, - "name": "" -}, { - "location": { - "latitude": 411633782, - "longitude": -746784970 - }, - "name": "211-225 Plains Road, Augusta, NJ 07822, USA" -}, { - "location": { - "latitude": 415830701, - "longitude": -742952812 - }, - "name": "" -}, { - "location": { - "latitude": 413447164, - "longitude": -748712898 - }, - "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" -}, { - "location": { - "latitude": 405047245, - "longitude": -749800722 - }, - "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" -}, { - "location": { - "latitude": 418858923, - "longitude": -746156790 - }, - "name": "" -}, { - "location": { - "latitude": 417951888, - "longitude": -748484944 - }, - "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" -}, { - "location": { - "latitude": 407033786, - "longitude": -743977337 - }, - "name": "26 East 3rd Street, New Providence, NJ 07974, USA" -}, { - "location": { - "latitude": 417548014, - "longitude": -740075041 - }, - "name": "" -}, { - "location": { - "latitude": 410395868, - "longitude": -744972325 - }, - "name": "" -}, { - "location": { - "latitude": 404615353, - "longitude": -745129803 - }, - "name": "" -}, { - "location": { - "latitude": 406589790, - "longitude": -743560121 - }, - "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" -}, { - "location": { - "latitude": 414653148, - "longitude": -740477477 - }, - "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" -}, { - "location": { - "latitude": 405957808, - "longitude": -743255336 - }, - "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" -}, { - "location": { - "latitude": 411733589, - "longitude": -741648093 - }, - "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" -}, { - "location": { - "latitude": 412676291, - "longitude": -742606606 - }, - "name": "1270 Lakes Road, Monroe, NY 10950, USA" -}, { - "location": { - "latitude": 409224445, - "longitude": -748286738 - }, - "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" -}, { - "location": { - "latitude": 406523420, - "longitude": -742135517 - }, - "name": "652 Garden Street, Elizabeth, NJ 07202, USA" -}, { - "location": { - "latitude": 401827388, - "longitude": -740294537 - }, - "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" -}, { - "location": { - "latitude": 410564152, - "longitude": -743685054 - }, - "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" -}, { - "location": { - "latitude": 408472324, - "longitude": -740726046 - }, - "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" -}, { - "location": { - "latitude": 412452168, - "longitude": -740214052 - }, - "name": "5 White Oak Lane, Stony Point, NY 10980, USA" -}, { - "location": { - "latitude": 409146138, - "longitude": -746188906 - }, - "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" -}, { - "location": { - "latitude": 404701380, - "longitude": -744781745 - }, - "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" -}, { - "location": { - "latitude": 409642566, - "longitude": -746017679 - }, - "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" -}, { - "location": { - "latitude": 408031728, - "longitude": -748645385 - }, - "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" -}, { - "location": { - "latitude": 413700272, - "longitude": -742135189 - }, - "name": "367 Prospect Road, Chester, NY 10918, USA" -}, { - "location": { - "latitude": 404310607, - "longitude": -740282632 - }, - "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" -}, { - "location": { - "latitude": 409319800, - "longitude": -746201391 - }, - "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" -}, { - "location": { - "latitude": 406685311, - "longitude": -742108603 - }, - "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" -}, { - "location": { - "latitude": 419018117, - "longitude": -749142781 - }, - "name": "43 Dreher Road, Roscoe, NY 12776, USA" -}, { - "location": { - "latitude": 412856162, - "longitude": -745148837 - }, - "name": "Swan Street, Pine Island, NY 10969, USA" -}, { - "location": { - "latitude": 416560744, - "longitude": -746721964 - }, - "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" -}, { - "location": { - "latitude": 405314270, - "longitude": -749836354 - }, - "name": "" -}, { - "location": { - "latitude": 414219548, - "longitude": -743327440 - }, - "name": "" -}, { - "location": { - "latitude": 415534177, - "longitude": -742900616 - }, - "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" -}, { - "location": { - "latitude": 406898530, - "longitude": -749127080 - }, - "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" -}, { - "location": { - "latitude": 407586880, - "longitude": -741670168 - }, - "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" -}, { - "location": { - "latitude": 400106455, - "longitude": -742870190 - }, - "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" -}, { - "location": { - "latitude": 400066188, - "longitude": -746793294 - }, - "name": "" -}, { - "location": { - "latitude": 418803880, - "longitude": -744102673 - }, - "name": "40 Mountain Road, Napanoch, NY 12458, USA" -}, { - "location": { - "latitude": 414204288, - "longitude": -747895140 - }, - "name": "" -}, { - "location": { - "latitude": 414777405, - "longitude": -740615601 - }, - "name": "" -}, { - "location": { - "latitude": 415464475, - "longitude": -747175374 - }, - "name": "48 North Road, Forestburgh, NY 12777, USA" -}, { - "location": { - "latitude": 404062378, - "longitude": -746376177 - }, - "name": "" -}, { - "location": { - "latitude": 405688272, - "longitude": -749285130 - }, - "name": "" -}, { - "location": { - "latitude": 400342070, - "longitude": -748788996 - }, - "name": "" -}, { - "location": { - "latitude": 401809022, - "longitude": -744157964 - }, - "name": "" -}, { - "location": { - "latitude": 404226644, - "longitude": -740517141 - }, - "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" -}, { - "location": { - "latitude": 410322033, - "longitude": -747871659 - }, - "name": "" -}, { - "location": { - "latitude": 407100674, - "longitude": -747742727 - }, - "name": "" -}, { - "location": { - "latitude": 418811433, - "longitude": -741718005 - }, - "name": "213 Bush Road, Stone Ridge, NY 12484, USA" -}, { - "location": { - "latitude": 415034302, - "longitude": -743850945 - }, - "name": "" -}, { - "location": { - "latitude": 411349992, - "longitude": -743694161 - }, - "name": "" -}, { - "location": { - "latitude": 404839914, - "longitude": -744759616 - }, - "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" -}, { - "location": { - "latitude": 414638017, - "longitude": -745957854 - }, - "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" -}, { - "location": { - "latitude": 412127800, - "longitude": -740173578 - }, - "name": "" -}, { - "location": { - "latitude": 401263460, - "longitude": -747964303 - }, - "name": "" -}, { - "location": { - "latitude": 412843391, - "longitude": -749086026 - }, - "name": "" -}, { - "location": { - "latitude": 418512773, - "longitude": -743067823 - }, - "name": "" -}, { - "location": { - "latitude": 404318328, - "longitude": -740835638 - }, - "name": "42-102 Main Street, Belford, NJ 07718, USA" -}, { - "location": { - "latitude": 419020746, - "longitude": -741172328 - }, - "name": "" -}, { - "location": { - "latitude": 404080723, - "longitude": -746119569 - }, - "name": "" -}, { - "location": { - "latitude": 401012643, - "longitude": -744035134 - }, - "name": "" -}, { - "location": { - "latitude": 404306372, - "longitude": -741079661 - }, - "name": "" -}, { - "location": { - "latitude": 403966326, - "longitude": -748519297 - }, - "name": "" -}, { - "location": { - "latitude": 405002031, - "longitude": -748407866 - }, - "name": "" -}, { - "location": { - "latitude": 409532885, - "longitude": -742200683 - }, - "name": "" -}, { - "location": { - "latitude": 416851321, - "longitude": -742674555 - }, - "name": "" -}, { - "location": { - "latitude": 406411633, - "longitude": -741722051 - }, - "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" -}, { - "location": { - "latitude": 413069058, - "longitude": -744597778 - }, - "name": "261 Van Sickle Road, Goshen, NY 10924, USA" -}, { - "location": { - "latitude": 418465462, - "longitude": -746859398 - }, - "name": "" -}, { - "location": { - "latitude": 411733222, - "longitude": -744228360 - }, - "name": "" -}, { - "location": { - "latitude": 410248224, - "longitude": -747127767 - }, - "name": "3 Hasta Way, Newton, NJ 07860, USA" -}] \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuideClient/App.config b/grpc-common/csharp/route_guide/RouteGuideClient/App.config deleted file mode 100644 index 8e15646352..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuideClient/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuideClient/Program.cs b/grpc-common/csharp/route_guide/RouteGuideClient/Program.cs deleted file mode 100644 index 0352c78020..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuideClient/Program.cs +++ /dev/null @@ -1,223 +0,0 @@ -using Grpc.Core; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace examples -{ - class Program - { - /// - /// Sample client code that makes gRPC calls to the server. - /// - public class RouteGuideClient - { - readonly RouteGuide.IRouteGuideClient client; - - public RouteGuideClient(RouteGuide.IRouteGuideClient client) - { - this.client = client; - } - - /// - /// Blocking unary call example. Calls GetFeature and prints the response. - /// - public void GetFeature(int lat, int lon) - { - try - { - Log("*** GetFeature: lat={0} lon={1}", lat, lon); - - Point request = Point.CreateBuilder().SetLatitude(lat).SetLongitude(lon).Build(); - - Feature feature = client.GetFeature(request); - if (RouteGuideUtil.Exists(feature)) - { - Log("Found feature called \"{0}\" at {1}, {2}", - feature.Name, - RouteGuideUtil.GetLatitude(feature.Location), - RouteGuideUtil.GetLongitude(feature.Location)); - } - else - { - Log("Found no feature at {0}, {1}", - RouteGuideUtil.GetLatitude(feature.Location), - RouteGuideUtil.GetLongitude(feature.Location)); - } - } - catch (RpcException e) - { - Log("RPC failed " + e); - throw e; - } - } - - - /// - /// Server-streaming example. Calls listFeatures with a rectangle of interest. Prints each response feature as it arrives. - /// - public async Task ListFeatures(int lowLat, int lowLon, int hiLat, int hiLon) - { - try - { - Log("*** ListFeatures: lowLat={0} lowLon={1} hiLat={2} hiLon={3}", lowLat, lowLon, hiLat, - hiLon); - - Rectangle request = - Rectangle.CreateBuilder() - .SetLo(Point.CreateBuilder().SetLatitude(lowLat).SetLongitude(lowLon).Build()) - .SetHi(Point.CreateBuilder().SetLatitude(hiLat).SetLongitude(hiLon).Build()).Build(); - - using (var call = client.ListFeatures(request)) - { - StringBuilder responseLog = new StringBuilder("Result: "); - - while (await call.ResponseStream.MoveNext()) - { - Feature feature = call.ResponseStream.Current; - responseLog.Append(feature.ToString()); - } - Log(responseLog.ToString()); - } - } - catch (RpcException e) - { - Log("RPC failed " + e); - throw e; - } - } - - /// - /// Client-streaming example. Sends numPoints randomly chosen points from features - /// with a variable delay in between. Prints the statistics when they are sent from the server. - /// - public async Task RecordRoute(List features, int numPoints) - { - try - { - Log("*** RecordRoute"); - using (var call = client.RecordRoute()) - { - // Send numPoints points randomly selected from the features list. - StringBuilder numMsg = new StringBuilder(); - Random rand = new Random(); - for (int i = 0; i < numPoints; ++i) - { - int index = rand.Next(features.Count); - Point point = features[index].Location; - Log("Visiting point {0}, {1}", RouteGuideUtil.GetLatitude(point), - RouteGuideUtil.GetLongitude(point)); - - await call.RequestStream.WriteAsync(point); - - // A bit of delay before sending the next one. - await Task.Delay(rand.Next(1000) + 500); - } - await call.RequestStream.CompleteAsync(); - - RouteSummary summary = await call.Result; - Log("Finished trip with {0} points. Passed {1} features. " - + "Travelled {2} meters. It took {3} seconds.", summary.PointCount, - summary.FeatureCount, summary.Distance, summary.ElapsedTime); - - Log("Finished RecordRoute"); - } - } - catch (RpcException e) - { - Log("RPC failed", e); - throw e; - } - } - - /// - /// Bi-directional streaming example. Send some chat messages, and print any - /// chat messages that are sent from the server. - /// - public async Task RouteChat() - { - try - { - Log("*** RouteChat"); - var requests = - new List { NewNote("First message", 0, 0), NewNote("Second message", 0, 1), NewNote("Third message", 1, 0), NewNote("Fourth message", 1, 1) }; - - using (var call = client.RouteChat()) - { - var responseReaderTask = Task.Run(async () => - { - while (await call.ResponseStream.MoveNext()) - { - var note = call.ResponseStream.Current; - Log("Got message \"{0}\" at {1}, {2}", note.Message, - note.Location.Latitude, note.Location.Longitude); - } - }); - - foreach (RouteNote request in requests) - { - Log("Sending message \"{0}\" at {1}, {2}", request.Message, - request.Location.Latitude, request.Location.Longitude); - - await call.RequestStream.WriteAsync(request); - } - await call.RequestStream.CompleteAsync(); - await responseReaderTask; - - Log("Finished RouteChat"); - } - } - catch (RpcException e) - { - Log("RPC failed", e); - throw e; - } - } - - private void Log(string s, params object[] args) - { - Console.WriteLine(string.Format(s, args)); - } - - private void Log(string s) - { - Console.WriteLine(s); - } - - private RouteNote NewNote(string message, int lat, int lon) - { - return RouteNote.CreateBuilder().SetMessage(message).SetLocation( - Point.CreateBuilder().SetLatitude(lat).SetLongitude(lat).Build()).Build(); - } - } - - static void Main(string[] args) - { - GrpcEnvironment.Initialize(); - - using (Channel channel = new Channel("127.0.0.1:50052")) - { - var client = new RouteGuideClient(RouteGuide.NewStub(channel)); - - // Looking for a valid feature - client.GetFeature(409146138, -746188906); - - // Feature missing. - client.GetFeature(0, 0); - - // Looking for features between 40, -75 and 42, -73. - client.ListFeatures(400000000, -750000000, 420000000, -730000000).Wait(); - - // Record a few randomly selected points from the features file. - client.RecordRoute(RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile), 10).Wait(); - - // Send and receive some notes. - client.RouteChat().Wait(); - } - - GrpcEnvironment.Shutdown(); - } - } -} diff --git a/grpc-common/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs b/grpc-common/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs deleted file mode 100644 index a17e164a78..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("RouteGuideClient")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("RouteGuideClient")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("914644eb-47cd-4a37-9fba-5e62dd432333")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/grpc-common/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj b/grpc-common/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj deleted file mode 100644 index 78034a9145..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - Debug - AnyCPU - {D47BE663-4DE3-4206-B7A8-EA3FA066DADC} - Exe - Properties - RouteGuideClient - RouteGuideClient - v4.5 - 512 - 794416d0 - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - - - False - ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll - - - - False - ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - - - - ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll - - - - - - - - - - - - - - - - - - {49954d9c-5f17-4662-96b2-73be833dd81a} - RouteGuide - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - - \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuideClient/packages.config b/grpc-common/csharp/route_guide/RouteGuideClient/packages.config deleted file mode 100644 index 5922553bc3..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuideClient/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuideServer/App.config b/grpc-common/csharp/route_guide/RouteGuideServer/App.config deleted file mode 100644 index 8e15646352..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuideServer/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuideServer/Program.cs b/grpc-common/csharp/route_guide/RouteGuideServer/Program.cs deleted file mode 100644 index e00b4d6723..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuideServer/Program.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Grpc.Core; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace examples -{ - class Program - { - static void Main(string[] args) - { - var features = RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile); - GrpcEnvironment.Initialize(); - - Server server = new Server(); - server.AddServiceDefinition(RouteGuide.BindService(new RouteGuideImpl(features))); - int port = server.AddListeningPort("localhost", 50052); - server.Start(); - - Console.WriteLine("RouteGuide server listening on port " + port); - Console.WriteLine("Press any key to stop the server..."); - Console.ReadKey(); - - server.ShutdownAsync().Wait(); - GrpcEnvironment.Shutdown(); - } - } -} diff --git a/grpc-common/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs b/grpc-common/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs deleted file mode 100644 index a161b1d602..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("RouteGuideServer")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("RouteGuideServer")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("908bdeef-05cc-42bf-9498-c4c573df8925")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs b/grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs deleted file mode 100644 index 0bdf386fc3..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs +++ /dev/null @@ -1,184 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace examples -{ - /// - /// Example implementation of RouteGuide server. - /// - public class RouteGuideImpl : RouteGuide.IRouteGuide - { - readonly List features; - private readonly ConcurrentDictionary> routeNotes = - new ConcurrentDictionary>(); - - public RouteGuideImpl(List features) - { - this.features = features; - } - - /// - /// Gets the feature at the requested point. If no feature at that location - /// exists, an unnammed feature is returned at the provided location. - /// - public Task GetFeature(Grpc.Core.ServerCallContext context, Point request) - { - return Task.FromResult(CheckFeature(request)); - } - - /// - /// Gets all features contained within the given bounding rectangle. - /// - public async Task ListFeatures(Grpc.Core.ServerCallContext context, Rectangle request, Grpc.Core.IServerStreamWriter responseStream) - { - int left = Math.Min(request.Lo.Longitude, request.Hi.Longitude); - int right = Math.Max(request.Lo.Longitude, request.Hi.Longitude); - int top = Math.Max(request.Lo.Latitude, request.Hi.Latitude); - int bottom = Math.Min(request.Lo.Latitude, request.Hi.Latitude); - - foreach (var feature in features) - { - if (!RouteGuideUtil.Exists(feature)) - { - continue; - } - - int lat = feature.Location.Latitude; - int lon = feature.Location.Longitude; - if (lon >= left && lon <= right && lat >= bottom && lat <= top) - { - await responseStream.WriteAsync(feature); - } - } - } - - /// - /// Gets a stream of points, and responds with statistics about the "trip": number of points, - /// number of known features visited, total distance traveled, and total time spent. - /// - public async Task RecordRoute(Grpc.Core.ServerCallContext context, Grpc.Core.IAsyncStreamReader requestStream) - { - int pointCount = 0; - int featureCount = 0; - int distance = 0; - Point previous = null; - var stopwatch = new Stopwatch(); - stopwatch.Start(); - - while (await requestStream.MoveNext()) - { - var point = requestStream.Current; - pointCount++; - if (RouteGuideUtil.Exists(CheckFeature(point))) - { - featureCount++; - } - if (previous != null) - { - distance += (int) CalcDistance(previous, point); - } - previous = point; - } - - stopwatch.Stop(); - return RouteSummary.CreateBuilder().SetPointCount(pointCount) - .SetFeatureCount(featureCount).SetDistance(distance) - .SetElapsedTime((int) (stopwatch.ElapsedMilliseconds / 1000)).Build(); - } - - /// - /// Receives a stream of message/location pairs, and responds with a stream of all previous - /// messages at each of those locations. - /// - public async Task RouteChat(Grpc.Core.ServerCallContext context, Grpc.Core.IAsyncStreamReader requestStream, Grpc.Core.IServerStreamWriter responseStream) - { - while (await requestStream.MoveNext()) - { - var note = requestStream.Current; - List notes = GetOrCreateNotes(note.Location); - - List prevNotes; - lock (notes) - { - prevNotes = new List(notes); - } - - foreach (var prevNote in prevNotes) - { - await responseStream.WriteAsync(prevNote); - } - - lock (notes) - { - notes.Add(note); - } - } - } - - - /// - /// Get the notes list for the given location. If missing, create it. - /// - private List GetOrCreateNotes(Point location) - { - List notes = new List(); - routeNotes.TryAdd(location, notes); - return routeNotes[location]; - } - - /// - /// Gets the feature at the given point. - /// - /// the location to check - /// The feature object at the point Note that an empty name indicates no feature. - private Feature CheckFeature(Point location) - { - foreach (var feature in features) - { - if (feature.Location.Latitude == location.Latitude - && feature.Location.Longitude == location.Longitude) - { - return feature; - } - } - - // No feature was found, return an unnamed feature. - return Feature.CreateBuilder().SetName("").SetLocation(location).Build(); - } - - /// - /// Calculate the distance between two points using the "haversine" formula. - /// This code was taken from http://www.movable-type.co.uk/scripts/latlong.html. - /// - /// the starting point - /// the end point - /// the distance between the points in meters - private static double CalcDistance(Point start, Point end) - { - double lat1 = RouteGuideUtil.GetLatitude(start); - double lat2 = RouteGuideUtil.GetLatitude(end); - double lon1 = RouteGuideUtil.GetLongitude(start); - double lon2 = RouteGuideUtil.GetLongitude(end); - int r = 6371000; // metres - double φ1 = ToRadians(lat1); - double φ2 = ToRadians(lat2); - double Δφ = ToRadians(lat2 - lat1); - double Δλ = ToRadians(lon2 - lon1); - - double a = Math.Sin(Δφ / 2) * Math.Sin(Δφ / 2) + Math.Cos(φ1) * Math.Cos(φ2) * Math.Sin(Δλ / 2) * Math.Sin(Δλ / 2); - double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); - - return r * c; - } - - private static double ToRadians(double val) - { - return (Math.PI / 180) * val; - } - } -} diff --git a/grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj b/grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj deleted file mode 100644 index 9ac1cfbf4d..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - Debug - AnyCPU - {4B7C7794-BE24-4477-ACE7-18259EB73D27} - Exe - Properties - RouteGuideServer - RouteGuideServer - v4.5 - 512 - 74781d8b - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll - - - ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll - - - False - ..\packages\Grpc.Core.0.6.0\lib\net45\Grpc.Core.dll - - - - False - ..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - - - - ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll - - - - - - - - - - - - - - - - - - - {49954d9c-5f17-4662-96b2-73be833dd81a} - RouteGuide - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - - \ No newline at end of file diff --git a/grpc-common/csharp/route_guide/RouteGuideServer/packages.config b/grpc-common/csharp/route_guide/RouteGuideServer/packages.config deleted file mode 100644 index 5922553bc3..0000000000 --- a/grpc-common/csharp/route_guide/RouteGuideServer/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/grpc-common/go/README.md b/grpc-common/go/README.md deleted file mode 100644 index 79db479ec5..0000000000 --- a/grpc-common/go/README.md +++ /dev/null @@ -1,53 +0,0 @@ -gRPC in 3 minutes (Go) -====================== - -BACKGROUND -------------- -For this sample, we've already generated the server and client stubs from [helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). - -PREREQUISITES -------------- - -- This requires Go 1.4 -- Requires that [GOPATH is set](https://golang.org/doc/code.html#GOPATH) -```sh -$ go help gopath -$ # ensure the PATH contains $GOPATH/bin -$ export PATH=$PATH:$GOPATH/bin -``` - -INSTALL -------- - -```sh -$ go get -u github.com/grpc/grpc-common/go/greeter_client -$ go get -u github.com/grpc/grpc-common/go/greeter_server -``` - -TRY IT! -------- - -- Run the server -```sh -$ greeter_server & -``` - -- Run the client -```sh -$ greeter_client -``` - -OPTIONAL - Rebuilding the generated code ----------------------------------------- - -1 First [install protoc](https://github.com/google/protobuf/blob/master/INSTALL.txt) - - For now, this needs to be installed from source - - This is will change once proto3 is officially released - -2 Install the protoc Go plugin. -```sh -$ go get -a github.com/golang/protobuf/protoc-gen-go -$ -$ # from this dir; invoke protoc -$ protoc -I ../protos ../protos/helloworld.proto --go_out=plugins=grpc:helloworld -``` diff --git a/grpc-common/go/gotutorial.md b/grpc-common/go/gotutorial.md deleted file mode 100644 index 63f0ad9058..0000000000 --- a/grpc-common/go/gotutorial.md +++ /dev/null @@ -1,431 +0,0 @@ -#gRPC Basics: Go - -This tutorial provides a basic Go programmer's introduction to working with gRPC. By walking through this example you'll learn how to: - -- Define a service in a .proto file. -- Generate server and client code using the protocol buffer compiler. -- Use the Go gRPC API to write a simple client and server for your service. - -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. - -This isn't a comprehensive guide to using gRPC in Go: more reference documentation is coming soon. - -## Why use gRPC? - -Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. - -With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. - -## Example code and setup - -The example code for our tutorial is in [grpc/grpc-go/examples/route_guide](https://github.com/grpc/grpc-go/tree/master/examples/route_guide). To download the example, clone the `grpc-go` repository by running the following command: -```shell -$ go get google.golang.org/grpc -``` - -Then change your current directory to `grpc-go/examples/route_guide`: -```shell -$ cd $GOPATH/src/google.golang.org/grpc/examples/route_guide -``` - -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Go quick start guide](https://github.com/grpc/grpc-common/tree/master/go). - - -## Defining the service - -Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). - -To define a service, you specify a named `service` in your .proto file: - -```proto -service RouteGuide { - ... -} -``` - -Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: - -- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. -```proto - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} -``` - -- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. -```proto - // Obtains the Features available within the given Rectangle. Results are - // streamed rather than returned at once (e.g. in a response message with a - // repeated field), as the rectangle may cover a large area and contain a - // huge number of features. - rpc ListFeatures(Rectangle) returns (stream Feature) {} -``` - -- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a client-side streaming method by placing the `stream` keyword before the *request* type. -```proto - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} -``` - -- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -```proto - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -``` - -Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -```proto -// 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; -} -``` - - -## Generating client and server code - -Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC Go plugin. - -For simplicity, we've provided a [bash script](https://github.com/grpc/grpc-go/blob/master/codegen.sh) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this by yourself, make sure you've installed protoc and followed the gRPC-Go [installation instructions](https://github.com/grpc/grpc-go/blob/master/README.md) first): - -```shell -$ codegen.sh route_guide.proto -``` - -which actually runs: - -```shell -$ protoc --go_out=plugins=grpc:. route_guide.proto -``` - -Running this command generates the following file in your current directory: -- `route_guide.pb.go` - -This contains: -- All the protocol buffer code to populate, serialize, and retrieve our request and response message types -- An interface type (or *stub*) for clients to call with the methods defined in the `RouteGuide` service. -- An interface type for servers to implement, also with the methods defined in the `RouteGuide` service. - - - -## Creating the server - -First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). - -There are two parts to making our `RouteGuide` service do its job: -- Implementing the service interface generated from our service definition: doing the actual "work" of our service. -- Running a gRPC server to listen for requests from clients and dispatch them to the right service implementation. - -You can find our example `RouteGuide` server in [grpc-go/examples/route_guide/server/server.go](https://github.com/grpc/grpc-go/tree/master/examples/route_guide/server/server.go). Let's take a closer look at how it works. - -### Implementing RouteGuide - -As you can see, our server has a `routeGuideServer` struct type that implements the generated `RouteGuideServer` interface: - -```go -type routeGuideServer struct { - ... -} -... - -func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) { - ... -} -... - -func (s *routeGuideServer) ListFeatures(rect *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer) error { - ... -} -... - -func (s *routeGuideServer) RecordRoute(stream pb.RouteGuide_RecordRouteServer) error { - ... -} -... - -func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error { - ... -} -... -``` - -#### Simple RPC -`routeGuideServer` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. - -```go -func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) { - for _, feature := range s.savedFeatures { - if proto.Equal(feature.Location, point) { - return feature, nil - } - } - // No feature was found, return an unnamed feature - return &pb.Feature{"", point}, nil -} -``` - -The method is passed a context object for the RPC and the client's `Point` protocol buffer request. It returns a `Feature` protocol buffer object with the response information and an `error`. In the method we populate the `Feature` with the appropriate information, and then `return` it along with an `nil` error to tell gRPC that we've finished dealing with the RPC and that the `Feature` can be returned to the client. - -#### Server-side streaming RPC -Now let's look at one of our streaming RPCs. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. - -```go -func (s *routeGuideServer) ListFeatures(rect *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer) error { - for _, feature := range s.savedFeatures { - if inRange(feature.Location, rect) { - if err := stream.Send(feature); err != nil { - return err - } - } - } - return nil -} -``` - -As you can see, instead of getting simple request and response objects in our method parameters, this time we get a request object (the `Rectangle` in which our client wants to find `Feature`s) and a special `RouteGuide_ListFeaturesServer` object to write our responses. - -In the method, we populate as many `Feature` objects as we need to return, writing them to the `RouteGuide_ListFeaturesServer` using its `Send()` method. Finally, as in our simple RPC, we return a `nil` error to tell gRPC that we've finished writing responses. Should any error happen in this call, we return a non-`nil` error; the gRPC layer will translate it into an appropriate RPC status to be sent on the wire. - -#### Client-side streaming RPC -Now let's look at something a little more complicated: the client-side streaming method `RecordRoute`, where we get a stream of `Point`s from the client and return a single `RouteSummary` with information about their trip. As you can see, this time the method doesn't have a request parameter at all. Instead, it gets a `RouteGuide_RecordRouteServer` stream, which the server can use to both read *and* write messages - it can receive client messages using its `Recv()` method and return its single response using its `SendAndClose()` method. - -```go -func (s *routeGuideServer) RecordRoute(stream pb.RouteGuide_RecordRouteServer) error { - var pointCount, featureCount, distance int32 - var lastPoint *pb.Point - startTime := time.Now() - for { - point, err := stream.Recv() - if err == io.EOF { - endTime := time.Now() - return stream.SendAndClose(&pb.RouteSummary{ - PointCount: pointCount, - FeatureCount: featureCount, - Distance: distance, - ElapsedTime: int32(endTime.Sub(startTime).Seconds()), - }) - } - if err != nil { - return err - } - pointCount++ - for _, feature := range s.savedFeatures { - if proto.Equal(feature.Location, point) { - featureCount++ - } - } - if lastPoint != nil { - distance += calcDistance(lastPoint, point) - } - lastPoint = point - } -} -``` - -In the method body we use the `RouteGuide_RecordRouteServer`s `Recv()` method to repeatedly read in our client's requests to a request object (in this case a `Point`) until there are no more messages: the server needs to check the the error returned from `Read()` after each call. If this is `nil`, the stream is still good and it can continue reading; if it's `io.EOF` the message stream has ended and the server can return its `RouteSummary`. If it has any other value, we return the error "as is" so that it'll be translated to an RPC status by the gRPC layer. - -#### Bidirectional streaming RPC -Finally, let's look at our bidirectional streaming RPC `RouteChat()`. - -```go -func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error { - for { - in, err := stream.Recv() - if err == io.EOF { - return nil - } - if err != nil { - return err - } - key := serialize(in.Location) - ... // look for notes to be sent to client - for _, note := range s.routeNotes[key] { - if err := stream.Send(note); err != nil { - return err - } - } - } -} -``` - -This time we get a `RouteGuide_RouteChatServer` stream that, as in our client-side streaming example, can be used to read and write messages. However, this time we return values via our method's stream while the client is still writing messages to *their* message stream. - -The syntax for reading and writing here is very similar to our client-streaming method, except the server uses the stream's `Send()` method rather than `SendAndClose()` because it's writing multiple responses. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. - -### Starting the server - -Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: - -```go -flag.Parse() -lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port)) -if err != nil { - log.Fatalf("failed to listen: %v", err) -} -grpcServer := grpc.NewServer() -pb.RegisterRouteGuideServer(grpcServer, &routeGuideServer{}) -... // determine whether to use TLS -grpcServer.Serve(lis) -``` -To build and start a server, we: - -1. Specify the port we want to use to listen for client requests using `lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))`. -2. Create an instance of the gRPC server using `grpc.NewServer()`. -3. Register our service implementation with the gRPC server. -4. Call `Serve()` on the server with our port details to do a blocking wait until the process is killed or `Stop()` is called. - - -## Creating the client - -In this section, we'll look at creating a Go client for our `RouteGuide` service. You can see our complete example client code in [grpc-go/examples/route_guide/client/client.go](https://github.com/grpc/grpc-go/tree/master/examples/route_guide/client/client.go). - -### Creating a stub - -To call service methods, we first need to create a gRPC *channel* to communicate with the server. We create this by passing the server address and port number to `grpc.Dial()` as follows: - -```go -conn, err := grpc.Dial(*serverAddr) -if err != nil { - ... -} -defer conn.Close() -``` - -You can use `DialOptions` to set the auth credentials (e.g., TLS, GCE credentials, JWT credentials) in `grpc.Dial` if the service you request requires that - however, we don't need to do this for our `RouteGuide` service. - -Once the gRPC *channel* is setup, we need a client *stub* to perform RPCs. We get this using the `NewRouteGuideClient` method provided in the `pb` package we generated from our .proto. - -```go -client := pb.NewRouteGuideClient(conn) -``` - -### Calling service methods - -Now let's look at how we call our service methods. Note that in gRPC-Go, RPCs operate in a blocking/synchronous mode, which means that the RPC call waits for the server to respond, and will either return a response or an error. - -#### Simple RPC - -Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. - -```go -feature, err := client.GetFeature(context.Background(), &pb.Point{409146138, -746188906}) -if err != nil { - ... -} -``` - -As you can see, we call the method on the stub we got earlier. In our method parameters we create and populate a request protocol buffer object (in our case `Point`). We also pass a `context.Context` object which lets us change our RPC's behaviour if necessary, such as time-out/cancel an RPC in flight. If the call doesn't return an error, then we can read the response information from the server from the first return value. - -```go -log.Println(feature) -``` - -#### Server-side streaming RPC - -Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. - -```go -rect := &pb.Rectangle{ ... } // initialize a pb.Rectangle -stream, err := client.ListFeatures(context.Background(), rect) -if err != nil { - ... -} -for { - feature, err := stream.Recv() - if err == io.EOF { - break - } - if err != nil { - log.Fatalf("%v.ListFeatures(_) = _, %v", client, err) - } - log.Println(feature) -} -``` - -As in the simple RPC, we pass the method a context and a request. However, instead of getting a response object back, we get back an instance of `RouteGuide_ListFeaturesClient`. The client can use the `RouteGuide_ListFeaturesClient` stream to read the server's responses. - -We use the `RouteGuide_ListFeaturesClient`'s `Recv()` method to repeatedly read in the server's responses to a response protocol buffer object (in this case a `Feature`) until there are no more messages: the client needs to check the error `err` returned from `Recv()` after each call. If `nil`, the stream is still good and it can continue reading; if it's `io.EOF` then the message stream has ended; otherwise there must be an RPC error, which is passed over through `err`. - -#### Client-side streaming RPC - -The client-side streaming method `RecordRoute` is similar to the server-side method, except that we only pass the method a context and get a `RouteGuide_RecordRouteClient` stream back, which we can use to both write *and* read messages. - -```go -// Create a random number of random points -r := rand.New(rand.NewSource(time.Now().UnixNano())) -pointCount := int(r.Int31n(100)) + 2 // Traverse at least two points -var points []*pb.Point -for i := 0; i < pointCount; i++ { - points = append(points, randomPoint(r)) -} -log.Printf("Traversing %d points.", len(points)) -stream, err := client.RecordRoute(context.Background()) -if err != nil { - log.Fatalf("%v.RecordRoute(_) = _, %v", client, err) -} -for _, point := range points { - if err := stream.Send(point); err != nil { - log.Fatalf("%v.Send(%v) = %v", stream, point, err) - } -} -reply, err := stream.CloseAndRecv() -if err != nil { - log.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, nil) -} -log.Printf("Route summary: %v", reply) -``` - -The `RouteGuide_RecordRouteClient` has a `Send()` method that we can use to send requests to the server. Once we've finished writing our client's requests to the stream using `Send()`, we need to call `CloseAndRecv()` on the stream to let gRPC know that we've finished writing and are expecting to receive a response. We get our RPC status from the `err` returned from `CloseAndRecv()`. If the status is `nil`, then the first return value from `CloseAndRecv()` will be a valid server response. - -#### Bidirectional streaming RPC - -Finally, let's look at our bidirectional streaming RPC `RouteChat()`. As in the case of `RecordRoute`, we only pass the method a context object and get back a stream that we can use to both write and read messages. However, this time we return values via our method's stream while the server is still writing messages to *their* message stream. - -```go -stream, err := client.RouteChat(context.Background()) -waitc := make(chan struct{}) -go func() { - for { - in, err := stream.Recv() - if err == io.EOF { - // read done. - close(waitc) - return - } - if err != nil { - log.Fatalf("Failed to receive a note : %v", err) - } - log.Printf("Got message %s at point(%d, %d)", in.Message, in.Location.Latitude, in.Location.Longitude) - } -}() -for _, note := range notes { - if err := stream.Send(note); err != nil { - log.Fatalf("Failed to send a note: %v", err) - } -} -stream.CloseSend() -<-waitc -``` - -The syntax for reading and writing here is very similar to our client-side streaming method, except we use the stream's `CloseSend()` method once we've finished our call. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. - -## Try it out! - -To compile and run the server, assuming you are in the folder -`$GOPATH/src/google.golang.org/grpc/examples/route_guide`, simply: - -```sh -$ go run server/server.go -``` - -Likewise, to run the client: - -```sh -$ go run client/client.go -``` - diff --git a/grpc-common/go/greeter_client/main.go b/grpc-common/go/greeter_client/main.go deleted file mode 100644 index 065ae852bc..0000000000 --- a/grpc-common/go/greeter_client/main.go +++ /dev/null @@ -1,69 +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. - * - */ - -package main - -import ( - "log" - "os" - - pb "github.com/grpc/grpc-common/go/helloworld" - "golang.org/x/net/context" - "google.golang.org/grpc" -) - -const ( - address = "localhost:50051" - defaultName = "world" -) - -func main() { - // Set up a connection to the server. - conn, err := grpc.Dial(address) - if err != nil { - log.Fatalf("did not connect: %v", err) - } - defer conn.Close() - c := pb.NewGreeterClient(conn) - - // Contact the server and print out its response. - name := defaultName - if len(os.Args) > 1 { - name = os.Args[1] - } - r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name}) - if err != nil { - log.Fatalf("could not greet: %v", err) - } - log.Printf("Greeting: %s", r.Message) -} diff --git a/grpc-common/go/greeter_server/main.go b/grpc-common/go/greeter_server/main.go deleted file mode 100644 index c7fa06ad18..0000000000 --- a/grpc-common/go/greeter_server/main.go +++ /dev/null @@ -1,65 +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. - * - */ - -package main - -import ( - "log" - "net" - - pb "github.com/grpc/grpc-common/go/helloworld" - "golang.org/x/net/context" - "google.golang.org/grpc" -) - -const ( - port = ":50051" -) - -// server is used to implement hellowrld.GreeterServer. -type server struct{} - -// SayHello implements helloworld.GreeterServer -func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { - return &pb.HelloReply{Message: "Hello " + in.Name}, nil -} - -func main() { - lis, err := net.Listen("tcp", port) - if err != nil { - log.Fatalf("failed to listen: %v", err) - } - s := grpc.NewServer() - pb.RegisterGreeterServer(s, &server{}) - s.Serve(lis) -} diff --git a/grpc-common/go/helloworld/helloworld.pb.go b/grpc-common/go/helloworld/helloworld.pb.go deleted file mode 100644 index 1ff931a384..0000000000 --- a/grpc-common/go/helloworld/helloworld.pb.go +++ /dev/null @@ -1,109 +0,0 @@ -// Code generated by protoc-gen-go. -// source: helloworld.proto -// DO NOT EDIT! - -/* -Package helloworld is a generated protocol buffer package. - -It is generated from these files: - helloworld.proto - -It has these top-level messages: - HelloRequest - HelloReply -*/ -package helloworld - -import proto "github.com/golang/protobuf/proto" - -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal - -// The request message containing the user's name. -type HelloRequest struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` -} - -func (m *HelloRequest) Reset() { *m = HelloRequest{} } -func (m *HelloRequest) String() string { return proto.CompactTextString(m) } -func (*HelloRequest) ProtoMessage() {} - -// The response message containing the greetings -type HelloReply struct { - Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` -} - -func (m *HelloReply) Reset() { *m = HelloReply{} } -func (m *HelloReply) String() string { return proto.CompactTextString(m) } -func (*HelloReply) ProtoMessage() {} - -func init() { -} - -// Client API for Greeter service - -type GreeterClient interface { - // Sends a greeting - SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) -} - -type greeterClient struct { - cc *grpc.ClientConn -} - -func NewGreeterClient(cc *grpc.ClientConn) GreeterClient { - return &greeterClient{cc} -} - -func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) { - out := new(HelloReply) - err := grpc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Greeter service - -type GreeterServer interface { - // Sends a greeting - SayHello(context.Context, *HelloRequest) (*HelloReply, error) -} - -func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) { - s.RegisterService(&_Greeter_serviceDesc, srv) -} - -func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { - in := new(HelloRequest) - if err := codec.Unmarshal(buf, in); err != nil { - return nil, err - } - out, err := srv.(GreeterServer).SayHello(ctx, in) - if err != nil { - return nil, err - } - return out, nil -} - -var _Greeter_serviceDesc = grpc.ServiceDesc{ - ServiceName: "helloworld.Greeter", - HandlerType: (*GreeterServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "SayHello", - Handler: _Greeter_SayHello_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, -} diff --git a/grpc-common/grpc-auth-support.md b/grpc-common/grpc-auth-support.md deleted file mode 100644 index b9ef299332..0000000000 --- a/grpc-common/grpc-auth-support.md +++ /dev/null @@ -1,289 +0,0 @@ -#gRPC Authentication support - -gRPC is designed to plug-in a number of authentication mechanisms. This document -provides a quick overview of the various auth mechanisms supported, discusses -the API with some examples, and concludes with a discussion of extensibility. -More documentation and examples are coming soon! - -## Supported auth mechanisms - -###SSL/TLS -gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the -server, and encrypt all the data exchanged between the client and the server. -Optional mechanisms are available for clients to provide certificates to -accomplish mutual authentication. - -###OAuth 2.0 -gRPC provides a generic mechanism (described below) to attach metadata to -requests and responses. This mechanism can be used to attach OAuth 2.0 Access -Tokens to RPCs being made at a client. Additional support for acquiring Access -Tokens while accessing Google APIs through gRPC is provided for certain auth -flows, demonstrated through code examples below. - -## API -To reduce complexity and minimize API clutter, gRPC works with a unified concept -of a Credentials object. Users construct gRPC credentials using corresponding -bootstrap credentials (e.g., SSL client certs or Service Account Keys), and use -the credentials while creating a gRPC channel to any server. Depending on the -type of credential supplied, the channel uses the credentials during the initial -SSL/TLS handshake with the server, or uses the credential to generate and -attach Access Tokens to each request being made on the channel. - -###SSL/TLS for server authentication and encryption -This is the simplest authentication scenario, where a client just wants to -authenticate the server and encrypt all data. - -```cpp -SslCredentialsOptions ssl_opts; // Options to override SSL params, empty by default -// Create the credentials object by providing service account key in constructor -std::unique_ptr creds = CredentialsFactory::SslCredentials(ssl_opts); -// Create a channel using the credentials created in the previous step -std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); -// Create a stub on the channel -std::unique_ptr stub(Greeter::NewStub(channel)); -// Make actual RPC calls on the stub. -grpc::Status s = stub->sayHello(&context, *request, response); -``` - -For advanced use cases such as modifying the root CA or using client certs, -the corresponding options can be set in the SslCredentialsOptions parameter -passed to the factory method. - - -###Authenticating with Google - -gRPC applications can use a simple API to create a credential that works in various deployment scenarios. - -```cpp -std::unique_ptr creds = CredentialsFactory::GoogleDefaultCredentials(); -// Create a channel, stub and make RPC calls (same as in the previous example) -std::shared_ptr channel = CreateChannel(server_name, creds, channel_args); -std::unique_ptr stub(Greeter::NewStub(channel)); -grpc::Status s = stub->sayHello(&context, *request, response); -``` - -This credential works for applications using Service Accounts as well as for -applications running in [Google Compute Engine (GCE)](https://cloud.google.com/compute/). In the former case, the -service account’s private keys are loaded from the file named in the environment -variable `GOOGLE_APPLICATION_CREDENTIALS`. The -keys are used to generate bearer tokens that are attached to each outgoing RPC -on the corresponding channel. - -For applications running in GCE, a default service account and corresponding -OAuth scopes can be configured during VM setup. At run-time, this credential -handles communication with the authentication systems to obtain OAuth2 access -tokens and attaches them to each outgoing RPC on the corresponding channel. -Extending gRPC to support other authentication mechanisms -The gRPC protocol is designed with a general mechanism for sending metadata -associated with RPC. Clients can send metadata at the beginning of an RPC and -servers can send back metadata at the beginning and end of the RPC. This -provides a natural mechanism to support OAuth2 and other authentication -mechanisms that need attach bearer tokens to individual request. - -In the simplest case, there is a single line of code required on the client -to add a specific token as metadata to an RPC and a corresponding access on -the server to retrieve this piece of metadata. The generation of the token -on the client side and its verification at the server can be done separately. - -A deeper integration can be achieved by plugging in a gRPC credentials implementation for any custom authentication mechanism that needs to attach per-request tokens. gRPC internals also allow switching out SSL/TLS with other encryption mechanisms. - -## Examples - -These authentication mechanisms will be available in all gRPC's supported languages. -The following sections demonstrate how authentication and authorization features described above appear in each language: more languages are coming soon. - -###SSL/TLS for server authentication and encryption (Ruby) -```ruby -# Base case - No encryption -stub = Helloworld::Greeter::Stub.new('localhost:50051') -... - -# With server authentication SSL/TLS -creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file -stub = Helloworld::Greeter::Stub.new('localhost:50051', creds: creds) -``` - -###SSL/TLS for server authentication and encryption (C#) -```csharp -// Base case - No encryption -var channel = new Channel("localhost:50051"); -var client = new Greeter.GreeterClient(channel); -... - -// With server authentication SSL/TLS -var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file -var channel = new Channel("localhost:50051", credentials); -var client = new Greeter.GreeterClient(channel); -``` - -###SSL/TLS for server authentication and encryption (Objective-C) - -The default for Objective-C is to use SSL/TLS, as that's the most common use case when accessing -remote APIs. - -```objective-c -// Base case - With server authentication SSL/TLS -HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"localhost:50051"]; -// Same as using @"https://localhost:50051". -... - -// No encryption -HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"http://localhost:50051"]; -// Specifying the HTTP scheme explicitly forces no encryption. -``` - -###SSL/TLS for server authentication and encryption (Python) -```python -# Base case - No encryption -stub = early_adopter_create_GreeterService_stub('localhost', 50051) -... - -# With server authentication SSL/TLS -stub = early_adopter_create_GreeterService_stub( - 'localhost', 50051, secure=True, root_certificates=open('ca.pem').read()) -... -``` -n.b.: the beta API will look different - -###Authenticating with Google (Ruby) -```ruby -# Base case - No encryption/authorization -stub = Helloworld::Greeter::Stub.new('localhost:50051') -... - -# Authenticating with Google -require 'googleauth' # from http://www.rubydoc.info/gems/googleauth/0.1.0 -... -creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file -scope = 'https://www.googleapis.com/auth/grpc-testing' -authorization = Google::Auth.get_application_default(scope) -stub = Helloworld::Greeter::Stub.new('localhost:50051', - creds: creds, - update_metadata: authorization.updater_proc) -``` - -###Authenticating with Google (Node.js) - -```node -// Base case - No encryption/authorization -var stub = new helloworld.Greeter('localhost:50051'); -... -// Authenticating with Google -var GoogleAuth = require('google-auth-library'); // from https://www.npmjs.com/package/google-auth-library -... -var creds = grpc.Credentials.createSsl(load_certs); // load_certs typically loads a CA roots file -var scope = 'https://www.googleapis.com/auth/grpc-testing'; -(new GoogleAuth()).getApplicationDefault(function(err, auth) { - if (auth.createScopeRequired()) { - auth = auth.createScoped(scope); - } - var stub = new helloworld.Greeter('localhost:50051', - {credentials: creds}, - grpc.getGoogleAuthDelegate(auth)); -}); -``` - -###Authenticating with Google (C#) -```csharp -// Base case - No encryption/authorization -var channel = new Channel("localhost:50051"); -var client = new Greeter.GreeterClient(channel); -... - -// Authenticating with Google -using Grpc.Auth; // from Grpc.Auth NuGet package -... -var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file -var channel = new Channel("localhost:50051", credentials); - -string scope = "https://www.googleapis.com/auth/grpc-testing"; -var authorization = GoogleCredential.GetApplicationDefault(); -if (authorization.IsCreateScopedRequired) -{ - authorization = credential.CreateScoped(new[] { scope }); -} -var client = new Greeter.GreeterClient(channel, - new StubConfiguration(OAuth2InterceptorFactory.Create(credential))); -``` - -###Authenticating with Google (PHP) -```php -// Base case - No encryption/authorization -$client = new helloworld\GreeterClient( - new Grpc\BaseStub('localhost:50051', [])); -... - -// Authenticating with Google -// the environment variable "GOOGLE_APPLICATION_CREDENTIALS" needs to be set -$scope = "https://www.googleapis.com/auth/grpc-testing"; -$auth = Google\Auth\ApplicationDefaultCredentials::getCredentials($scope); -$opts = [ - 'credentials' => Grpc\Credentials::createSsl(file_get_contents('ca.pem')); - 'update_metadata' => $auth->getUpdateMetadataFunc(), -]; - -$client = new helloworld\GreeterClient( - new Grpc\BaseStub('localhost:50051', $opts)); - -``` - -###Authenticating with Google (Objective-C) - -This example uses the [Google iOS Sign-In library](https://developers.google.com/identity/sign-in/ios/), -but it's easily extrapolated to any other OAuth2 library. - -```objective-c -// Base case - No authentication -[client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { - ... -}]; - -... - -// Authenticating with Google - -// When signing the user in, ask her for the relevant scopes. -GIDSignIn.sharedInstance.scopes = @[@"https://www.googleapis.com/auth/grpc-testing"]; - -... - -#import - -// Create a not-yet-started RPC. We want to set the request headers on this object before starting -// it. -ProtoRPC *call = - [client RPCToSayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { - ... - }]; - -// Set the access token to be used. -NSString *accessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken; -call.requestMetadata[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken]}]; - -// Start the RPC. -[call start]; -``` - -You can see a working example app, with a more detailed explanation, [here](https://github.com/grpc/grpc-common/tree/master/objective-c/auth_sample). - -### Authenticating with Google (Python) -```python -# Base case - No encryption -stub = early_adopter_create_GreeterService_stub('localhost', 50051) -... - -# With server authentication SSL/TLS -import oauth2client.client -credentials = oauth2client.GoogleCredentials.get_application_default() -scope = 'https://www.googleapis.com/auth/grpc-testing' -scoped_credentials = credentials.create_scoped([scope]) -access_token = scoped_credentials.get_access_token().access_token -metadata_transformer = ( - lambda x: [('Authorization', 'Bearer {}'.format(access_token))]) - -stub = early_adopter_create_GreeterService_stub( - 'localhost', 50051, secure=True, root_certificates=open('ca.pem').read(), - metadata_transformer=metadata_transformer) -... -``` -n.b.: the beta API will look different diff --git a/grpc-common/java/android/.gitignore b/grpc-common/java/android/.gitignore deleted file mode 100644 index 6345b76a48..0000000000 --- a/grpc-common/java/android/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -.gradle -/local.properties -/gradle.properties -/.idea/workspace.xml -/.idea/libraries -.DS_Store -/build -.idea/ - -*.iml -*.apk -*.ap_ -*.dex -*.class -bin/ -gen/ -.gradle/ -/*/build/ -local.properties -proguard/ -*.log diff --git a/grpc-common/java/android/README.md b/grpc-common/java/android/README.md deleted file mode 100644 index 9de65a0267..0000000000 --- a/grpc-common/java/android/README.md +++ /dev/null @@ -1,41 +0,0 @@ -gRPC Hello World Tutorial (Android Java) -======================== - -BACKGROUND -------------- -For this sample, we've already generated the server and client stubs from [helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). - -PREREQUISITES -------------- -- [Java gRPC](https://github.com/grpc/grpc-java) - -- [Android Tutorial](https://developer.android.com/training/basics/firstapp/index.html) if you're new to Android development - -- We only have Android gRPC client in this example. Please follow examples in other languages to build and run a gRPC server. - -INSTALL -------- -**1 Clone the gRPC Java git repo** -```sh -$ git clone https://github.com/grpc/grpc-java -``` - -**2 Install gRPC Java, as described in [How to Build](https://github.com/grpc/grpc-java#how-to-build)** -```sh -$ # from this dir -$ cd grpc-java -$ # follow the instructions in 'How to Build' -``` - -**3 Prepare the app** -- Clone this git repo -```sh -$ git clone https://github.com/grpc/grpc-common - -``` - -**4 Install the app** -```sh -$ cd grpc-common/java/android -$ ./gradlew installDebug -``` diff --git a/grpc-common/java/android/app/.gitignore b/grpc-common/java/android/app/.gitignore deleted file mode 100644 index 796b96d1c4..0000000000 --- a/grpc-common/java/android/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/grpc-common/java/android/app/build.gradle b/grpc-common/java/android/app/build.gradle deleted file mode 100644 index aedf4fe92a..0000000000 --- a/grpc-common/java/android/app/build.gradle +++ /dev/null @@ -1,34 +0,0 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion 21 - buildToolsVersion "21.1.2" - - defaultConfig { - applicationId "io.grpc.helloworldexample" - minSdkVersion 7 - targetSdkVersion 21 - versionCode 1 - versionName "1.0" - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } -} - -dependencies { - compile 'com.android.support:appcompat-v7:21.0.3' - compile 'com.google.code.findbugs:jsr305:3.0.0' - compile 'com.squareup.okhttp:okhttp:2.2.0' - compile 'com.google.guava:guava:18.0' - - // You need to build the https://github.com/grpc/grpc-java - // to obtain these libraries below. - compile 'io.grpc:grpc-core:0.1.0-SNAPSHOT' - compile 'io.grpc:grpc-protobuf-nano:0.1.0-SNAPSHOT' - compile 'io.grpc:grpc-okhttp:0.1.0-SNAPSHOT' - compile 'io.grpc:grpc-stub:0.1.0-SNAPSHOT' -} diff --git a/grpc-common/java/android/app/proguard-rules.pro b/grpc-common/java/android/app/proguard-rules.pro deleted file mode 100644 index 3e659b91f3..0000000000 --- a/grpc-common/java/android/app/proguard-rules.pro +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /Users/thagikura/android-sdk/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/grpc-common/java/android/app/src/main/AndroidManifest.xml b/grpc-common/java/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index 8c40f11684..0000000000 --- a/grpc-common/java/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/GreeterGrpc.java b/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/GreeterGrpc.java deleted file mode 100644 index 817c9fde8f..0000000000 --- a/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/GreeterGrpc.java +++ /dev/null @@ -1,179 +0,0 @@ -package io.grpc.helloworldexample; - -import java.io.IOException; - -import static io.grpc.stub.Calls.asyncUnaryCall; -import static io.grpc.stub.Calls.blockingUnaryCall; -import static io.grpc.stub.Calls.createMethodDescriptor; -import static io.grpc.stub.Calls.unaryFutureCall; -import static io.grpc.stub.ServerCalls.asyncUnaryRequestCall; -import static io.grpc.stub.ServerCalls.createMethodDefinition; - -public class GreeterGrpc { - - private static final io.grpc.stub.Method METHOD_SAY_HELLO = - io.grpc.stub.Method.create( - io.grpc.MethodType.UNARY, "SayHello", - io.grpc.protobuf.nano.NanoUtils.marshaller( - new io.grpc.protobuf.nano.Parser() { - @Override - public Helloworld.HelloRequest parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { - return Helloworld.HelloRequest.parseFrom(input); - } - }), - io.grpc.protobuf.nano.NanoUtils.marshaller( - new io.grpc.protobuf.nano.Parser() { - @Override - public Helloworld.HelloReply parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { - return Helloworld.HelloReply.parseFrom(input); - } - })); - - public static GreeterStub newStub(io.grpc.Channel channel) { - return new GreeterStub(channel, CONFIG); - } - - public static GreeterBlockingStub newBlockingStub( - io.grpc.Channel channel) { - return new GreeterBlockingStub(channel, CONFIG); - } - - public static GreeterFutureStub newFutureStub( - io.grpc.Channel channel) { - return new GreeterFutureStub(channel, CONFIG); - } - - public static final GreeterServiceDescriptor CONFIG = - new GreeterServiceDescriptor(); - - public static class GreeterServiceDescriptor extends - io.grpc.stub.AbstractServiceDescriptor { - public final io.grpc.MethodDescriptor sayHello; - - private GreeterServiceDescriptor() { - sayHello = createMethodDescriptor( - "helloworld.Greeter", METHOD_SAY_HELLO); - } - - private GreeterServiceDescriptor( - java.util.Map> methodMap) { - sayHello = (io.grpc.MethodDescriptor) methodMap.get( - CONFIG.sayHello.getName()); - } - - @java.lang.Override - protected GreeterServiceDescriptor build( - java.util.Map> methodMap) { - return new GreeterServiceDescriptor(methodMap); - } - - @java.lang.Override - public com.google.common.collect.ImmutableList> methods() { - return com.google.common.collect.ImmutableList.>of( - sayHello); - } - } - - public static interface Greeter { - - public void sayHello(Helloworld.HelloRequest request, - io.grpc.stub.StreamObserver responseObserver); - } - - public static interface GreeterBlockingClient { - - public Helloworld.HelloReply sayHello(Helloworld.HelloRequest request); - } - - public static interface GreeterFutureClient { - - public com.google.common.util.concurrent.ListenableFuture sayHello( - Helloworld.HelloRequest request); - } - - public static class GreeterStub extends - io.grpc.stub.AbstractStub - implements Greeter { - private GreeterStub(io.grpc.Channel channel, - GreeterServiceDescriptor config) { - super(channel, config); - } - - @java.lang.Override - protected GreeterStub build(io.grpc.Channel channel, - GreeterServiceDescriptor config) { - return new GreeterStub(channel, config); - } - - @java.lang.Override - public void sayHello(Helloworld.HelloRequest request, - io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( - channel.newCall(config.sayHello), request, responseObserver); - } - } - - public static class GreeterBlockingStub extends - io.grpc.stub.AbstractStub - implements GreeterBlockingClient { - private GreeterBlockingStub(io.grpc.Channel channel, - GreeterServiceDescriptor config) { - super(channel, config); - } - - @java.lang.Override - protected GreeterBlockingStub build(io.grpc.Channel channel, - GreeterServiceDescriptor config) { - return new GreeterBlockingStub(channel, config); - } - - @java.lang.Override - public Helloworld.HelloReply sayHello(Helloworld.HelloRequest request) { - return blockingUnaryCall( - channel.newCall(config.sayHello), request); - } - } - - public static class GreeterFutureStub extends - io.grpc.stub.AbstractStub - implements GreeterFutureClient { - private GreeterFutureStub(io.grpc.Channel channel, - GreeterServiceDescriptor config) { - super(channel, config); - } - - @java.lang.Override - protected GreeterFutureStub build(io.grpc.Channel channel, - GreeterServiceDescriptor config) { - return new GreeterFutureStub(channel, config); - } - - @java.lang.Override - public com.google.common.util.concurrent.ListenableFuture sayHello( - Helloworld.HelloRequest request) { - return unaryFutureCall( - channel.newCall(config.sayHello), request); - } - } - - public static io.grpc.ServerServiceDefinition bindService( - final Greeter serviceImpl) { - return io.grpc.ServerServiceDefinition.builder("helloworld.Greeter") - .addMethod(createMethodDefinition( - METHOD_SAY_HELLO, - asyncUnaryRequestCall( - new io.grpc.stub.ServerCalls.UnaryRequestMethod< - Helloworld.HelloRequest, - Helloworld.HelloReply>() { - @java.lang.Override - public void invoke( - Helloworld.HelloRequest request, - io.grpc.stub.StreamObserver responseObserver) { - serviceImpl.sayHello(request, responseObserver); - } - }))).build(); - } -} diff --git a/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/Helloworld.java b/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/Helloworld.java deleted file mode 100644 index 28da5a91d3..0000000000 --- a/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/Helloworld.java +++ /dev/null @@ -1,175 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! - -package io.grpc.helloworldexample; - -@SuppressWarnings("hiding") -public interface Helloworld { - - public static final class HelloRequest extends - com.google.protobuf.nano.MessageNano { - - private static volatile HelloRequest[] _emptyArray; - public static HelloRequest[] emptyArray() { - // Lazily initializes the empty array - if (_emptyArray == null) { - synchronized ( - com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { - if (_emptyArray == null) { - _emptyArray = new HelloRequest[0]; - } - } - } - return _emptyArray; - } - - // optional string name = 1; - public java.lang.String name; - - public HelloRequest() { - clear(); - } - - public HelloRequest clear() { - name = ""; - cachedSize = -1; - return this; - } - - @Override - public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) - throws java.io.IOException { - if (!this.name.equals("")) { - output.writeString(1, this.name); - } - super.writeTo(output); - } - - @Override - protected int computeSerializedSize() { - int size = super.computeSerializedSize(); - if (!this.name.equals("")) { - size += com.google.protobuf.nano.CodedOutputByteBufferNano - .computeStringSize(1, this.name); - } - return size; - } - - @Override - public HelloRequest mergeFrom( - com.google.protobuf.nano.CodedInputByteBufferNano input) - throws java.io.IOException { - while (true) { - int tag = input.readTag(); - switch (tag) { - case 0: - return this; - default: { - if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { - return this; - } - break; - } - case 10: { - this.name = input.readString(); - break; - } - } - } - } - - public static HelloRequest parseFrom(byte[] data) - throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { - return com.google.protobuf.nano.MessageNano.mergeFrom(new HelloRequest(), data); - } - - public static HelloRequest parseFrom( - com.google.protobuf.nano.CodedInputByteBufferNano input) - throws java.io.IOException { - return new HelloRequest().mergeFrom(input); - } - } - - public static final class HelloReply extends - com.google.protobuf.nano.MessageNano { - - private static volatile HelloReply[] _emptyArray; - public static HelloReply[] emptyArray() { - // Lazily initializes the empty array - if (_emptyArray == null) { - synchronized ( - com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { - if (_emptyArray == null) { - _emptyArray = new HelloReply[0]; - } - } - } - return _emptyArray; - } - - // optional string message = 1; - public java.lang.String message; - - public HelloReply() { - clear(); - } - - public HelloReply clear() { - message = ""; - cachedSize = -1; - return this; - } - - @Override - public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) - throws java.io.IOException { - if (!this.message.equals("")) { - output.writeString(1, this.message); - } - super.writeTo(output); - } - - @Override - protected int computeSerializedSize() { - int size = super.computeSerializedSize(); - if (!this.message.equals("")) { - size += com.google.protobuf.nano.CodedOutputByteBufferNano - .computeStringSize(1, this.message); - } - return size; - } - - @Override - public HelloReply mergeFrom( - com.google.protobuf.nano.CodedInputByteBufferNano input) - throws java.io.IOException { - while (true) { - int tag = input.readTag(); - switch (tag) { - case 0: - return this; - default: { - if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { - return this; - } - break; - } - case 10: { - this.message = input.readString(); - break; - } - } - } - } - - public static HelloReply parseFrom(byte[] data) - throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { - return com.google.protobuf.nano.MessageNano.mergeFrom(new HelloReply(), data); - } - - public static HelloReply parseFrom( - com.google.protobuf.nano.CodedInputByteBufferNano input) - throws java.io.IOException { - return new HelloReply().mergeFrom(input); - } - } -} \ No newline at end of file diff --git a/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java b/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java deleted file mode 100644 index b6d734f9a9..0000000000 --- a/grpc-common/java/android/app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java +++ /dev/null @@ -1,90 +0,0 @@ -package io.grpc.helloworldexample; - -import android.content.Context; -import android.os.AsyncTask; -import android.os.Bundle; -import android.support.v7.app.ActionBarActivity; -import android.text.TextUtils; -import android.view.View; -import android.view.inputmethod.InputMethodManager; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TextView; - -import java.util.concurrent.TimeUnit; - -import io.grpc.ChannelImpl; -import io.grpc.helloworldexample.Helloworld.HelloReply; -import io.grpc.helloworldexample.Helloworld.HelloRequest; -import io.grpc.transport.okhttp.OkHttpChannelBuilder; - -public class HelloworldActivity extends ActionBarActivity { - private Button mSendButton; - private EditText mHostEdit; - private EditText mPortEdit; - private EditText mMessageEdit; - private TextView mResultText; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_helloworld); - mSendButton = (Button) findViewById(R.id.send_button); - mHostEdit = (EditText) findViewById(R.id.host_edit_text); - mPortEdit = (EditText) findViewById(R.id.port_edit_text); - mMessageEdit = (EditText) findViewById(R.id.message_edit_text); - mResultText = (TextView) findViewById(R.id.grpc_response_text); - } - - public void sendMessage(View view) { - ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)) - .hideSoftInputFromWindow(mHostEdit.getWindowToken(), 0); - mSendButton.setEnabled(false); - new GrpcTask().execute(); - } - - private class GrpcTask extends AsyncTask { - private String mHost; - private String mMessage; - private int mPort; - private ChannelImpl mChannel; - - @Override - protected void onPreExecute() { - mHost = mHostEdit.getText().toString(); - mMessage = mMessageEdit.getText().toString(); - String portStr = mPortEdit.getText().toString(); - mPort = TextUtils.isEmpty(portStr) ? 0 : Integer.valueOf(portStr); - mResultText.setText(""); - } - - private String sayHello(ChannelImpl channel) { - GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel); - HelloRequest message = new HelloRequest(); - message.name = mMessage; - HelloReply reply = stub.sayHello(message); - return reply.message; - } - - @Override - protected String doInBackground(Void... nothing) { - try { - mChannel = OkHttpChannelBuilder.forAddress(mHost, mPort).build(); - return sayHello(mChannel); - } catch (Exception e) { - return "Failed... : " + e.getMessage(); - } - } - - @Override - protected void onPostExecute(String result) { - try { - mChannel.shutdown().awaitTerminated(1, TimeUnit.SECONDS); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - mResultText.setText(result); - mSendButton.setEnabled(true); - } - } -} \ No newline at end of file diff --git a/grpc-common/java/android/app/src/main/res/layout/activity_helloworld.xml b/grpc-common/java/android/app/src/main/res/layout/activity_helloworld.xml deleted file mode 100644 index 00ca04ce65..0000000000 --- a/grpc-common/java/android/app/src/main/res/layout/activity_helloworld.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/grpc-common/objective-c/auth_sample/Misc/GoogleService-Info.plist b/grpc-common/objective-c/auth_sample/Misc/GoogleService-Info.plist deleted file mode 100644 index 86909d84a3..0000000000 --- a/grpc-common/objective-c/auth_sample/Misc/GoogleService-Info.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - CLIENT_ID - 15087385131-lh9bpkiai9nls53uadju0if6k7un3uih.apps.googleusercontent.com - REVERSED_CLIENT_ID - com.googleusercontent.apps.15087385131-lh9bpkiai9nls53uadju0if6k7un3uih - - \ No newline at end of file diff --git a/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json b/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 36d2c80d88..0000000000 --- a/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json b/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json deleted file mode 100644 index 33a745102c..0000000000 --- a/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "first.pdf" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf b/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf deleted file mode 100644 index 47d911dea6..0000000000 Binary files a/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf and /dev/null differ diff --git a/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json b/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json deleted file mode 100644 index 03bd9c927f..0000000000 --- a/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "second.pdf" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf b/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf deleted file mode 100644 index 401614e288..0000000000 Binary files a/grpc-common/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf and /dev/null differ diff --git a/grpc-common/objective-c/auth_sample/Misc/Info.plist b/grpc-common/objective-c/auth_sample/Misc/Info.plist deleted file mode 100644 index fc292507c7..0000000000 --- a/grpc-common/objective-c/auth_sample/Misc/Info.plist +++ /dev/null @@ -1,80 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - io.grpc.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleURLTypes - - - CFBundleTypeRole - Editor - CFBundleURLName - REVERSED_CLIENT_ID - CFBundleURLSchemes - - com.googleusercontent.apps.15087385131-lh9bpkiai9nls53uadju0if6k7un3uih - - - - CFBundleTypeRole - Editor - CFBundleURLName - BUNDLE_ID - CFBundleURLSchemes - - io.grpc.AuthSample - - - - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - Main - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarTintParameters - - UINavigationBar - - Style - UIBarStyleDefault - Translucent - - - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/grpc-common/objective-c/auth_sample/Misc/main.m b/grpc-common/objective-c/auth_sample/Misc/main.m deleted file mode 100644 index 81e9d44e54..0000000000 --- a/grpc-common/objective-c/auth_sample/Misc/main.m +++ /dev/null @@ -1,41 +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. - * - */ - -#import -#import "AppDelegate.h" - -int main(int argc, char * argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/grpc-common/objective-c/auth_sample/Podfile b/grpc-common/objective-c/auth_sample/Podfile deleted file mode 100644 index dd4fd558c0..0000000000 --- a/grpc-common/objective-c/auth_sample/Podfile +++ /dev/null @@ -1,10 +0,0 @@ -source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '8.0' - -target 'AuthSample' do - # Depend on the generated AuthTestService library. - pod 'AuthTestService', :path => '.' - - # Depend on Google's OAuth2 library - pod 'Google/SignIn' -end diff --git a/grpc-common/objective-c/auth_sample/README.md b/grpc-common/objective-c/auth_sample/README.md deleted file mode 100644 index 4ca4982f53..0000000000 --- a/grpc-common/objective-c/auth_sample/README.md +++ /dev/null @@ -1,189 +0,0 @@ -#OAuth2 on gRPC: Objective-C - -This example application demostrates how to use OAuth2 on gRPC to make authenticated API calls on -behalf of a user. By walking through it you'll learn how to use the Objective-C gRPC API to: - -- Initialize and configure a remote call object before the RPC is started. -- Set request metadata elements on a call, which are semantically equivalent to HTTP request -headers. -- Read response metadata from a call, which is equivalent to HTTP response headers and trailers. - -It assumes you know the basics on how to make gRPC API calls using the Objective-C client library, -as shown in the [Hello World](https://github.com/grpc/grpc-common/tree/master/objective-c/helloworld) -or [Route Guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide) tutorials, -and are familiar with OAuth2 concepts like _access token_. - -- [Example code and setup](#setup) -- [Try it out!](#try) -- [Create an RPC object and start it later](#rpc-object) -- [Set request metadata of a call: Authorization header with an access token](#request-metadata) -- [Get response metadata of a call: Auth challenge header](#response-metadata) - - -## Example code and setup - -The example code for our tutorial is in [grpc/grpc-common/objective-c/auth_sample](https://github.com/grpc/grpc-common/tree/master/objective-c/auth_sample). -To download the example, clone the `grpc-common` repository by running the following command: -```shell -$ git clone https://github.com/grpc/grpc-common.git -``` - -Then change your current directory to `grpc-common/objective-c/auth_sample`: -```shell -$ cd grpc-common/objective-c/auth_sample -``` - -Our example is a simple application with two views. The first one lets a user sign in and out using -the OAuth2 flow of Google's [iOS SignIn library](https://developers.google.com/identity/sign-in/ios/). -(Google's library is used in this example because the test gRPC service we are going to call expects -Google account credentials, but neither gRPC nor the Objective-C client library is tied to any -specific OAuth2 provider). The second view makes a gRPC request to the test server, using the -access token obtained by the first view. - -Note: OAuth2 libraries need the application to register and obtain an ID from the identity provider -(in the case of this example app, Google). The app's XCode project is configured using that ID, so -you shouldn't copy this project "as is" for your own app: it would result in your app being -identified in the consent screen as "gRPC-AuthSample", and not having access to real Google -services. Instead, configure your own XCode project following the [instructions here](https://developers.google.com/identity/sign-in/ios/). - -As with the other examples, you also should have [Cocoapods](https://cocoapods.org/#install) -installed, as well as the relevant tools to generate the client library code. You can obtain the -latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). - - - -## Try it out! - -To try the sample app, first have Cocoapods generate and install the client library for our .proto -files: - -```shell -$ pod install -``` - -(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet -on your computer's cache). - -Finally, open the XCode workspace created by Cocoapods, and run the app. - -The first view, `SelectUserViewController.h/m`, asks you to sign in with your Google account, and to -give the "gRPC-AuthSample" app the following permissions: - -- View your email address. -- View your basic profile info. -- "Test scope for access to the Zoo service". - -This last permission, corresponding to the scope `https://www.googleapis.com/auth/xapi.zoo` doesn't -grant any real capability: it's only used for testing. You can log out at any time. - -The second view, `MakeRPCViewController.h/m`, makes a gRPC request to a test server at -https://grpc-test.sandbox.google.com, sending the access token along with the request. The test -service simply validates the token and writes in its response which user it belongs to, and which -scopes it gives access to. (The client application already knows those two values; it's a way to -verify that everything went as expected). - -The next sections guide you step-by-step through how the gRPC call in `MakeRPCViewController` is -performed. - - -## Create an RPC object and start it later - -The other basic tutorials show how to invoke an RPC by calling an asynchronous method in a generated -client object. This shows how to initialize an object that represents the RPC, and configure it -before starting the network request. - -Assume you have a proto service definition like this: - -```protobuf -option objc_class_prefix = "AUTH"; - -service TestService { - rpc UnaryCall(Request) returns (Response); -} -``` - -A `unaryCallWithRequest:handler:` method, with which you're already familiar, is generated for the -`AUTHTestService` class: - -```objective-c -[client unaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { - ... -}]; -``` - -In addition, an `RPCToUnaryCallWithRequest:handler:` method is generated, which returns a -not-yet-started RPC object: - -```objective-c -#import - -ProtoRPC *call = - [client RPCToUnaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { - ... - }]; -``` - -The RPC represented by this object can be started at any later time like this: - -```objective-c -[call start]; -``` - - -## Set request metadata of a call: Authorization header with an access token - -The `ProtoRPC` class has a `requestMetadata` property (inherited from `GRPCCall`) defined like this: - -```objective-c -- (NSMutableDictionary *)requestMetadata; // nonatomic -- (void)setRequestMetadata:(NSDictionary *)requestMetadata; // nonatomic, copy -``` - -Setting it to a dictionary of metadata keys and values will have them sent on the wire when the call -is started. gRPC metadata are pieces of information about the call sent by the client to the server -(and vice versa). They take the form of key-value pairs and are essentially opaque to gRPC itself. - -```objective-c -call.requestMetadata = @{@"My-Header": @"Value for this header", - @"Another-Header": @"Its value"}; -``` - -For convenience, the property is initialized with an empty `NSMutableDictionary`, so that request -metadata elements can be set like this: - -```objective-c -call.requestMetadata[@"My-Header"] = @"Value for this header"; -``` - -If you have an access token, OAuth2 specifies it is to be sent in this format: - -```objective-c -call.requestMetadata[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken]; -``` - - -## Get response metadata of a call: Auth challenge header - -The `ProtoRPC` class also inherits a `responseMetadata` property, analogous to the request metadata -we just looked at. It's defined like this: - -```objective-c -@property(atomic, readonly) NSDictionary *responseMetadata; -``` - -To access OAuth2's authentication challenge header you write: - -```objective-c -call.responseMetadata[@"www-authenticate"] -``` - -Note that, as gRPC metadata elements are mapped to HTTP/2 headers (or trailers), the keys of the -response metadata are always ASCII strings in lowercase. - -Many uses cases of response metadata are getting more details about an RPC error. For convenience, -when a `NSError` instance is passed to an RPC handler block, the response metadata dictionary can -also be accessed this way: - -```objective-c -error.userInfo[kGRPCStatusMetadataKey] -``` diff --git a/grpc-common/objective-c/auth_sample/SelectUserViewController.h b/grpc-common/objective-c/auth_sample/SelectUserViewController.h deleted file mode 100644 index eb3c2cf5f0..0000000000 --- a/grpc-common/objective-c/auth_sample/SelectUserViewController.h +++ /dev/null @@ -1,42 +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. - * - */ - -#import -#import - -@interface SelectUserViewController : UIViewController -@property(weak, nonatomic) IBOutlet GIDSignInButton *signInButton; -@property(weak, nonatomic) IBOutlet UIButton *signOutButton; -@property(weak, nonatomic) IBOutlet UILabel *mainLabel; -@property(weak, nonatomic) IBOutlet UILabel *subLabel; -@end diff --git a/grpc-common/objective-c/auth_sample/SelectUserViewController.m b/grpc-common/objective-c/auth_sample/SelectUserViewController.m deleted file mode 100644 index 954c531f3f..0000000000 --- a/grpc-common/objective-c/auth_sample/SelectUserViewController.m +++ /dev/null @@ -1,86 +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. - * - */ - -#import "SelectUserViewController.h" - -#import "MakeRPCViewController.h" - -@implementation SelectUserViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.signOutButton.layer.cornerRadius = 5; - self.signOutButton.hidden = YES; - - // As instructed in https://developers.google.com/identity/sign-in/ios/sign-in - GIDSignIn *signIn = GIDSignIn.sharedInstance; - signIn.delegate = self; - signIn.uiDelegate = self; - - // As instructed in https://developers.google.com/identity/sign-in/ios/additional-scopes - if (![signIn.scopes containsObject:kTestScope]) { - signIn.scopes = [signIn.scopes arrayByAddingObject:kTestScope]; - } - - [signIn signInSilently]; -} - -- (void)signIn:(GIDSignIn *)signIn -didSignInForUser:(GIDGoogleUser *)user - withError:(NSError *)error { - if (error) { - // The user probably cancelled the sign-in flow. - return; - } - - self.mainLabel.text = [NSString stringWithFormat:@"User: %@", user.profile.email]; - NSString *scopes = [user.accessibleScopes componentsJoinedByString:@", "]; - scopes = scopes.length ? scopes : @"(none)"; - self.subLabel.text = [NSString stringWithFormat:@"Scopes: %@", scopes]; - - self.signInButton.hidden = YES; - self.signOutButton.hidden = NO; -} - -- (IBAction)didTapSignOut { - [GIDSignIn.sharedInstance signOut]; - - self.mainLabel.text = @"Please sign in."; - self.subLabel.text = @""; - - self.signInButton.hidden = NO; - self.signOutButton.hidden = YES; -} - -@end diff --git a/grpc-common/objective-c/helloworld/HelloWorld.podspec b/grpc-common/objective-c/helloworld/HelloWorld.podspec deleted file mode 100644 index ae009a688c..0000000000 --- a/grpc-common/objective-c/helloworld/HelloWorld.podspec +++ /dev/null @@ -1,35 +0,0 @@ -Pod::Spec.new do |s| - s.name = "HelloWorld" - s.version = "0.0.1" - s.license = "New BSD" - - s.ios.deployment_target = "6.0" - s.osx.deployment_target = "10.8" - - # Base directory where the .proto files are. - src = "../../protos" - - # Directory where the generated files will be place. - dir = "Pods/" + s.name - - # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.prepare_command = <<-CMD - mkdir -p #{dir} - protoc -I #{src} --objc_out=#{dir} --objcgrpc_out=#{dir} #{src}/helloworld.proto - CMD - - s.subspec "Messages" do |ms| - ms.source_files = "#{dir}/*.pbobjc.{h,m}", "#{dir}/**/*.pbobjc.{h,m}" - ms.header_mappings_dir = dir - ms.requires_arc = false - ms.dependency "Protobuf", "~> 3.0.0-alpha-3" - end - - s.subspec "Services" do |ss| - ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}" - ss.header_mappings_dir = dir - ss.requires_arc = true - ss.dependency "gRPC", "~> 0.6" - ss.dependency "#{s.name}/Messages" - end -end diff --git a/grpc-common/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj b/grpc-common/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj deleted file mode 100644 index 702ad3ff8b..0000000000 --- a/grpc-common/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj +++ /dev/null @@ -1,349 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 5E3690661B2A23800040F884 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3690651B2A23800040F884 /* main.m */; }; - 5E3690691B2A23800040F884 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3690681B2A23800040F884 /* AppDelegate.m */; }; - 5E36906C1B2A23800040F884 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E36906B1B2A23800040F884 /* ViewController.m */; }; - 5E36906F1B2A23800040F884 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E36906D1B2A23800040F884 /* Main.storyboard */; }; - 5E3690711B2A23800040F884 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5E3690701B2A23800040F884 /* Images.xcassets */; }; - EF61CF6AE2536A31D47F0E63 /* libPods-HelloWorld.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B4E1F55F8A2EC95A0E7EE88 /* libPods-HelloWorld.a */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.release.xcconfig"; path = "Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld.release.xcconfig"; sourceTree = ""; }; - 5E3690601B2A23800040F884 /* HelloWorld.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorld.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 5E3690641B2A23800040F884 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5E3690651B2A23800040F884 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 5E3690671B2A23800040F884 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 5E3690681B2A23800040F884 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 5E36906B1B2A23800040F884 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; - 5E36906E1B2A23800040F884 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 5E3690701B2A23800040F884 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6B4E1F55F8A2EC95A0E7EE88 /* libPods-HelloWorld.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HelloWorld.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.debug.xcconfig"; path = "Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld.debug.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 5E36905D1B2A23800040F884 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - EF61CF6AE2536A31D47F0E63 /* libPods-HelloWorld.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 5E3690571B2A23800040F884 = { - isa = PBXGroup; - children = ( - 5E3690651B2A23800040F884 /* main.m */, - 5E3690621B2A23800040F884 /* HelloWorld */, - 5E3690611B2A23800040F884 /* Products */, - BD9CE6458E7C4FF49A1DF69F /* Pods */, - 66CEC7120220DDD2221DD075 /* Frameworks */, - ); - sourceTree = ""; - }; - 5E3690611B2A23800040F884 /* Products */ = { - isa = PBXGroup; - children = ( - 5E3690601B2A23800040F884 /* HelloWorld.app */, - ); - name = Products; - sourceTree = ""; - }; - 5E3690621B2A23800040F884 /* HelloWorld */ = { - isa = PBXGroup; - children = ( - 5E3690631B2A23800040F884 /* Supporting Files */, - ); - path = HelloWorld; - sourceTree = ""; - }; - 5E3690631B2A23800040F884 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 5E3690701B2A23800040F884 /* Images.xcassets */, - 5E36906D1B2A23800040F884 /* Main.storyboard */, - 5E36906B1B2A23800040F884 /* ViewController.m */, - 5E3690681B2A23800040F884 /* AppDelegate.m */, - 5E3690671B2A23800040F884 /* AppDelegate.h */, - 5E3690641B2A23800040F884 /* Info.plist */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 66CEC7120220DDD2221DD075 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 6B4E1F55F8A2EC95A0E7EE88 /* libPods-HelloWorld.a */, - ); - name = Frameworks; - sourceTree = ""; - }; - BD9CE6458E7C4FF49A1DF69F /* Pods */ = { - isa = PBXGroup; - children = ( - DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */, - 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 5E36905F1B2A23800040F884 /* HelloWorld */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5E3690831B2A23810040F884 /* Build configuration list for PBXNativeTarget "HelloWorld" */; - buildPhases = ( - ACF9162361FB8F24C70657DE /* Check Pods Manifest.lock */, - 5E36905C1B2A23800040F884 /* Sources */, - 5E36905D1B2A23800040F884 /* Frameworks */, - 5E36905E1B2A23800040F884 /* Resources */, - 4C7D815378D98AB3BFC1A7D5 /* Copy Pods Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = HelloWorld; - productName = HelloWorld; - productReference = 5E3690601B2A23800040F884 /* HelloWorld.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 5E3690581B2A23800040F884 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0620; - ORGANIZATIONNAME = Google; - TargetAttributes = { - 5E36905F1B2A23800040F884 = { - CreatedOnToolsVersion = 6.2; - }; - }; - }; - buildConfigurationList = 5E36905B1B2A23800040F884 /* Build configuration list for PBXProject "HelloWorld" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 5E3690571B2A23800040F884; - productRefGroup = 5E3690611B2A23800040F884 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 5E36905F1B2A23800040F884 /* HelloWorld */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 5E36905E1B2A23800040F884 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5E36906F1B2A23800040F884 /* Main.storyboard in Resources */, - 5E3690711B2A23800040F884 /* Images.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 4C7D815378D98AB3BFC1A7D5 /* Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - ACF9162361FB8F24C70657DE /* Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Check Pods Manifest.lock"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 5E36905C1B2A23800040F884 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5E36906C1B2A23800040F884 /* ViewController.m in Sources */, - 5E3690691B2A23800040F884 /* AppDelegate.m in Sources */, - 5E3690661B2A23800040F884 /* main.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 5E36906D1B2A23800040F884 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 5E36906E1B2A23800040F884 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 5E3690811B2A23810040F884 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.2; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 5E3690821B2A23810040F884 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.2; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 5E3690841B2A23810040F884 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = HelloWorld/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 5E3690851B2A23810040F884 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = HelloWorld/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 5E36905B1B2A23800040F884 /* Build configuration list for PBXProject "HelloWorld" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5E3690811B2A23810040F884 /* Debug */, - 5E3690821B2A23810040F884 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5E3690831B2A23810040F884 /* Build configuration list for PBXNativeTarget "HelloWorld" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5E3690841B2A23810040F884 /* Debug */, - 5E3690851B2A23810040F884 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 5E3690581B2A23800040F884 /* Project object */; -} diff --git a/grpc-common/objective-c/helloworld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/grpc-common/objective-c/helloworld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 174a04ecb8..0000000000 --- a/grpc-common/objective-c/helloworld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/grpc-common/objective-c/helloworld/HelloWorld/AppDelegate.h b/grpc-common/objective-c/helloworld/HelloWorld/AppDelegate.h deleted file mode 100644 index 102e7f3ade..0000000000 --- a/grpc-common/objective-c/helloworld/HelloWorld/AppDelegate.h +++ /dev/null @@ -1,38 +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. - * - */ - -#import - -@interface AppDelegate : UIResponder -@property (strong, nonatomic) UIWindow *window; -@end diff --git a/grpc-common/objective-c/helloworld/HelloWorld/AppDelegate.m b/grpc-common/objective-c/helloworld/HelloWorld/AppDelegate.m deleted file mode 100644 index a38e36651e..0000000000 --- a/grpc-common/objective-c/helloworld/HelloWorld/AppDelegate.m +++ /dev/null @@ -1,37 +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. - * - */ - -#import "AppDelegate.h" - -@implementation AppDelegate -@end diff --git a/grpc-common/objective-c/helloworld/HelloWorld/Base.lproj/Main.storyboard b/grpc-common/objective-c/helloworld/HelloWorld/Base.lproj/Main.storyboard deleted file mode 100644 index f56d2f3bb5..0000000000 --- a/grpc-common/objective-c/helloworld/HelloWorld/Base.lproj/Main.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/grpc-common/objective-c/helloworld/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json b/grpc-common/objective-c/helloworld/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 36d2c80d88..0000000000 --- a/grpc-common/objective-c/helloworld/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/grpc-common/objective-c/helloworld/HelloWorld/Info.plist b/grpc-common/objective-c/helloworld/HelloWorld/Info.plist deleted file mode 100644 index 1078fff723..0000000000 --- a/grpc-common/objective-c/helloworld/HelloWorld/Info.plist +++ /dev/null @@ -1,47 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - Google.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - Main - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/grpc-common/objective-c/helloworld/HelloWorld/ViewController.m b/grpc-common/objective-c/helloworld/HelloWorld/ViewController.m deleted file mode 100644 index 090fd93689..0000000000 --- a/grpc-common/objective-c/helloworld/HelloWorld/ViewController.m +++ /dev/null @@ -1,40 +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. - * - */ - -#import - -@interface ViewController : UIViewController -@end - -@implementation ViewController -@end diff --git a/grpc-common/objective-c/helloworld/Podfile b/grpc-common/objective-c/helloworld/Podfile deleted file mode 100644 index 2934ebc2c8..0000000000 --- a/grpc-common/objective-c/helloworld/Podfile +++ /dev/null @@ -1,7 +0,0 @@ -source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '8.0' - -target 'HelloWorld' do - # Depend on the generated HelloWorld library. - pod 'HelloWorld', :path => '.' -end diff --git a/grpc-common/objective-c/helloworld/README.md b/grpc-common/objective-c/helloworld/README.md deleted file mode 100644 index 685339e84a..0000000000 --- a/grpc-common/objective-c/helloworld/README.md +++ /dev/null @@ -1,56 +0,0 @@ -#gRPC in 3 minutes (Objective-C) - -## Installation - -To run this example you should have [Cocoapods](https://cocoapods.org/#install) installed, as well -as the relevant tools to generate the client library code (and a server in another language, for -testing). You can obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). - -## Hello Objective-C gRPC! - -Here's how to build and run the Objective-C implementation of the [Hello World](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto) -example used in [Getting started](https://github.com/grpc/grpc-common). - -The example code for this and our other examples lives in the `grpc-common` GitHub repository. Clone -this repository to your local machine by running the following command: - - -```sh -$ git clone https://github.com/grpc/grpc-common.git -``` - -Change your current directory to `grpc-common/objective-c/helloworld` - -```sh -$ cd grpc-common/objective-c/helloworld -``` - -### Try it! -To try the sample app, we need a gRPC server running locally. Let's compile and run, for example, -the C++ server in this repository: - -```shell -$ pushd ../../cpp/helloworld -$ make -$ ./greeter_server & -$ popd -``` - -Now have Cocoapods generate and install the client library for our .proto files: - -```shell -$ pod install -``` - -(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet -on your computer's cache.) - -Finally, open the XCode workspace created by Cocoapods, and run the app. You can check the calling -code in `main.m` and see the results in XCode's log console. - -The code sends a `HLWHelloRequest` containing the string "Objective-C" to a local server. The server -responds with a `HLWHelloResponse`, which contains a string that is then output to the log. - -## Tutorial - -You can find a more detailed tutorial in [gRPC Basics: Objective-C](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/README.md). diff --git a/grpc-common/objective-c/helloworld/main.m b/grpc-common/objective-c/helloworld/main.m deleted file mode 100644 index 458580be30..0000000000 --- a/grpc-common/objective-c/helloworld/main.m +++ /dev/null @@ -1,51 +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. - * - */ - -#import -#import "AppDelegate.h" - -#import - -static NSString * const kHostAddress = @"http://localhost:50051"; - -int main(int argc, char * argv[]) { - @autoreleasepool { - HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress]; - HLWHelloRequest *request = [HLWHelloRequest message]; - request.name = @"Objective-C"; - [client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { - NSLog(@"%@", response.message); - }]; - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/grpc-common/objective-c/route_guide/Misc/AppDelegate.h b/grpc-common/objective-c/route_guide/Misc/AppDelegate.h deleted file mode 100644 index 102e7f3ade..0000000000 --- a/grpc-common/objective-c/route_guide/Misc/AppDelegate.h +++ /dev/null @@ -1,38 +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. - * - */ - -#import - -@interface AppDelegate : UIResponder -@property (strong, nonatomic) UIWindow *window; -@end diff --git a/grpc-common/objective-c/route_guide/Misc/AppDelegate.m b/grpc-common/objective-c/route_guide/Misc/AppDelegate.m deleted file mode 100644 index a38e36651e..0000000000 --- a/grpc-common/objective-c/route_guide/Misc/AppDelegate.m +++ /dev/null @@ -1,37 +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. - * - */ - -#import "AppDelegate.h" - -@implementation AppDelegate -@end diff --git a/grpc-common/objective-c/route_guide/Misc/Base.lproj/Main.storyboard b/grpc-common/objective-c/route_guide/Misc/Base.lproj/Main.storyboard deleted file mode 100644 index 9bf9498d62..0000000000 --- a/grpc-common/objective-c/route_guide/Misc/Base.lproj/Main.storyboard +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/grpc-common/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json b/grpc-common/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 36d2c80d88..0000000000 --- a/grpc-common/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/grpc-common/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json b/grpc-common/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json deleted file mode 100644 index 33a745102c..0000000000 --- a/grpc-common/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "first.pdf" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/grpc-common/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf b/grpc-common/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf deleted file mode 100644 index 47d911dea6..0000000000 Binary files a/grpc-common/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf and /dev/null differ diff --git a/grpc-common/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json b/grpc-common/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json deleted file mode 100644 index 03bd9c927f..0000000000 --- a/grpc-common/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "second.pdf" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/grpc-common/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf b/grpc-common/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf deleted file mode 100644 index 401614e288..0000000000 Binary files a/grpc-common/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf and /dev/null differ diff --git a/grpc-common/objective-c/route_guide/Misc/Info.plist b/grpc-common/objective-c/route_guide/Misc/Info.plist deleted file mode 100644 index 33ad4800f6..0000000000 --- a/grpc-common/objective-c/route_guide/Misc/Info.plist +++ /dev/null @@ -1,57 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - gRPC.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - Main - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarTintParameters - - UINavigationBar - - Style - UIBarStyleDefault - Translucent - - - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/grpc-common/objective-c/route_guide/Misc/main.m b/grpc-common/objective-c/route_guide/Misc/main.m deleted file mode 100644 index fb701005d1..0000000000 --- a/grpc-common/objective-c/route_guide/Misc/main.m +++ /dev/null @@ -1,41 +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. - * - */ - -#import -#import "AppDelegate.h" - -int main(int argc, char * argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/grpc-common/objective-c/route_guide/Podfile b/grpc-common/objective-c/route_guide/Podfile deleted file mode 100644 index a97f414685..0000000000 --- a/grpc-common/objective-c/route_guide/Podfile +++ /dev/null @@ -1,7 +0,0 @@ -source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '8.0' - -target 'RouteGuideClient' do - # Depend on the generated RouteGuide library. - pod 'RouteGuide', :path => '.' -end diff --git a/grpc-common/objective-c/route_guide/README.md b/grpc-common/objective-c/route_guide/README.md deleted file mode 100644 index bbbd9e020d..0000000000 --- a/grpc-common/objective-c/route_guide/README.md +++ /dev/null @@ -1,360 +0,0 @@ -#gRPC Basics: Objective-C - -This tutorial provides a basic Objective-C programmer's introduction to working with gRPC. By -walking through this example you'll learn how to: - -- Define a service in a .proto file. -- Generate client code using the protocol buffer compiler. -- Use the Objective-C gRPC API to write a simple client for your service. - -It assumes a passing familiarity with [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). -Note that the example in this tutorial uses the proto3 version of the protocol buffers language, -which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) -and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the -protocol buffers Github repository. - -This isn't a comprehensive guide to using gRPC in Objective-C: more reference documentation is -coming soon. - -- [Why use gRPC?](#why-grpc) -- [Example code and setup](#setup) -- [Try it out!](#try) -- [Defining the service](#proto) -- [Generating client code](#protoc) -- [Creating the client](#client) - - -## Why use gRPC? - -With gRPC you can define your service once in a .proto file and implement clients and servers in any -of gRPC's supported languages, which in turn can be run in environments ranging from servers inside -Google to your own tablet - all the complexity of communication between different languages and -environments is handled for you by gRPC. You also get all the advantages of working with protocol -buffers, including efficient serialization, a simple IDL, and easy interface updating. - -gRPC and proto3 are specially suited for mobile clients: gRPC is implemented on top of HTTP/2, which -results in network bandwidth savings over using HTTP/1.1. Serialization and parsing of the proto -binary format is more efficient than the equivalent JSON, resulting in CPU and battery savings. And -proto3 uses a runtime that has been optimized over the years at Google to keep code size to a -minimum. The latter is important in Objective-C, because the ability of the compiler to strip unused -code is limited by the dynamic nature of the language. - - - -## Example code and setup - -The example code for our tutorial is in [grpc/grpc-common/objective-c/route_guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide). -To download the example, clone the `grpc-common` repository by running the following command: -```shell -$ git clone https://github.com/grpc/grpc-common.git -``` - -Then change your current directory to `grpc-common/objective-c/route_guide`: -```shell -$ cd grpc-common/objective-c/route_guide -``` - -Our example is a simple route mapping application that lets clients get information about features -on their route, create a summary of their route, and exchange route information such as traffic -updates with the server and other clients. - -You also should have [Cocoapods](https://cocoapods.org/#install) installed, as well as the relevant -tools to generate the client library code (and a server in another language, for testing). You can -obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). - - - -## Try it out! - -To try the sample app, we need a gRPC server running locally. Let's compile and run, for example, -the C++ server in this repository: - -```shell -$ pushd ../../cpp/route_guide -$ make -$ ./route_guide_server & -$ popd -``` - -Now have Cocoapods generate and install the client library for our .proto files: - -```shell -$ pod install -``` - -(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet -on your computer's cache). - -Finally, open the XCode workspace created by Cocoapods, and run the app. You can check the calling -code in `ViewControllers.m` and see the results in XCode's log console. - -The next sections guide you step-by-step through how this proto service is defined, how to generate -a client library from it, and how to create an app that uses that library. - - - -## Defining the service - -First let's look at how the service we're using is defined. A gRPC *service* and its method -*request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). -You can see the complete .proto file for our example in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). - -To define a service, you specify a named `service` in your .proto file: - -```protobuf -service RouteGuide { - ... -} -``` - -Then you define `rpc` methods inside your service definition, specifying their request and response -types. Protocol buffers let you define four kinds of service method, all of which are used in the -`RouteGuide` service: - -- A *simple RPC* where the client sends a request to the server and receives a response later, just -like a normal remote procedure call. -```protobuf - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} -``` - -- A *response-streaming RPC* where the client sends a request to the server and gets back a stream -of response messages. You specify a response-streaming method by placing the `stream` keyword before -the *response* type. -```protobuf - // 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 *request-streaming RPC* where the client sends a sequence of messages to the server. Once the -client has finished writing the messages, it waits for the server to read them all and return its -response. You specify a request-streaming method by placing the `stream` keyword before the -*request* type. -```protobuf - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} -``` - -- A *bidirectional streaming RPC* where both sides send a sequence of messages to the other. The two -streams operate independently, so clients and servers can read and write in whatever order they -like: for example, the server could wait to receive all the client messages before writing its -responses, or it could alternately read a message then write a message, or some other combination of -reads and writes. The order of messages in each stream is preserved. You specify this type of method -by placing the `stream` keyword before both the request and the response. -```protobuf - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -``` - -Our .proto file also contains protocol buffer message type definitions for all the request and -response types used in our service methods - for example, here's the `Point` message type: -```protobuf -// 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; -} -``` - -You can specify a prefix to be used for your generated classes by adding the `objc_class_prefix` -option at the top of the file. For example: -```protobuf -option objc_class_prefix = "RTG"; -``` - - - -## Generating client code - -Next we need to generate the gRPC client interfaces from our .proto service definition. We do this -using the protocol buffer compiler (`protoc`) with a special gRPC Objective-C plugin. - -For simplicity, we've provided a [Podspec file](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/RouteGuide.podspec) -that runs `protoc` for you with the appropriate plugin, input, and output, and describes how to -compile the generated files. You just need to run in this directory (`grpc-common/objective-c/route_guide`): - -```shell -$ pod install -``` - -which, before installing the generated library in the XCode project of this sample, runs: - -```shell -$ protoc -I ../../protos --objc_out=Pods/RouteGuide --objcgrpc_out=Pods/RouteGuide ../../protos/route_guide.proto -``` - -Running this command generates the following files under `Pods/RouteGuide/`: -- `RouteGuide.pbobjc.h`, the header which declares your generated message classes. -- `RouteGuide.pbobjc.m`, which contains the implementation of your message classes. -- `RouteGuide.pbrpc.h`, the header which declares your generated service classes. -- `RouteGuide.pbrpc.m`, which contains the implementation of your service classes. - -These contain: -- All the protocol buffer code to populate, serialize, and retrieve our request and response message -types. -- A class called `RTGRouteGuide` that lets clients call the methods defined in the `RouteGuide` -service. - -You can also use the provided Podspec file to generate client code from any other proto service -definition; just replace the name (matching the file name), version, and other metadata. - - - -## Creating the client - -In this section, we'll look at creating an Objective-C client for our `RouteGuide` service. You can -see our complete example client code in [grpc-common/objective-c/route_guide/ViewControllers.m](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/ViewControllers.m). -(Note: In your apps, for maintainability and readability reasons, you shouldn't put all of your view -controllers in a single file; it's done here only to simplify the learning process). - -### Constructing a client object - -To call service methods, we first need to create a client object, an instance of the generated -`RTGRouteGuide` class. The designated initializer of the class expects a `NSString *` with the -server address and port we want to connect to: - -```objective-c -#import - -static NSString * const kHostAddress = @"http://localhost:50051"; - -... - -RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; -``` - -Notice that we've specified the HTTP scheme in the host address. This is because the server we will -be using to test our client doesn't use [TLS](http://en.wikipedia.org/wiki/Transport_Layer_Security). -This is fine because it will be running locally on our development machine. The most common case, -though, is connecting with a gRPC server on the internet, running gRPC over TLS. For that case, the -HTTPS scheme can be specified (or no scheme at all, as HTTPS is the default value). The default -value of the port is that of the scheme selected: 443 for HTTPS and 80 for HTTP. - - -### Calling service methods - -Now let's look at how we call our service methods. As you will see, all these methods are -asynchronous, so you can call them from the main thread of your app without worrying about freezing -your UI or the OS killing your app. - -#### Simple RPC - -Calling the simple RPC `GetFeature` is nearly as straightforward as calling any other asynchronous -method on Cocoa. - -```objective-c -RTGPoint *point = [RTGPoint message]; -point.latitude = 40E7; -point.longitude = -74E7; - -[client getFeatureWithRequest:point handler:^(RTGFeature *response, NSError *error) { - if (response) { - // Successful response received - } else { - // RPC error - } -}]; -``` - -As you can see, we create and populate a request protocol buffer object (in our case `RTGPoint`). -Then, we call the method on the client object, passing it the request, and a block to handle the -response (or any RPC error). If the RPC finishes successfully, the handler block is called with a -`nil` error argument, and we can read the response information from the server from the response -argument. If, instead, some RPC error happens, the handler block is called with a `nil` response -argument, and we can read the details of the problem from the error argument. - -```objective-c -NSLog(@"Found feature called %@ at %@.", response.name, response.location); -``` - -#### Streaming RPCs - -Now let's look at our streaming methods. Here's where we call the response-streaming method -`ListFeatures`, which results in our client receiving a stream of geographical `RTGFeature`s: - -```objective-c -[client listFeaturesWithRequest:rectangle - eventHandler:^(BOOL done, RTGFeature *response, NSError *error) { - if (response) { - // Element of the stream of responses received - } else if (error) { - // RPC error; the stream is over. - } - if (done) { - // The stream is over (all the responses were received, or an error occured). Do any cleanup. - } -}]; -``` - -Notice how the signature of the `eventHandler` block now includes a `BOOL done` parameter. The -`eventHandler` block can be called any number of times; only on the last call is the `done` argument -value set to `YES`. If an error occurs, the RPC finishes and the block is called with the arguments -`(YES, nil, error)`. - -The request-streaming method `RecordRoute` expects a stream of `RTGPoint`s from the cient. This -stream is passed to the method as an object of class `GRXWriter`. The simplest way to create one is -to initialize one from a `NSArray` object: - - -```objective-c -#import - -... - -RTGPoint *point1 = [RTGPoint message]; -point.latitude = 40E7; -point.longitude = -74E7; - -RTGPoint *point2 = [RTGPoint message]; -point.latitude = 40E7; -point.longitude = -74E7; - -GRXWriter *locationsWriter = [GRXWriter writerWithContainer:@[point1, point2]]; - -[client recordRouteWithRequestsWriter:locationsWriter - handler:^(RTGRouteSummary *response, NSError *error) { - if (response) { - NSLog(@"Finished trip with %i points", response.pointCount); - NSLog(@"Passed %i features", response.featureCount); - NSLog(@"Travelled %i meters", response.distance); - NSLog(@"It took %i seconds", response.elapsedTime); - } else { - NSLog(@"RPC error: %@", error); - } -}]; - -``` - -The `GRXWriter` class is generic enough to allow for asynchronous streams, streams of future values, -or even infinite streams. - -Finally, let's look at our bidirectional streaming RPC `RouteChat()`. The way to call a -bidirectional streaming RPC is just a combination of how to call request-streaming RPCs and -response-streaming RPCs. - -```objective-c -[client routeChatWithRequestsWriter:notesWriter - eventHandler:^(BOOL done, RTGRouteNote *note, NSError *error) { - if (note) { - NSLog(@"Got message %@ at %@", note.message, note.location); - } else if (error) { - NSLog(@"RPC error: %@", error); - } - if (done) { - NSLog(@"Chat ended."); - } -}]; -``` - -The semantics for the handler block and the `GRXWriter` argument here are exactly the same as for -our request-streaming and response-streaming methods. Although both client and server will always -get the other's messages in the order they were written, the two streams operate completely -independently. diff --git a/grpc-common/objective-c/route_guide/RouteGuide.podspec b/grpc-common/objective-c/route_guide/RouteGuide.podspec deleted file mode 100644 index 7b99a6c6a7..0000000000 --- a/grpc-common/objective-c/route_guide/RouteGuide.podspec +++ /dev/null @@ -1,35 +0,0 @@ -Pod::Spec.new do |s| - s.name = "RouteGuide" - s.version = "0.0.1" - s.license = "New BSD" - - s.ios.deployment_target = "6.0" - s.osx.deployment_target = "10.8" - - # Base directory where the .proto files are. - src = "../../protos" - - # Directory where the generated files will be place. - dir = "Pods/" + s.name - - # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.prepare_command = <<-CMD - mkdir -p #{dir} - protoc -I #{src} --objc_out=#{dir} --objcgrpc_out=#{dir} #{src}/route_guide.proto - CMD - - s.subspec "Messages" do |ms| - ms.source_files = "#{dir}/*.pbobjc.{h,m}", "#{dir}/**/*.pbobjc.{h,m}" - ms.header_mappings_dir = dir - ms.requires_arc = false - ms.dependency "Protobuf", "~> 3.0.0-alpha-3" - end - - s.subspec "Services" do |ss| - ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}" - ss.header_mappings_dir = dir - ss.requires_arc = true - ss.dependency "gRPC", "~> 0.6" - ss.dependency "#{s.name}/Messages" - end -end diff --git a/grpc-common/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj b/grpc-common/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj deleted file mode 100644 index 6ab6b27a1b..0000000000 --- a/grpc-common/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj +++ /dev/null @@ -1,366 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 124E20A2FC8EAE54460D4ED2 /* libPods-RouteGuideClient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 71CEE03D66D40FC37264D6E4 /* libPods-RouteGuideClient.a */; }; - 632527831B1D0396003073D9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 632527821B1D0396003073D9 /* main.m */; }; - 632527861B1D0396003073D9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 632527851B1D0396003073D9 /* AppDelegate.m */; }; - 6325278F1B1D0396003073D9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6325278D1B1D0396003073D9 /* Main.storyboard */; }; - 632527911B1D0396003073D9 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 632527901B1D0396003073D9 /* Images.xcassets */; }; - 6367B55B1B223AFA008861F5 /* route_guide_db.json in Resources */ = {isa = PBXBuildFile; fileRef = 6367B55A1B223AFA008861F5 /* route_guide_db.json */; }; - 63A6015C1B1DAB5000FA5B86 /* ViewControllers.m in Sources */ = {isa = PBXBuildFile; fileRef = 63A6015B1B1DAB5000FA5B86 /* ViewControllers.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 6325277D1B1D0396003073D9 /* RouteGuideClient.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RouteGuideClient.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 632527811B1D0396003073D9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 632527821B1D0396003073D9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 632527841B1D0396003073D9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 632527851B1D0396003073D9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6325278E1B1D0396003073D9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 632527901B1D0396003073D9 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6367B55A1B223AFA008861F5 /* route_guide_db.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = route_guide_db.json; sourceTree = ""; }; - 63A6015B1B1DAB5000FA5B86 /* ViewControllers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewControllers.m; sourceTree = ""; }; - 71CEE03D66D40FC37264D6E4 /* libPods-RouteGuideClient.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RouteGuideClient.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - ADA4C647BAE906F79AD9A45E /* Pods-RouteGuideClient.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RouteGuideClient.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RouteGuideClient/Pods-RouteGuideClient.debug.xcconfig"; sourceTree = ""; }; - C83C5A54D1A4EA07569F1AED /* Pods-RouteGuideClient.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RouteGuideClient.release.xcconfig"; path = "Pods/Target Support Files/Pods-RouteGuideClient/Pods-RouteGuideClient.release.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6325277A1B1D0395003073D9 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 124E20A2FC8EAE54460D4ED2 /* libPods-RouteGuideClient.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 56849C29DC376BF4B902CD77 /* Pods */ = { - isa = PBXGroup; - children = ( - ADA4C647BAE906F79AD9A45E /* Pods-RouteGuideClient.debug.xcconfig */, - C83C5A54D1A4EA07569F1AED /* Pods-RouteGuideClient.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; - 631C63891B1DBC41001295D5 /* Misc */ = { - isa = PBXGroup; - children = ( - 632527841B1D0396003073D9 /* AppDelegate.h */, - 632527851B1D0396003073D9 /* AppDelegate.m */, - 632527901B1D0396003073D9 /* Images.xcassets */, - 632527801B1D0396003073D9 /* Supporting Files */, - ); - path = Misc; - sourceTree = ""; - }; - 632527741B1D0395003073D9 = { - isa = PBXGroup; - children = ( - 6325277F1B1D0396003073D9 /* RouteGuideClient */, - 6325277E1B1D0396003073D9 /* Products */, - 56849C29DC376BF4B902CD77 /* Pods */, - 7482B8A18481F7B13ADE4530 /* Frameworks */, - ); - sourceTree = ""; - }; - 6325277E1B1D0396003073D9 /* Products */ = { - isa = PBXGroup; - children = ( - 6325277D1B1D0396003073D9 /* RouteGuideClient.app */, - ); - name = Products; - sourceTree = ""; - }; - 6325277F1B1D0396003073D9 /* RouteGuideClient */ = { - isa = PBXGroup; - children = ( - 63A6015B1B1DAB5000FA5B86 /* ViewControllers.m */, - 6367B55A1B223AFA008861F5 /* route_guide_db.json */, - 6325278D1B1D0396003073D9 /* Main.storyboard */, - 631C63891B1DBC41001295D5 /* Misc */, - ); - name = RouteGuideClient; - sourceTree = SOURCE_ROOT; - }; - 632527801B1D0396003073D9 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 632527811B1D0396003073D9 /* Info.plist */, - 632527821B1D0396003073D9 /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 7482B8A18481F7B13ADE4530 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 71CEE03D66D40FC37264D6E4 /* libPods-RouteGuideClient.a */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6325277C1B1D0395003073D9 /* RouteGuideClient */ = { - isa = PBXNativeTarget; - buildConfigurationList = 632527A31B1D0396003073D9 /* Build configuration list for PBXNativeTarget "RouteGuideClient" */; - buildPhases = ( - C6FC30AD2376EC04317237C5 /* Check Pods Manifest.lock */, - 632527791B1D0395003073D9 /* Sources */, - 6325277A1B1D0395003073D9 /* Frameworks */, - 6325277B1B1D0395003073D9 /* Resources */, - FFE0BCF30339E7A50A989EAB /* Copy Pods Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = RouteGuideClient; - productName = RouteGuideClient; - productReference = 6325277D1B1D0396003073D9 /* RouteGuideClient.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 632527751B1D0395003073D9 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = gRPC; - TargetAttributes = { - 6325277C1B1D0395003073D9 = { - CreatedOnToolsVersion = 6.3.1; - }; - }; - }; - buildConfigurationList = 632527781B1D0395003073D9 /* Build configuration list for PBXProject "RouteGuideClient" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 632527741B1D0395003073D9; - productRefGroup = 6325277E1B1D0396003073D9 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6325277C1B1D0395003073D9 /* RouteGuideClient */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6325277B1B1D0395003073D9 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6325278F1B1D0396003073D9 /* Main.storyboard in Resources */, - 632527911B1D0396003073D9 /* Images.xcassets in Resources */, - 6367B55B1B223AFA008861F5 /* route_guide_db.json in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - C6FC30AD2376EC04317237C5 /* Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Check Pods Manifest.lock"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; - showEnvVarsInLog = 0; - }; - FFE0BCF30339E7A50A989EAB /* Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RouteGuideClient/Pods-RouteGuideClient-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 632527791B1D0395003073D9 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 632527861B1D0396003073D9 /* AppDelegate.m in Sources */, - 632527831B1D0396003073D9 /* main.m in Sources */, - 63A6015C1B1DAB5000FA5B86 /* ViewControllers.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6325278D1B1D0396003073D9 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6325278E1B1D0396003073D9 /* Base */, - ); - name = Main.storyboard; - path = Misc; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 632527A11B1D0396003073D9 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 632527A21B1D0396003073D9 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 632527A41B1D0396003073D9 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = ADA4C647BAE906F79AD9A45E /* Pods-RouteGuideClient.debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = Misc/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 632527A51B1D0396003073D9 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = C83C5A54D1A4EA07569F1AED /* Pods-RouteGuideClient.release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = Misc/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 632527781B1D0395003073D9 /* Build configuration list for PBXProject "RouteGuideClient" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 632527A11B1D0396003073D9 /* Debug */, - 632527A21B1D0396003073D9 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 632527A31B1D0396003073D9 /* Build configuration list for PBXNativeTarget "RouteGuideClient" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 632527A41B1D0396003073D9 /* Debug */, - 632527A51B1D0396003073D9 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 632527751B1D0395003073D9 /* Project object */; -} diff --git a/grpc-common/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/grpc-common/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index f208589e44..0000000000 --- a/grpc-common/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/grpc-common/objective-c/route_guide/ViewControllers.m b/grpc-common/objective-c/route_guide/ViewControllers.m deleted file mode 100644 index cfc3338bca..0000000000 --- a/grpc-common/objective-c/route_guide/ViewControllers.m +++ /dev/null @@ -1,228 +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. - * - */ - -#import -#import -#import -#import - -static NSString * const kHostAddress = @"http://localhost:50051"; - -// Category to override RTGPoint's description. -@interface RTGPoint (Description) -- (NSString *)description; -@end - -@implementation RTGPoint (Description) -- (NSString *)description { - NSString *verticalDirection = self.latitude >= 0 ? @"N" : @"S"; - NSString *horizontalDirection = self.longitude >= 0 ? @"E" : @"W"; - return [NSString stringWithFormat:@"%.02f%@ %.02f%@", - abs(self.latitude) / 1E7f, verticalDirection, - abs(self.longitude) / 1E7f, horizontalDirection]; -} -@end - -// Category to give RTGRouteNote a convenience constructor. -@interface RTGRouteNote (Constructors) -+ (instancetype)noteWithMessage:(NSString *)message - latitude:(float)latitude - longitude:(float)longitude; -@end - -@implementation RTGRouteNote (Constructors) -+ (instancetype)noteWithMessage:(NSString *)message - latitude:(float)latitude - longitude:(float)longitude { - RTGRouteNote *note = [self message]; - note.message = message; - note.location.latitude = (int32_t) latitude * 1E7; - note.location.longitude = (int32_t) longitude * 1E7; - return note; -} -@end - - -#pragma mark Demo: Get Feature - -// Run the getFeature demo. Calls getFeature with a point known to have a feature and a point known -// not to have a feature. - -@interface GetFeatureViewController : UIViewController -@end - -@implementation GetFeatureViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; - - void (^handler)(RTGFeature *response, NSError *error) = ^(RTGFeature *response, NSError *error) { - if (response.name.length) { - NSLog(@"Found feature called %@ at %@.", response.name, response.location); - } else if (response) { - NSLog(@"Found no features at %@", response.location); - } else { - NSLog(@"RPC error: %@", error); - } - }; - - RTGPoint *point = [RTGPoint message]; - point.latitude = 409146138; - point.longitude = -746188906; - - [client getFeatureWithRequest:point handler:handler]; - [client getFeatureWithRequest:[RTGPoint message] handler:handler]; -} - -@end - - -#pragma mark Demo: List Features - -// Run the listFeatures demo. Calls listFeatures with a rectangle containing all of the features in -// the pre-generated database. Prints each response as it comes in. - -@interface ListFeaturesViewController : UIViewController -@end - -@implementation ListFeaturesViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; - - RTGRectangle *rectangle = [RTGRectangle message]; - rectangle.lo.latitude = 405E6; - rectangle.lo.longitude = -750E6; - rectangle.hi.latitude = 410E6; - rectangle.hi.longitude = -745E6; - - NSLog(@"Looking for features between %@ and %@", rectangle.lo, rectangle.hi); - [client listFeaturesWithRequest:rectangle - eventHandler:^(BOOL done, RTGFeature *response, NSError *error) { - if (response) { - NSLog(@"Found feature at %@ called %@.", response.location, response.name); - } else if (error) { - NSLog(@"RPC error: %@", error); - } - }]; -} - -@end - - -#pragma mark Demo: Record Route - -// Run the recordRoute demo. Sends several randomly chosen points from the pre-generated feature -// database with a variable delay in between. Prints the statistics when they are sent from the -// server. - -@interface RecordRouteViewController : UIViewController -@end - -@implementation RecordRouteViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - NSString *dataBasePath = [NSBundle.mainBundle pathForResource:@"route_guide_db" - ofType:@"json"]; - NSData *dataBaseContent = [NSData dataWithContentsOfFile:dataBasePath]; - NSArray *features = [NSJSONSerialization JSONObjectWithData:dataBaseContent options:0 error:NULL]; - - GRXWriter *locations = [[GRXWriter writerWithContainer:features] map:^id(id feature) { - RTGPoint *location = [RTGPoint message]; - location.longitude = [((NSNumber *) feature[@"location"][@"longitude"]) intValue]; - location.latitude = [((NSNumber *) feature[@"location"][@"latitude"]) intValue]; - NSLog(@"Visiting point %@", location); - return location; - }]; - - RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; - - [client recordRouteWithRequestsWriter:locations handler:^(RTGRouteSummary *response, NSError *error) { - if (response) { - NSLog(@"Finished trip with %i points", response.pointCount); - NSLog(@"Passed %i features", response.featureCount); - NSLog(@"Travelled %i meters", response.distance); - NSLog(@"It took %i seconds", response.elapsedTime); - } else { - NSLog(@"RPC error: %@", error); - } - }]; -} - -@end - - -#pragma mark Demo: Route Chat - -// Run the routeChat demo. Send some chat messages, and print any chat messages that are sent from -// the server. - -@interface RouteChatViewController : UIViewController -@end - -@implementation RouteChatViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - NSArray *notes = @[[RTGRouteNote noteWithMessage:@"First message" latitude:0 longitude:0], - [RTGRouteNote noteWithMessage:@"Second message" latitude:0 longitude:1], - [RTGRouteNote noteWithMessage:@"Third message" latitude:1 longitude:0], - [RTGRouteNote noteWithMessage:@"Fourth message" latitude:0 longitude:0]]; - GRXWriter *notesWriter = [[GRXWriter writerWithContainer:notes] map:^id(RTGRouteNote *note) { - NSLog(@"Sending message %@ at %@", note.message, note.location); - return note; - }]; - - RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; - - [client routeChatWithRequestsWriter:notesWriter - eventHandler:^(BOOL done, RTGRouteNote *note, NSError *error) { - if (note) { - NSLog(@"Got message %@ at %@", note.message, note.location); - } else if (error) { - NSLog(@"RPC error: %@", error); - } - if (done) { - NSLog(@"Chat ended."); - } - }]; -} - -@end diff --git a/grpc-common/objective-c/route_guide/route_guide_db.json b/grpc-common/objective-c/route_guide/route_guide_db.json deleted file mode 100644 index 9caebaa433..0000000000 --- a/grpc-common/objective-c/route_guide/route_guide_db.json +++ /dev/null @@ -1,121 +0,0 @@ -[{ - "location": { - "latitude": 407838351, - "longitude": -746143763 - }, - "name": "Patriots Path, Mendham, NJ 07945, USA" -}, { - "location": { - "latitude": 408122808, - "longitude": -743999179 - }, - "name": "101 New Jersey 10, Whippany, NJ 07981, USA" -}, { - "location": { - "latitude": 413628156, - "longitude": -749015468 - }, - "name": "U.S. 6, Shohola, PA 18458, USA" -}, { - "location": { - "latitude": 419999544, - "longitude": -740371136 - }, - "name": "5 Conners Road, Kingston, NY 12401, USA" -}, { - "location": { - "latitude": 414008389, - "longitude": -743951297 - }, - "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" -}, { - "location": { - "latitude": 419611318, - "longitude": -746524769 - }, - "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" -}, { - "location": { - "latitude": 406109563, - "longitude": -742186778 - }, - "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" -}, { - "location": { - "latitude": 416802456, - "longitude": -742370183 - }, - "name": "352 South Mountain Road, Wallkill, NY 12589, USA" -}, { - "location": { - "latitude": 412950425, - "longitude": -741077389 - }, - "name": "Bailey Turn Road, Harriman, NY 10926, USA" -}, { - "location": { - "latitude": 412144655, - "longitude": -743949739 - }, - "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" -}, { - "location": { - "latitude": 404306372, - "longitude": -741079661 - }, - "name": "" -}, { - "location": { - "latitude": 403966326, - "longitude": -748519297 - }, - "name": "" -}, { - "location": { - "latitude": 405002031, - "longitude": -748407866 - }, - "name": "" -}, { - "location": { - "latitude": 409532885, - "longitude": -742200683 - }, - "name": "" -}, { - "location": { - "latitude": 416851321, - "longitude": -742674555 - }, - "name": "" -}, { - "location": { - "latitude": 406411633, - "longitude": -741722051 - }, - "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" -}, { - "location": { - "latitude": 413069058, - "longitude": -744597778 - }, - "name": "261 Van Sickle Road, Goshen, NY 10924, USA" -}, { - "location": { - "latitude": 418465462, - "longitude": -746859398 - }, - "name": "" -}, { - "location": { - "latitude": 411733222, - "longitude": -744228360 - }, - "name": "" -}, { - "location": { - "latitude": 410248224, - "longitude": -747127767 - }, - "name": "3 Hasta Way, Newton, NJ 07860, USA" -}] diff --git a/grpc-common/php/.gitignore b/grpc-common/php/.gitignore deleted file mode 100644 index d8a7996ab3..0000000000 --- a/grpc-common/php/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -composer.lock -vendor/ diff --git a/grpc-common/php/README.md b/grpc-common/php/README.md deleted file mode 100644 index 247235adfd..0000000000 --- a/grpc-common/php/README.md +++ /dev/null @@ -1,64 +0,0 @@ -gRPC in 3 minutes (PHP) -=========================== - -PREREQUISITES -------------- - -This requires PHP 5.5 or greater. - -INSTALL -------- - - On Mac OS X, install [homebrew][]. On Linux, install [linuxbrew][]. Run the following command to install gRPC. - - ```sh - $ curl -fsSL https://goo.gl/getgrpc | bash -s php - ``` - This will download and run the [gRPC install script][] and compile the gRPC PHP extension. - - - Clone this repository - - ```sh - $ git clone https://github.com/grpc/grpc-common.git - ``` - - - Install composer - - ``` - $ cd grpc-common/php - $ curl -sS https://getcomposer.org/installer | php - $ php composer.phar install - ``` - -TRY IT! -------- - - - Run the server - - Please follow the instruction in [Node][] to run the server - ``` - $ cd grpc-common/node - $ nodejs greeter_server.js - ``` - - - Run the client - - ``` - $ cd grpc-common/php - $ ./run_greeter_client.sh - ``` - -NOTE ----- - -This directory has a copy of `helloworld.proto` because it currently depends on -some Protocol Buffer 2.0 syntax. There is no proto3 support for PHP yet. - -TUTORIAL --------- - -Coming soon - -[homebrew]:http://brew.sh -[linuxbrew]:https://github.com/Homebrew/linuxbrew#installation -[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install -[Node]:https://github.com/grpc/grpc-common/tree/master/node diff --git a/grpc-common/php/composer.json b/grpc-common/php/composer.json deleted file mode 100644 index f0ce3a2aff..0000000000 --- a/grpc-common/php/composer.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/stanley-cheung/Protobuf-PHP" - } - ], - "name": "grpc/grpc-demo", - "description": "gRPC example for PHP", - "minimum-stability": "dev", - "require": { - "php": ">=5.5.0", - "datto/protobuf-php": "dev-master", - "google/auth": "dev-master", - "grpc/grpc": "dev-master" - } -} diff --git a/grpc-common/php/greeter_client.php b/grpc-common/php/greeter_client.php deleted file mode 100644 index 8ae19ae46c..0000000000 --- a/grpc-common/php/greeter_client.php +++ /dev/null @@ -1,49 +0,0 @@ -setName($name); - list($reply, $status) = $client->SayHello($request)->wait(); - $message = $reply->getMessage(); - return $message; -} - -$name = !empty($argv[1]) ? $argv[1] : 'world'; -print(greet($name)."\n"); diff --git a/grpc-common/php/helloworld.php b/grpc-common/php/helloworld.php deleted file mode 100644 index 22da3d3970..0000000000 --- a/grpc-common/php/helloworld.php +++ /dev/null @@ -1,160 +0,0 @@ -number = 1; - $f->name = "name"; - $f->type = \DrSlump\Protobuf::TYPE_STRING; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasName(){ - return $this->_has(1); - } - - /** - * Clear value - * - * @return \helloworld\HelloRequest - */ - public function clearName(){ - return $this->_clear(1); - } - - /** - * Get value - * - * @return string - */ - public function getName(){ - return $this->_get(1); - } - - /** - * Set value - * - * @param string $value - * @return \helloworld\HelloRequest - */ - public function setName( $value){ - return $this->_set(1, $value); - } - } -} - -namespace helloworld { - - class HelloReply extends \DrSlump\Protobuf\Message { - - /** @var string */ - public $message = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloReply'); - - // OPTIONAL STRING message = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "message"; - $f->type = \DrSlump\Protobuf::TYPE_STRING; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasMessage(){ - return $this->_has(1); - } - - /** - * Clear value - * - * @return \helloworld\HelloReply - */ - public function clearMessage(){ - return $this->_clear(1); - } - - /** - * Get value - * - * @return string - */ - public function getMessage(){ - return $this->_get(1); - } - - /** - * Set value - * - * @param string $value - * @return \helloworld\HelloReply - */ - public function setMessage( $value){ - return $this->_set(1, $value); - } - } -} - -namespace helloworld { - - class GreeterClient{ - - private $rpc_impl; - - public function __construct($rpc_impl) { - $this->rpc_impl = $rpc_impl; - } - /** - * @param helloworld\HelloRequest $input - */ - public function SayHello(\helloworld\HelloRequest $argument, $metadata = array()) { - return $this->rpc_impl->_simpleRequest('/helloworld.Greeter/SayHello', $argument, '\helloworld\HelloReply::deserialize', $metadata); - } - } -} diff --git a/grpc-common/php/helloworld.proto b/grpc-common/php/helloworld.proto deleted file mode 100644 index ad8f7a1524..0000000000 --- a/grpc-common/php/helloworld.proto +++ /dev/null @@ -1,50 +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 = "proto2"; - -option java_package = "ex.grpc"; - -package helloworld; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - optional string name = 1; -} - -// The response message containing the greetings -message HelloReply { - optional string message = 1; -} diff --git a/grpc-common/php/route_guide/README.md b/grpc-common/php/route_guide/README.md deleted file mode 100644 index 084661a5eb..0000000000 --- a/grpc-common/php/route_guide/README.md +++ /dev/null @@ -1,262 +0,0 @@ -#gRPC Basics: PHP - -This tutorial provides a basic PHP programmer's introduction to working with gRPC. By walking through this example you'll learn how to: - -- Define a service in a .proto file. -- Generate client code using the protocol buffer compiler. -- Use the PHP gRPC API to write a simple client for your service. - -It assumes a passing familiarity with [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto2 version of the protocol buffers language. - -Also note that currently you can only create clients in PHP for gRPC services - you can find out how to create gRPC servers in our other tutorials, e.g. [Node.js](https://github.com/grpc/grpc-common/tree/master/node/route_guide). - -This isn't a comprehensive guide to using gRPC in PHP: more reference documentation is coming soon. - -- [Why use gRPC?](#why-grpc) -- [Example code and setup](#setup) -- [Try it out!](#try) -- [Defining the service](#proto) -- [Generating client code](#protoc) -- [Creating the client](#client) - - - -## Why use gRPC? - -With gRPC you can define your service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. You also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. - - - -## Example code and setup - -The example code for our tutorial is in [grpc/grpc-common/php/route_guide](https://github.com/grpc/grpc-common/tree/master/php/route_guide). To download the example, clone the `grpc-common` repository by running the following command: -```shell -$ git clone https://github.com/grpc/grpc-common.git -``` - -Then change your current directory to `grpc-common/php/route_guide`: -```shell -$ cd grpc-common/php/route_guide -``` - -Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. - -You also should have the relevant tools installed to generate the client interface code (and a server in another language, for testing). You can obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). - - - -## Try it out! - -To try the sample app, we need a gRPC server running locally. Let's compile and run, for example, the Node.js server in this repository: - -```shell -$ cd ../../node -$ npm install -$ cd route_guide -$ nodejs ./route_guide_server.js --db_path=route_guide_db.json -``` - -Run the PHP client (in a different terminal): - -```shell -$ ./run_route_guide_client.sh -``` - -The next sections guide you step-by-step through how this proto service is defined, how to generate a client library from it, and how to create a client stub that uses that library. - - - -## Defining the service - -First let's look at how the service we're using is defined. A gRPC *service* and its method *request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file for our example in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). - -To define a service, you specify a named `service` in your .proto file: - -```protobuf -service RouteGuide { - ... -} -``` - -Then you define `rpc` methods inside your service definition, specifying their request and response types. Protocol buffers let you define four kinds of service method, all of which are used in the `RouteGuide` service: - -- A *simple RPC* where the client sends a request to the server and receives a response later, just like a normal remote procedure call. -```protobuf - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} -``` - -- A *response-streaming RPC* where the client sends a request to the server and gets back a stream of response messages. You specify a response-streaming method by placing the `stream` keyword before the *response* type. -```protobuf - // 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 *request-streaming RPC* where the client sends a sequence of messages to the server. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a request-streaming method by placing the `stream` keyword before the *request* type. -```protobuf - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} -``` - -- A *bidirectional streaming RPC* where both sides send a sequence of messages to the other. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -```protobuf - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -``` - -Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -```protobuf -// 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; -} -``` - - - -## Generating client code - -The PHP client stub implementation of the proto files can be generated by the [`protoc-gen-php`](https://github.com/datto/protobuf-php) tool. To install the tool: - -```sh -$ cd grpc-common/php -$ php composer.phar install -$ cd vendor/datto/protobuf-php -$ gem install rake ronn -$ rake pear:package version=1.0 -$ sudo pear install Protobuf-1.0.tgz -``` - -To generate the client stub implementation .php file: - -```sh -$ cd php/route_guide -$ protoc-gen-php -i . -o . ./route_guide.proto -``` - -A `route_guide.php` file will be generated in the `php/route_guide` directory. You do not need to modify the file. - -To load the generated client stub file, simply `require` it in your PHP application: - -```php -require dirname(__FILE__) . '/route_guide.php'; -``` - -The file contains: -- All the protocol buffer code to populate, serialize, and retrieve our request and response message types. -- A class called `examples\RouteGuideClient` that lets clients call the methods defined in the `RouteGuide` service. - - - -## Creating the client - -In this section, we'll look at creating a PHP client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/php/route_guide/route_guide_client.php](https://github.com/grpc/grpc-common/blob/master/php/route_guide/route_guide_client.php). - -### Constructing a client object - -To call service methods, we first need to create a client object, an instance of the generated `RouteGuideClient` class. The constructor of the class expects the server address and port we want to connect to: - -```php -$client = new examples\RouteGuideClient(new Grpc\BaseStub('localhost:50051', [])); -``` - -### Calling service methods - -Now let's look at how we call our service methods. - -#### Simple RPC - -Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local asynchronous method. - -```php - $point = new examples\Point(); - $point->setLatitude(409146138); - $point->setLongitude(-746188906); - list($feature, $status) = $client->GetFeature($point)->wait(); -``` - -As you can see, we create and populate a request object, i.e. an `examples\Point` object. Then, we call the method on the stub, passing it the request object. If there is no error, then we can read the response information from the server from our response object, i.e. an `examples\Feature` object. - -```php - print sprintf("Found %s \n at %f, %f\n", $feature->getName(), - $feature->getLocation()->getLatitude() / COORD_FACTOR, - $feature->getLocation()->getLongitude() / COORD_FACTOR); -``` - -#### Streaming RPCs - -Now let's look at our streaming methods. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: - -```php - $lo_point = new examples\Point(); - $hi_point = new examples\Point(); - - $lo_point->setLatitude(400000000); - $lo_point->setLongitude(-750000000); - $hi_point->setLatitude(420000000); - $hi_point->setLongitude(-730000000); - - $rectangle = new examples\Rectangle(); - $rectangle->setLo($lo_point); - $rectangle->setHi($hi_point); - - $call = $client->ListFeatures($rectangle); - // an iterator over the server streaming responses - $features = $call->responses(); - foreach ($features as $feature) { - // process each feature - } // the loop will end when the server indicates there is no more responses to be sent. -``` - -The `$call->responses()` method call returns an iterator. When the server sends a response, a `$feature` object will be returned in the `foreach` loop, until the server indiciates that there will be no more responses to be sent. - -The client-side streaming method `RecordRoute` is similar, except there we pass the method an iterator and get back a `examples\RouteSummary`. - -```php - $points_iter = function($db) { - for ($i = 0; $i < $num_points; $i++) { - $point = new examples\Point(); - $point->setLatitude($lat); - $point->setLongitude($long); - yield $point; - } - }; - // $points_iter is an iterator simulating client streaming - list($route_summary, $status) = - $client->RecordRoute($points_iter($db))->wait(); -``` - -Finally, let's look at our bidirectional streaming RPC `routeChat()`. In this case, we just pass a context to the method and get back a `BidiStreamingCall` stream object, which we can use to both write and read messages. - -```php -$call = $client->RouteChat(); -``` - -To write messages from the client: - -```php - foreach ($notes as $n) { - $route_note = new examples\RouteNote(); - $call->write($route_note); - } - $call->writesDone(); -``` - -To read messages from the server: - -```php - while ($route_note_reply = $call->read()) { - // process $route_note_reply - } -``` - -Each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. diff --git a/grpc-common/php/route_guide/route_guide.php b/grpc-common/php/route_guide/route_guide.php deleted file mode 100644 index a836e03b55..0000000000 --- a/grpc-common/php/route_guide/route_guide.php +++ /dev/null @@ -1,731 +0,0 @@ -number = 1; - $f->name = "latitude"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->default = 0; - $descriptor->addField($f); - - // OPTIONAL INT32 longitude = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "longitude"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->default = 0; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasLatitude(){ - return $this->_has(1); - } - - /** - * Clear value - * - * @return \examples\Point - */ - public function clearLatitude(){ - return $this->_clear(1); - } - - /** - * Get value - * - * @return int - */ - public function getLatitude(){ - return $this->_get(1); - } - - /** - * Set value - * - * @param int $value - * @return \examples\Point - */ - public function setLatitude( $value){ - return $this->_set(1, $value); - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasLongitude(){ - return $this->_has(2); - } - - /** - * Clear value - * - * @return \examples\Point - */ - public function clearLongitude(){ - return $this->_clear(2); - } - - /** - * Get value - * - * @return int - */ - public function getLongitude(){ - return $this->_get(2); - } - - /** - * Set value - * - * @param int $value - * @return \examples\Point - */ - public function setLongitude( $value){ - return $this->_set(2, $value); - } - } -} - -namespace examples { - - class Rectangle extends \DrSlump\Protobuf\Message { - - /** @var \examples\Point */ - public $lo = null; - - /** @var \examples\Point */ - public $hi = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.Rectangle'); - - // OPTIONAL MESSAGE lo = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "lo"; - $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\examples\Point'; - $descriptor->addField($f); - - // OPTIONAL MESSAGE hi = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "hi"; - $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\examples\Point'; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasLo(){ - return $this->_has(1); - } - - /** - * Clear value - * - * @return \examples\Rectangle - */ - public function clearLo(){ - return $this->_clear(1); - } - - /** - * Get value - * - * @return \examples\Point - */ - public function getLo(){ - return $this->_get(1); - } - - /** - * Set value - * - * @param \examples\Point $value - * @return \examples\Rectangle - */ - public function setLo(\examples\Point $value){ - return $this->_set(1, $value); - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasHi(){ - return $this->_has(2); - } - - /** - * Clear value - * - * @return \examples\Rectangle - */ - public function clearHi(){ - return $this->_clear(2); - } - - /** - * Get value - * - * @return \examples\Point - */ - public function getHi(){ - return $this->_get(2); - } - - /** - * Set value - * - * @param \examples\Point $value - * @return \examples\Rectangle - */ - public function setHi(\examples\Point $value){ - return $this->_set(2, $value); - } - } -} - -namespace examples { - - class Feature extends \DrSlump\Protobuf\Message { - - /** @var string */ - public $name = null; - - /** @var \examples\Point */ - public $location = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.Feature'); - - // OPTIONAL STRING name = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "name"; - $f->type = \DrSlump\Protobuf::TYPE_STRING; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - // OPTIONAL MESSAGE location = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "location"; - $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\examples\Point'; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasName(){ - return $this->_has(1); - } - - /** - * Clear value - * - * @return \examples\Feature - */ - public function clearName(){ - return $this->_clear(1); - } - - /** - * Get value - * - * @return string - */ - public function getName(){ - return $this->_get(1); - } - - /** - * Set value - * - * @param string $value - * @return \examples\Feature - */ - public function setName( $value){ - return $this->_set(1, $value); - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasLocation(){ - return $this->_has(2); - } - - /** - * Clear value - * - * @return \examples\Feature - */ - public function clearLocation(){ - return $this->_clear(2); - } - - /** - * Get value - * - * @return \examples\Point - */ - public function getLocation(){ - return $this->_get(2); - } - - /** - * Set value - * - * @param \examples\Point $value - * @return \examples\Feature - */ - public function setLocation(\examples\Point $value){ - return $this->_set(2, $value); - } - } -} - -namespace examples { - - class RouteNote extends \DrSlump\Protobuf\Message { - - /** @var \examples\Point */ - public $location = null; - - /** @var string */ - public $message = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.RouteNote'); - - // OPTIONAL MESSAGE location = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "location"; - $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\examples\Point'; - $descriptor->addField($f); - - // OPTIONAL STRING message = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "message"; - $f->type = \DrSlump\Protobuf::TYPE_STRING; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasLocation(){ - return $this->_has(1); - } - - /** - * Clear value - * - * @return \examples\RouteNote - */ - public function clearLocation(){ - return $this->_clear(1); - } - - /** - * Get value - * - * @return \examples\Point - */ - public function getLocation(){ - return $this->_get(1); - } - - /** - * Set value - * - * @param \examples\Point $value - * @return \examples\RouteNote - */ - public function setLocation(\examples\Point $value){ - return $this->_set(1, $value); - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasMessage(){ - return $this->_has(2); - } - - /** - * Clear value - * - * @return \examples\RouteNote - */ - public function clearMessage(){ - return $this->_clear(2); - } - - /** - * Get value - * - * @return string - */ - public function getMessage(){ - return $this->_get(2); - } - - /** - * Set value - * - * @param string $value - * @return \examples\RouteNote - */ - public function setMessage( $value){ - return $this->_set(2, $value); - } - } -} - -namespace examples { - - class RouteSummary extends \DrSlump\Protobuf\Message { - - /** @var int */ - public $point_count = 0; - - /** @var int */ - public $feature_count = 0; - - /** @var int */ - public $distance = 0; - - /** @var int */ - public $elapsed_time = 0; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'examples.RouteSummary'); - - // OPTIONAL INT32 point_count = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "point_count"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->default = 0; - $descriptor->addField($f); - - // OPTIONAL INT32 feature_count = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "feature_count"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->default = 0; - $descriptor->addField($f); - - // OPTIONAL INT32 distance = 3 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 3; - $f->name = "distance"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->default = 0; - $descriptor->addField($f); - - // OPTIONAL INT32 elapsed_time = 4 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 4; - $f->name = "elapsed_time"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->default = 0; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasPointCount(){ - return $this->_has(1); - } - - /** - * Clear value - * - * @return \examples\RouteSummary - */ - public function clearPointCount(){ - return $this->_clear(1); - } - - /** - * Get value - * - * @return int - */ - public function getPointCount(){ - return $this->_get(1); - } - - /** - * Set value - * - * @param int $value - * @return \examples\RouteSummary - */ - public function setPointCount( $value){ - return $this->_set(1, $value); - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasFeatureCount(){ - return $this->_has(2); - } - - /** - * Clear value - * - * @return \examples\RouteSummary - */ - public function clearFeatureCount(){ - return $this->_clear(2); - } - - /** - * Get value - * - * @return int - */ - public function getFeatureCount(){ - return $this->_get(2); - } - - /** - * Set value - * - * @param int $value - * @return \examples\RouteSummary - */ - public function setFeatureCount( $value){ - return $this->_set(2, $value); - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasDistance(){ - return $this->_has(3); - } - - /** - * Clear value - * - * @return \examples\RouteSummary - */ - public function clearDistance(){ - return $this->_clear(3); - } - - /** - * Get value - * - * @return int - */ - public function getDistance(){ - return $this->_get(3); - } - - /** - * Set value - * - * @param int $value - * @return \examples\RouteSummary - */ - public function setDistance( $value){ - return $this->_set(3, $value); - } - - /** - * Check if has a value - * - * @return boolean - */ - public function hasElapsedTime(){ - return $this->_has(4); - } - - /** - * Clear value - * - * @return \examples\RouteSummary - */ - public function clearElapsedTime(){ - return $this->_clear(4); - } - - /** - * Get value - * - * @return int - */ - public function getElapsedTime(){ - return $this->_get(4); - } - - /** - * Set value - * - * @param int $value - * @return \examples\RouteSummary - */ - public function setElapsedTime( $value){ - return $this->_set(4, $value); - } - } -} - -namespace examples { - - class RouteGuideClient{ - - private $rpc_impl; - - public function __construct($rpc_impl) { - $this->rpc_impl = $rpc_impl; - } - /** - * @param examples\Point $input - */ - public function GetFeature(\examples\Point $argument, $metadata = array()) { - return $this->rpc_impl->_simpleRequest('/examples.RouteGuide/GetFeature', $argument, '\examples\Feature::deserialize', $metadata); - } - /** - * @param examples\Rectangle $input - */ - public function ListFeatures($argument, $metadata = array()) { - return $this->rpc_impl->_serverStreamRequest('/examples.RouteGuide/ListFeatures', $argument, '\examples\Feature::deserialize', $metadata); - } - /** - * @param examples\Point $input - */ - public function RecordRoute($arguments, $metadata = array()) { - return $this->rpc_impl->_clientStreamRequest('/examples.RouteGuide/RecordRoute', $arguments, '\examples\RouteSummary::deserialize', $metadata); - } - /** - * @param examples\RouteNote $input - */ - public function RouteChat($metadata = array()) { - return $this->rpc_impl->_bidiRequest('/examples.RouteGuide/RouteChat', '\examples\RouteNote::deserialize', $metadata); - } - } -} diff --git a/grpc-common/php/route_guide/route_guide.proto b/grpc-common/php/route_guide/route_guide.proto deleted file mode 100644 index 0947184dbb..0000000000 --- a/grpc-common/php/route_guide/route_guide.proto +++ /dev/null @@ -1,120 +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 = "proto2"; - -option java_package = "io.grpc.examples"; - -package examples; - -// Interface exported by the server. -service RouteGuide { - // A simple RPC. - // - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} - - // A server-to-client streaming RPC. - // - // Obtains the Features available within the given Rectangle. Results are - // streamed rather than returned at once (e.g. in a response message with a - // repeated field), as the rectangle may cover a large area and contain a - // huge number of features. - rpc ListFeatures(Rectangle) returns (stream Feature) {} - - // A client-to-server streaming RPC. - // - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} - - // A Bidirectional streaming RPC. - // - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -} - -// Points are represented as latitude-longitude pairs in the E7 representation -// (degrees multiplied by 10**7 and rounded to the nearest integer). -// Latitudes should be in the range +/- 90 degrees and longitude should be in -// the range +/- 180 degrees (inclusive). -message Point { - optional int32 latitude = 1 [default = 0]; - optional int32 longitude = 2 [default = 0]; -} - -// A latitude-longitude rectangle, represented as two diagonally opposite -// points "lo" and "hi". -message Rectangle { - // One corner of the rectangle. - optional Point lo = 1; - - // The other corner of the rectangle. - optional Point hi = 2; -} - -// A feature names something at a given point. -// -// If a feature could not be named, the name is empty. -message Feature { - // The name of the feature. - optional string name = 1; - - // The point where the feature is detected. - optional Point location = 2; -} - -// A RouteNote is a message sent while at a given point. -message RouteNote { - // The location from which the message is sent. - optional Point location = 1; - - // The message to be sent. - optional string message = 2; -} - -// A RouteSummary is received in response to a RecordRoute rpc. -// -// It contains the number of individual points received, the number of -// detected features, and the total distance covered as the cumulative sum of -// the distance between each point. -message RouteSummary { - // The number of points received. - optional int32 point_count = 1 [default = 0]; - - // The number of known features passed while traversing the route. - optional int32 feature_count = 2 [default = 0]; - - // The distance covered in metres. - optional int32 distance = 3 [default = 0]; - - // The duration of the traversal in seconds. - optional int32 elapsed_time = 4 [default = 0]; -} diff --git a/grpc-common/php/route_guide/route_guide_client.php b/grpc-common/php/route_guide/route_guide_client.php deleted file mode 100644 index 6d9ae58b66..0000000000 --- a/grpc-common/php/route_guide/route_guide_client.php +++ /dev/null @@ -1,205 +0,0 @@ -getName(); - if (!$name) { - $name_str = "no feature"; - } else { - $name_str = "feature called $name"; - } - print sprintf("Found %s \n at %f, %f\n", $name_str, - $feature->getLocation()->getLatitude() / COORD_FACTOR, - $feature->getLocation()->getLongitude() / COORD_FACTOR); -} - -/** - * Run the getFeature demo. Calls getFeature with a point known to have a - * feature and a point known not to have a feature. - */ -function runGetFeature() { - print "Running GetFeature...\n"; - global $client; - - $point = new examples\Point(); - $points = array( - array(409146138, -746188906), - array(0, 0), - ); - - foreach ($points as $p) { - $point->setLatitude($p[0]); - $point->setLongitude($p[1]); - // make a unary grpc call - list($feature, $status) = $client->GetFeature($point)->wait(); - printFeature($feature); - } -} - -/** - * Run the listFeatures demo. Calls listFeatures with a rectangle - * containing all of the features in the pre-generated - * database. Prints each response as it comes in. - */ -function runListFeatures() { - print "Running ListFeatures...\n"; - global $client; - - $lo_point = new examples\Point(); - $hi_point = new examples\Point(); - - $lo_point->setLatitude(400000000); - $lo_point->setLongitude(-750000000); - $hi_point->setLatitude(420000000); - $hi_point->setLongitude(-730000000); - - $rectangle = new examples\Rectangle(); - $rectangle->setLo($lo_point); - $rectangle->setHi($hi_point); - - $call = $client->ListFeatures($rectangle); - // an iterator over the server streaming responses - $features = $call->responses(); - foreach ($features as $feature) { - printFeature($feature); - } -} - -/** - * Run the recordRoute demo. Sends several randomly chosen points from the - * pre-generated feature database with a variable delay in between. Prints - * the statistics when they are sent from the server. - */ -function runRecordRoute() { - print "Running RecordRoute...\n"; - global $client, $argv; - - $db = json_decode(file_get_contents($argv[1]), true); - $points_iter = function($db) { - $num_points_in_db = count($db); - $num_points = 10; - for ($i = 0; $i < $num_points; $i++) { - $point = new examples\Point(); - $index = rand(0, $num_points_in_db - 1); - $lat = $db[$index]['location']['latitude']; - $long = $db[$index]['location']['longitude']; - $feature_name = $db[$index]['name']; - $point->setLatitude($lat); - $point->setLongitude($long); - print sprintf("Visiting point %f, %f,\n with feature name: %s\n", - $lat / COORD_FACTOR, $long / COORD_FACTOR, - $feature_name ? $feature_name : ''); - usleep(rand(300000, 800000)); - yield $point; - } - }; - // $points_iter is an iterator simulating client streaming - list($route_summary, $status) = - $client->RecordRoute($points_iter($db))->wait(); - print sprintf("Finished trip with %d points\nPassed %d features\n". - "Travelled %d meters\nIt took %d seconds\n", - $route_summary->getPointCount(), - $route_summary->getFeatureCount(), - $route_summary->getDistance(), - $route_summary->getElapsedTime()); -} - -/** - * Run the routeChat demo. Send some chat messages, and print any chat - * messages that are sent from the server. - */ -function runRouteChat() { - print "Running RouteChat...\n"; - global $client; - - // start the bidirectional streaming call - $call = $client->RouteChat(); - - $notes = array( - array(1, 1, 'first message'), - array(1, 2, 'second message'), - array(2, 1, 'third message'), - array(1, 1, 'fourth message'), - array(1, 1, 'fifth message'), - ); - - foreach ($notes as $n) { - $point = new examples\Point(); - $point->setLatitude($lat = $n[0]); - $point->setLongitude($long = $n[1]); - - $route_note = new examples\RouteNote(); - $route_note->setLocation($point); - $route_note->setMessage($message = $n[2]); - - print sprintf("Sending message: '%s' at (%d, %d)\n", - $message, $lat, $long); - // send a bunch of messages to the server - $call->write($route_note); - } - $call->writesDone(); - - // read from the server until there's no more - while ($route_note_reply = $call->read()) { - print sprintf("Previous left message at (%d, %d): '%s'\n", - $route_note_reply->getLocation()->getLatitude(), - $route_note_reply->getLocation()->getLongitude(), - $route_note_reply->getMessage()); - } -} - -/** - * Run all of the demos in order - */ -function main() { - runGetFeature(); - runListFeatures(); - runRecordRoute(); - runRouteChat(); -} - -if (empty($argv[1])) { - print "Usage: php -d extension=grpc.so route_guide_client.php " . - "\n"; - exit(1); -} -main(); diff --git a/grpc-common/php/route_guide/run_route_guide_client.sh b/grpc-common/php/route_guide/run_route_guide_client.sh deleted file mode 100755 index e5ca07796b..0000000000 --- a/grpc-common/php/route_guide/run_route_guide_client.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -# 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. - -set -e -cd $(dirname $0) -command -v brew >/dev/null 2>&1 && \ - extension_dir="-d extension_dir="`brew --prefix`/opt/grpc-php -php $extension_dir -d extension=grpc.so \ - route_guide_client.php ../../node/route_guide/route_guide_db.json diff --git a/grpc-common/php/run_greeter_client.sh b/grpc-common/php/run_greeter_client.sh deleted file mode 100755 index 2906de9af8..0000000000 --- a/grpc-common/php/run_greeter_client.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash -# 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. - -set -e -cd $(dirname $0) -command -v brew >/dev/null 2>&1 && \ - extension_dir="-d extension_dir="`brew --prefix`/opt/grpc-php -php $extension_dir -d extension=grpc.so greeter_client.php $1 diff --git a/grpc-common/protos/README.md b/grpc-common/protos/README.md deleted file mode 100644 index 48df7c8943..0000000000 --- a/grpc-common/protos/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Example protos - -## Contents - -- [helloworld.proto] - - The simple example used in the overview. -- [route_guide.proto] - - An example service described in detail in the tutorial. diff --git a/grpc-common/protos/auth_sample.proto b/grpc-common/protos/auth_sample.proto deleted file mode 100644 index a49caca657..0000000000 --- a/grpc-common/protos/auth_sample.proto +++ /dev/null @@ -1,57 +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 grpc.testing; - -option objc_class_prefix = "AUTH"; - -// Unary request. -message Request { - // Whether Response should include username. - bool fill_username = 4; - - // Whether Response should include OAuth scope. - bool fill_oauth_scope = 5; -} - -// Unary response, as configured by the request. -message Response { - // The user the request came from, for verifying authentication was - // successful. - string username = 2; - // OAuth scope. - string oauth_scope = 3; -} - -service TestService { - // One request followed by one response. - rpc UnaryCall(Request) returns (Response); -} diff --git a/grpc-common/protos/hellostreamingworld.proto b/grpc-common/protos/hellostreamingworld.proto deleted file mode 100644 index bd5af3b2d5..0000000000 --- a/grpc-common/protos/hellostreamingworld.proto +++ /dev/null @@ -1,54 +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"; - -option java_package = "ex.grpc"; -option objc_class_prefix = "HSW"; - -package hellostreamingworld; - -// The greeting service definition. -service MultiGreeter { - // Sends multiple greetings - rpc sayHello (HelloRequest) returns (stream HelloReply) {} -} - -// The request message containing the user's name and how many greetings -// they want. -message HelloRequest { - string name = 1; - string num_greetings = 2; -} - -// A response message containing a greeting -message HelloReply { - string message = 1; -} - diff --git a/grpc-common/protos/helloworld.proto b/grpc-common/protos/helloworld.proto deleted file mode 100644 index 7d58870a70..0000000000 --- a/grpc-common/protos/helloworld.proto +++ /dev/null @@ -1,51 +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"; - -option java_package = "io.grpc.examples"; -option objc_class_prefix = "HLW"; - -package helloworld; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} diff --git a/grpc-common/protos/route_guide.proto b/grpc-common/protos/route_guide.proto deleted file mode 100644 index bfde5f1ead..0000000000 --- a/grpc-common/protos/route_guide.proto +++ /dev/null @@ -1,124 +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"; - -option java_package = "ex.grpc"; -option objc_class_prefix = "RTG"; - -package examples; - -// Interface exported by the server. -service RouteGuide { - // A simple RPC. - // - // Obtains the feature at a given position. - // - // A feature with an empty name is returned if there's no feature at the 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/grpc-common/python/helloworld/.gitignore b/grpc-common/python/helloworld/.gitignore deleted file mode 100644 index 0d20b6487c..0000000000 --- a/grpc-common/python/helloworld/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/grpc-common/python/helloworld/README.md b/grpc-common/python/helloworld/README.md deleted file mode 100644 index 0a6a718bae..0000000000 --- a/grpc-common/python/helloworld/README.md +++ /dev/null @@ -1,116 +0,0 @@ -# gRPC Python Hello World - -This is a quick introduction with a simple example and installation instructions: for a more complete tutorial see [gRPC Basics: Python](https://github.com/grpc/grpc-common/tree/master/python/route_guide). - -### Install gRPC -Make sure you have built gRPC Python from source on your system. Follow the instructions here: -[https://github.com/grpc/grpc/blob/master/src/python/README.md](https://github.com/grpc/grpc/blob/master/src/python/README.md). - -This gives you a python virtual environment with installed gRPC Python -in GRPC_ROOT/python2.7_virtual_environment. GRPC_ROOT is the path to which you -have cloned the [gRPC git repo](https://github.com/grpc/grpc). - -### Get the source code - -The example code for our Hello World and our other examples live in the `grpc-common` -GitHub repository. Clone this repository to your local machine by running the -following command: - - -```sh -$ git clone https://github.com/grpc/grpc-common.git -``` - -Change your current directory to grpc-common/python/helloworld - -```sh -$ cd grpc-common/python/helloworld/ -``` - -### Defining a service - -The first step in creating our example is to define a *service*: an RPC -service specifies the methods that can be called remotely with their parameters -and return types. As you saw in the -[overview](#protocolbuffers) above, gRPC does this using [protocol -buffers](https://developers.google.com/protocol-buffers/docs/overview). We -use the protocol buffers interface definition language (IDL) to define our -service methods, and define the parameters and return -types as protocol buffer message types. Both the client and the -server use interface code generated from the service definition. - -Here's our example service definition. The `Greeting` -service has one method, `hello`, that lets the server receive a single -`HelloRequest` -message from the remote client containing the user's name, then send back -a greeting in a single `HelloReply`. This is the simplest type of RPC you -can specify in gRPC. - -``` -syntax = "proto3"; - -option java_package = "io.grpc.examples"; - -package helloworld; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} - -``` - - -### Generating gRPC code - -Once we've defined our service, we use the protocol buffer compiler -`protoc` to generate the special client and server code we need to create -our application. The generated code contains both stub code for clients to -use and an abstract interface for servers to implement, both with the method -defined in our `Greeting` service. - -To generate the client and server side interfaces: - -```sh -$ ./run_codegen.sh -``` -Which internally invokes the proto-compiler as: - -```sh -$ protoc -I ../../protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` ../../protos/helloworld.proto -``` - -Optionally, you can just skip the code generation step as the generated python module has already -been generated for you (helloworld_pb2.py). - -### The client - -Client-side code can be found in [greeter_client.py](https://github.com/grpc/grpc-common/blob/master/python/helloworld/greeter_client.py). - -You can run the client using: - -```sh -$ ./run_client.sh -``` - - -### The server - -Server side code can be found in [greeter_server.py](https://github.com/grpc/grpc-common/blob/master/python/helloworld/greeter_server.py). - -You can run the server using: - -```sh -$ ./run_server.sh -``` diff --git a/grpc-common/python/helloworld/greeter_client.py b/grpc-common/python/helloworld/greeter_client.py deleted file mode 100755 index 370ce46770..0000000000 --- a/grpc-common/python/helloworld/greeter_client.py +++ /dev/null @@ -1,44 +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. - -"""The Python implementation of the GRPC helloworld.Greeter client.""" - -import helloworld_pb2 - -_TIMEOUT_SECONDS = 10 - - -def run(): - with helloworld_pb2.early_adopter_create_Greeter_stub('localhost', 50051) as stub: - response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'), _TIMEOUT_SECONDS) - print "Greeter client received: " + response.message - - -if __name__ == '__main__': - run() diff --git a/grpc-common/python/helloworld/greeter_server.py b/grpc-common/python/helloworld/greeter_server.py deleted file mode 100644 index 81353666b1..0000000000 --- a/grpc-common/python/helloworld/greeter_server.py +++ /dev/null @@ -1,56 +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. - -"""The Python implementation of the GRPC helloworld.Greeter server.""" - -import time - -import helloworld_pb2 - -_ONE_DAY_IN_SECONDS = 60 * 60 * 24 - - -class Greeter(helloworld_pb2.EarlyAdopterGreeterServicer): - - def SayHello(self, request, context): - return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) - - -def serve(): - server = helloworld_pb2.early_adopter_create_Greeter_server( - Greeter(), 50051, None, None) - server.start() - try: - while True: - time.sleep(_ONE_DAY_IN_SECONDS) - except KeyboardInterrupt: - server.stop() - -if __name__ == '__main__': - serve() diff --git a/grpc-common/python/helloworld/run_client.sh b/grpc-common/python/helloworld/run_client.sh deleted file mode 100755 index 095e6bc2f0..0000000000 --- a/grpc-common/python/helloworld/run_client.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -# This is where you have cloned out the https://github.com/grpc/grpc repository -# And built gRPC Python. -# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS -GRPC_ROOT=~/github/grpc - -$GRPC_ROOT/python2.7_virtual_environment/bin/python greeter_client.py diff --git a/grpc-common/python/helloworld/run_codegen.sh b/grpc-common/python/helloworld/run_codegen.sh deleted file mode 100755 index 4d826c7946..0000000000 --- a/grpc-common/python/helloworld/run_codegen.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -# Runs the protoc with gRPC plugin to generate protocol messages and gRPC stubs. -protoc -I ../../protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` ../../protos/helloworld.proto diff --git a/grpc-common/python/helloworld/run_server.sh b/grpc-common/python/helloworld/run_server.sh deleted file mode 100755 index 13b009e6cc..0000000000 --- a/grpc-common/python/helloworld/run_server.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -# This is where you have cloned out the https://github.com/grpc/grpc repository -# And built gRPC Python. -# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS -GRPC_ROOT=~/github/grpc - -$GRPC_ROOT/python2.7_virtual_environment/bin/python greeter_server.py - diff --git a/grpc-common/python/route_guide/.gitignore b/grpc-common/python/route_guide/.gitignore deleted file mode 100644 index 0d20b6487c..0000000000 --- a/grpc-common/python/route_guide/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/grpc-common/python/route_guide/README.md b/grpc-common/python/route_guide/README.md deleted file mode 100644 index 91bef0ac00..0000000000 --- a/grpc-common/python/route_guide/README.md +++ /dev/null @@ -1,303 +0,0 @@ -#gRPC Basics: Python - -This tutorial provides a basic Python programmer's introduction to working with gRPC. By walking through this example you'll learn how to: - -- Define a service in a .proto file. -- Generate server and client code using the protocol buffer compiler. -- Use the Python gRPC API to write a simple client and server for your service. - -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. - -This isn't a comprehensive guide to using gRPC in Python: more reference documentation is coming soon. - - -## Why use gRPC? - -This example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. - -With gRPC you can define your service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet, with all the complexity of communication between different languages and environments is handled for you by gRPC. You also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. - -## Example code and setup - -The example code for this tutorial is in [grpc/grpc-common/python/route_guide](https://github.com/grpc/grpc-common/tree/master/python/route_guide). To download the example, clone the `grpc-common` repository by running the following command: -```shell -$ git clone https://github.com/grpc/grpc-common.git -``` - -Then change your current directory to `grpc-common/python/route_guide`: -```shell -$ cd grpc-common/python/route_guide -``` - -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Python quick start guide](https://github.com/grpc/grpc-common/tree/master/python). - -## Defining the service - -Your first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). - -To define a service, you specify a named `service` in your .proto file: - -```protobuf -service RouteGuide { - // (Method definitions not shown) -} -``` - -Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: - -- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. -```protobuf - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} -``` - -- A *response-streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in the example, you specify a response-streaming method by placing the `stream` keyword before the *response* type. -```protobuf - // 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 *request-streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a request-streaming method by placing the `stream` keyword before the *request* type. -```protobuf - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} -``` - -- A *bidirectionally-streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -```protobuf - // 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) {} -``` - -Your .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -```protobuf -// 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; -} -``` - -## Generating client and server code - -Next you need to generate the gRPC client and server interfaces from your .proto service definition. You do this using the protocol buffer compiler `protoc` with a special gRPC Python plugin. Make sure you've installed protoc and followed the gRPC Python plugin [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): - -With `protoc` and the gRPC Python plugin installed, use the following command to generate the Python code: - -```shell -$ protoc -I ../../protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` ../../protos/route_guide.proto -``` - -Note that as we've already provided a version of the generated code in the example repository, running this command regenerates the appropriate file rather than creates a new one. The generated code file is called `route_guide_pb2.py` and contains: -- classes for the messages defined in route_guide.proto -- abstract classes for the service defined in route_guide.proto - - `EarlyAdopterRouteGuideServicer`, which defines the interface for implementations of the RouteGuide service - - `EarlyAdopterRouteGuideServer`, which may be started and stopped - - `EarlyAdopterRouteGuideStub`, which can be used by clients to invoke RouteGuide RPCs -- functions for application use - - `early_adopter_create_RouteGuide_server`, which creates a gRPC server given an `EarlyAdopterRouteGuideServicer` object - - `early_adopter_create_RouteGuide_stub`, which can be used by clients to create a stub object - - -## Creating the server - -First let's look at how you create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). - -Creating and running a `RouteGuide` server breaks down into two work items: -- Implementing the servicer interface generated from our service definition with functions that perform the actual "work" of the service. -- Running a gRPC server to listen for requests from clients and transmit responses. - -You can find the example `RouteGuide` server in [grpc-common/python/route_guide/route_guide_server.py](https://github.com/grpc/grpc-common/blob/master/python/route_guide/route_guide_server.py). - -### Implementing RouteGuide - -`route_guide_server.py` has a `RouteGuideServicer` class that implements the generated interface `route_guide_pb2.EarlyAdopterRouteGuideServicer`: - -```python -# RouteGuideServicer provides an implementation of the methods of the RouteGuide service. -class RouteGuideServicer(route_guide_pb2.EarlyAdopterRouteGuideServicer): -``` - -`RouteGuideServicer` implements all the `RouteGuide` service methods. - -#### Simple RPC - -Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. - -```python - def GetFeature(self, request, context): - feature = get_feature(self.db, request) - if feature is None: - return route_guide_pb2.Feature(name="", location=request) - else: - return feature -``` - -The method is passed a `route_guide_pb2.Point` request for the RPC, and an `RpcContext` object that provides RPC-specific information such as timeout limits. It returns a `route_guide_pb2.Feature` response. - -#### Response-streaming RPC - -Now let's look at the next method. `ListFeatures` is a response-streaming RPC that sends multiple `Feature`s to the client. - -```python - def ListFeatures(self, request, context): - left = min(request.lo.longitude, request.hi.longitude) - right = max(request.lo.longitude, request.hi.longitude) - top = max(request.lo.latitude, request.hi.latitude) - bottom = min(request.lo.latitude, request.hi.latitude) - for feature in self.db: - if (feature.location.longitude >= left and - feature.location.longitude <= right and - feature.location.latitude >= bottom and - feature.location.latitude <= top): - yield feature -``` - -Here the request message is a `route_guide_pb2.Rectangle` within which the client wants to find `Feature`s. Instead of returning a single response the method yields zero or more responses. - -#### Request-streaming RPC - -The request-streaming method `RecordRoute` uses an [iterator](https://docs.python.org/2/library/stdtypes.html#iterator-types) of request values and returns a single response value. - -```python - def RecordRoute(self, request_iterator, context): - point_count = 0 - feature_count = 0 - distance = 0.0 - prev_point = None - - start_time = time.time() - for point in request_iterator: - point_count += 1 - if get_feature(self.db, point): - feature_count += 1 - if prev_point: - distance += get_distance(prev_point, point) - prev_point = point - - elapsed_time = time.time() - start_time - return route_guide_pb2.RouteSummary(point_count=point_count, - feature_count=feature_count, - distance=int(distance), - elapsed_time=int(elapsed_time)) -``` - -#### Bidirectional streaming RPC - -Lastly let's look at the bidirectionally-streaming method `RouteChat`. - -```python - def RouteChat(self, request_iterator, context): - prev_notes = [] - for new_note in request_iterator: - for prev_note in prev_notes: - if prev_note.location == new_note.location: - yield prev_note - prev_notes.append(new_note) -``` - -This method's semantics are a combination of those of the request-streaming method and the response-streaming method. It is passed an iterator of request values and is itself an iterator of response values. - -### Starting the server - -Once you have implemented all the `RouteGuide` methods, the next step is to start up a gRPC server so that clients can actually use your service: - -```python -def serve(): - server = route_guide_pb2.early_adopter_create_RouteGuide_server( - RouteGuideServicer(), 50051, None, None) - server.start() -``` - -Because `start()` does not block you may need to sleep-loop if there is nothing else for your code to do while serving. - - -## Creating the client - -You can see the complete example client code in [grpc-common/python/route_guide/route_guide_client.py](https://github.com/grpc/grpc-common/blob/master/python/route_guide/route_guide_client.py). - -### Creating a stub - -To call service methods, we first need to create a *stub*. - -We use the `early_adopter_create_RouteGuide_stub` function of the `route_guide_pb2` module, generated from our .proto. - -```python -stub = RouteGuide::Stub.new('localhost', 50051) -``` - -The returned object implements all the methods defined by the `EarlyAdopterRouteGuideStub` interface, and is also a [context manager](https://docs.python.org/2/library/stdtypes.html#typecontextmanager). All RPCs invoked on the stub must be invoked within the stub's context, so it is common for stubs to be created and used with a [with statement](https://docs.python.org/2/reference/compound_stmts.html#the-with-statement): - -```python -with route_guide_pb2.early_adopter_create_RouteGuide_stub('localhost', 50051) as stub: -``` - -### Calling service methods - -For RPC methods that return a single response ("response-unary" methods), gRPC Python supports both synchronous (blocking) and asynchronous (non-blocking) control flow semantics. For response-streaming RPC methods, calls immediately return an iterator of response values. Calls to that iterator's `next()` method block until the response to be yielded from the iterator becomes available. - -#### Simple RPC - -A synchronous call to the simple RPC `GetFeature` is nearly as straightforward as calling a local method. The RPC call waits for the server to respond, and will either return a response or raise an exception: - -```python -feature = stub.GetFeature(point, timeout_in_seconds) -``` - -An asynchronous call to `GetFeature` is similar, but like calling a local method asynchronously in a thread pool: - -```python -feature_future = stub.GetFeature.async(point, timeout_in_seconds) -feature = feature_future.result() -``` - -#### Response-streaming RPC - -Calling the response-streaming `ListFeatures` is similar to working with sequence types: - -```python -for feature in stub.ListFeatures(rectangle, timeout_in_seconds): -``` - -#### Request-streaming RPC - -Calling the request-streaming `RecordRoute` is similar to passing a sequence to a local method. Like the simple RPC above that also returns a single response, it can be called synchronously or asynchronously: - -```python -route_summary = stub.RecordRoute(point_sequence, timeout_in_seconds) -``` - -```python -route_summary_future = stub.RecordRoute.async(point_sequence, timeout_in_seconds) -route_summary = route_summary_future.result() -``` - -#### Bidirectional streaming RPC - -Calling the bidirectionally-streaming `RouteChat` has (as is the case on the service-side) a combination of the request-streaming and response-streaming semantics: - -```python -for received_route_note in stub.RouteChat(sent_routes, timeout_in_seconds): -``` - -## Try it out! - -Run the server, which will listen on port 50051: - -```shell -$ python route_guide_server.py -``` - -Run the client (in a different terminal): - -```shell -$ python route_guide_client.py -``` diff --git a/grpc-common/python/route_guide/route_guide_client.py b/grpc-common/python/route_guide/route_guide_client.py deleted file mode 100755 index 078231543e..0000000000 --- a/grpc-common/python/route_guide/route_guide_client.py +++ /dev/null @@ -1,130 +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. - -"""The Python implementation of the gRPC route guide client.""" - -import random -import time - -import route_guide_pb2 -import route_guide_resources - -_TIMEOUT_SECONDS = 30 - - -def make_route_note(message, latitude, longitude): - return route_guide_pb2.RouteNote( - message=message, - location=route_guide_pb2.Point(latitude=latitude, longitude=longitude)) - - -def guide_get_one_feature(stub, point): - feature = stub.GetFeature(point, _TIMEOUT_SECONDS) - if not feature.location: - print "Server returned incomplete feature" - return - - if feature.name: - print "Feature called %s at %s" % (feature.name, feature.location) - else: - print "Found no feature at %s" % feature.location - - -def guide_get_feature(stub): - guide_get_one_feature(stub, route_guide_pb2.Point(latitude=409146138, longitude=-746188906)) - guide_get_one_feature(stub, route_guide_pb2.Point(latitude=0, longitude=0)) - - -def guide_list_features(stub): - rect = route_guide_pb2.Rectangle( - lo=route_guide_pb2.Point( - latitude=400000000, longitude = -750000000), - hi=route_guide_pb2.Point( - latitude = 420000000, longitude = -730000000)) - print "Looking for features between 40, -75 and 42, -73" - - features = stub.ListFeatures(rect, _TIMEOUT_SECONDS) - - for feature in features: - print "Feature called %s at %s" % (feature.name, feature.location) - - -def generate_route(feature_list): - for _ in range(0, 10): - random_feature = feature_list[random.randint(0, len(feature_list) - 1)] - print "Visiting point %s" % random_feature.location - yield random_feature.location - time.sleep(random.uniform(0.5, 1.5)) - - -def guide_record_route(stub): - feature_list = route_guide_resources.read_route_guide_database() - - route_iter = generate_route(feature_list) - route_summary = stub.RecordRoute(route_iter, _TIMEOUT_SECONDS) - print "Finished trip with %s points " % route_summary.point_count - print "Passed %s features " % route_summary.feature_count - print "Travelled %s meters " % route_summary.distance - print "It took %s seconds " % route_summary.elapsed_time - - -def generate_messages(): - messages = [ - make_route_note("First message", 0, 0), - make_route_note("Second message", 0, 1), - make_route_note("Third message", 1, 0), - make_route_note("Fourth message", 0, 0), - make_route_note("Fifth message", 1, 0), - ] - for msg in messages: - print "Sending %s at %s" % (msg.message, msg.location) - yield msg - time.sleep(random.uniform(0.5, 1.0)) - - -def guide_route_chat(stub): - responses = stub.RouteChat(generate_messages(), _TIMEOUT_SECONDS) - for response in responses: - print "Received message %s at %s" % (response.message, response.location) - - -def run(): - with route_guide_pb2.early_adopter_create_RouteGuide_stub('localhost', 50051) as stub: - print "-------------- GetFeature --------------" - guide_get_feature(stub) - print "-------------- ListFeatures --------------" - guide_list_features(stub) - print "-------------- RecordRoute --------------" - guide_record_route(stub) - print "-------------- RouteChat --------------" - guide_route_chat(stub) - - -if __name__ == '__main__': - run() diff --git a/grpc-common/python/route_guide/route_guide_db.json b/grpc-common/python/route_guide/route_guide_db.json deleted file mode 100644 index 9d6a980ab7..0000000000 --- a/grpc-common/python/route_guide/route_guide_db.json +++ /dev/null @@ -1,601 +0,0 @@ -[{ - "location": { - "latitude": 407838351, - "longitude": -746143763 - }, - "name": "Patriots Path, Mendham, NJ 07945, USA" -}, { - "location": { - "latitude": 408122808, - "longitude": -743999179 - }, - "name": "101 New Jersey 10, Whippany, NJ 07981, USA" -}, { - "location": { - "latitude": 413628156, - "longitude": -749015468 - }, - "name": "U.S. 6, Shohola, PA 18458, USA" -}, { - "location": { - "latitude": 419999544, - "longitude": -740371136 - }, - "name": "5 Conners Road, Kingston, NY 12401, USA" -}, { - "location": { - "latitude": 414008389, - "longitude": -743951297 - }, - "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" -}, { - "location": { - "latitude": 419611318, - "longitude": -746524769 - }, - "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" -}, { - "location": { - "latitude": 406109563, - "longitude": -742186778 - }, - "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" -}, { - "location": { - "latitude": 416802456, - "longitude": -742370183 - }, - "name": "352 South Mountain Road, Wallkill, NY 12589, USA" -}, { - "location": { - "latitude": 412950425, - "longitude": -741077389 - }, - "name": "Bailey Turn Road, Harriman, NY 10926, USA" -}, { - "location": { - "latitude": 412144655, - "longitude": -743949739 - }, - "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" -}, { - "location": { - "latitude": 415736605, - "longitude": -742847522 - }, - "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" -}, { - "location": { - "latitude": 413843930, - "longitude": -740501726 - }, - "name": "162 Merrill Road, Highland Mills, NY 10930, USA" -}, { - "location": { - "latitude": 410873075, - "longitude": -744459023 - }, - "name": "Clinton Road, West Milford, NJ 07480, USA" -}, { - "location": { - "latitude": 412346009, - "longitude": -744026814 - }, - "name": "16 Old Brook Lane, Warwick, NY 10990, USA" -}, { - "location": { - "latitude": 402948455, - "longitude": -747903913 - }, - "name": "3 Drake Lane, Pennington, NJ 08534, USA" -}, { - "location": { - "latitude": 406337092, - "longitude": -740122226 - }, - "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" -}, { - "location": { - "latitude": 406421967, - "longitude": -747727624 - }, - "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" -}, { - "location": { - "latitude": 416318082, - "longitude": -749677716 - }, - "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" -}, { - "location": { - "latitude": 415301720, - "longitude": -748416257 - }, - "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" -}, { - "location": { - "latitude": 402647019, - "longitude": -747071791 - }, - "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" -}, { - "location": { - "latitude": 412567807, - "longitude": -741058078 - }, - "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" -}, { - "location": { - "latitude": 416855156, - "longitude": -744420597 - }, - "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" -}, { - "location": { - "latitude": 404663628, - "longitude": -744820157 - }, - "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" -}, { - "location": { - "latitude": 407113723, - "longitude": -749746483 - }, - "name": "" -}, { - "location": { - "latitude": 402133926, - "longitude": -743613249 - }, - "name": "" -}, { - "location": { - "latitude": 400273442, - "longitude": -741220915 - }, - "name": "" -}, { - "location": { - "latitude": 411236786, - "longitude": -744070769 - }, - "name": "" -}, { - "location": { - "latitude": 411633782, - "longitude": -746784970 - }, - "name": "211-225 Plains Road, Augusta, NJ 07822, USA" -}, { - "location": { - "latitude": 415830701, - "longitude": -742952812 - }, - "name": "" -}, { - "location": { - "latitude": 413447164, - "longitude": -748712898 - }, - "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" -}, { - "location": { - "latitude": 405047245, - "longitude": -749800722 - }, - "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" -}, { - "location": { - "latitude": 418858923, - "longitude": -746156790 - }, - "name": "" -}, { - "location": { - "latitude": 417951888, - "longitude": -748484944 - }, - "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" -}, { - "location": { - "latitude": 407033786, - "longitude": -743977337 - }, - "name": "26 East 3rd Street, New Providence, NJ 07974, USA" -}, { - "location": { - "latitude": 417548014, - "longitude": -740075041 - }, - "name": "" -}, { - "location": { - "latitude": 410395868, - "longitude": -744972325 - }, - "name": "" -}, { - "location": { - "latitude": 404615353, - "longitude": -745129803 - }, - "name": "" -}, { - "location": { - "latitude": 406589790, - "longitude": -743560121 - }, - "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" -}, { - "location": { - "latitude": 414653148, - "longitude": -740477477 - }, - "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" -}, { - "location": { - "latitude": 405957808, - "longitude": -743255336 - }, - "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" -}, { - "location": { - "latitude": 411733589, - "longitude": -741648093 - }, - "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" -}, { - "location": { - "latitude": 412676291, - "longitude": -742606606 - }, - "name": "1270 Lakes Road, Monroe, NY 10950, USA" -}, { - "location": { - "latitude": 409224445, - "longitude": -748286738 - }, - "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" -}, { - "location": { - "latitude": 406523420, - "longitude": -742135517 - }, - "name": "652 Garden Street, Elizabeth, NJ 07202, USA" -}, { - "location": { - "latitude": 401827388, - "longitude": -740294537 - }, - "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" -}, { - "location": { - "latitude": 410564152, - "longitude": -743685054 - }, - "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" -}, { - "location": { - "latitude": 408472324, - "longitude": -740726046 - }, - "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" -}, { - "location": { - "latitude": 412452168, - "longitude": -740214052 - }, - "name": "5 White Oak Lane, Stony Point, NY 10980, USA" -}, { - "location": { - "latitude": 409146138, - "longitude": -746188906 - }, - "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" -}, { - "location": { - "latitude": 404701380, - "longitude": -744781745 - }, - "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" -}, { - "location": { - "latitude": 409642566, - "longitude": -746017679 - }, - "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" -}, { - "location": { - "latitude": 408031728, - "longitude": -748645385 - }, - "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" -}, { - "location": { - "latitude": 413700272, - "longitude": -742135189 - }, - "name": "367 Prospect Road, Chester, NY 10918, USA" -}, { - "location": { - "latitude": 404310607, - "longitude": -740282632 - }, - "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" -}, { - "location": { - "latitude": 409319800, - "longitude": -746201391 - }, - "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" -}, { - "location": { - "latitude": 406685311, - "longitude": -742108603 - }, - "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" -}, { - "location": { - "latitude": 419018117, - "longitude": -749142781 - }, - "name": "43 Dreher Road, Roscoe, NY 12776, USA" -}, { - "location": { - "latitude": 412856162, - "longitude": -745148837 - }, - "name": "Swan Street, Pine Island, NY 10969, USA" -}, { - "location": { - "latitude": 416560744, - "longitude": -746721964 - }, - "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" -}, { - "location": { - "latitude": 405314270, - "longitude": -749836354 - }, - "name": "" -}, { - "location": { - "latitude": 414219548, - "longitude": -743327440 - }, - "name": "" -}, { - "location": { - "latitude": 415534177, - "longitude": -742900616 - }, - "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" -}, { - "location": { - "latitude": 406898530, - "longitude": -749127080 - }, - "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" -}, { - "location": { - "latitude": 407586880, - "longitude": -741670168 - }, - "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" -}, { - "location": { - "latitude": 400106455, - "longitude": -742870190 - }, - "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" -}, { - "location": { - "latitude": 400066188, - "longitude": -746793294 - }, - "name": "" -}, { - "location": { - "latitude": 418803880, - "longitude": -744102673 - }, - "name": "40 Mountain Road, Napanoch, NY 12458, USA" -}, { - "location": { - "latitude": 414204288, - "longitude": -747895140 - }, - "name": "" -}, { - "location": { - "latitude": 414777405, - "longitude": -740615601 - }, - "name": "" -}, { - "location": { - "latitude": 415464475, - "longitude": -747175374 - }, - "name": "48 North Road, Forestburgh, NY 12777, USA" -}, { - "location": { - "latitude": 404062378, - "longitude": -746376177 - }, - "name": "" -}, { - "location": { - "latitude": 405688272, - "longitude": -749285130 - }, - "name": "" -}, { - "location": { - "latitude": 400342070, - "longitude": -748788996 - }, - "name": "" -}, { - "location": { - "latitude": 401809022, - "longitude": -744157964 - }, - "name": "" -}, { - "location": { - "latitude": 404226644, - "longitude": -740517141 - }, - "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" -}, { - "location": { - "latitude": 410322033, - "longitude": -747871659 - }, - "name": "" -}, { - "location": { - "latitude": 407100674, - "longitude": -747742727 - }, - "name": "" -}, { - "location": { - "latitude": 418811433, - "longitude": -741718005 - }, - "name": "213 Bush Road, Stone Ridge, NY 12484, USA" -}, { - "location": { - "latitude": 415034302, - "longitude": -743850945 - }, - "name": "" -}, { - "location": { - "latitude": 411349992, - "longitude": -743694161 - }, - "name": "" -}, { - "location": { - "latitude": 404839914, - "longitude": -744759616 - }, - "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" -}, { - "location": { - "latitude": 414638017, - "longitude": -745957854 - }, - "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" -}, { - "location": { - "latitude": 412127800, - "longitude": -740173578 - }, - "name": "" -}, { - "location": { - "latitude": 401263460, - "longitude": -747964303 - }, - "name": "" -}, { - "location": { - "latitude": 412843391, - "longitude": -749086026 - }, - "name": "" -}, { - "location": { - "latitude": 418512773, - "longitude": -743067823 - }, - "name": "" -}, { - "location": { - "latitude": 404318328, - "longitude": -740835638 - }, - "name": "42-102 Main Street, Belford, NJ 07718, USA" -}, { - "location": { - "latitude": 419020746, - "longitude": -741172328 - }, - "name": "" -}, { - "location": { - "latitude": 404080723, - "longitude": -746119569 - }, - "name": "" -}, { - "location": { - "latitude": 401012643, - "longitude": -744035134 - }, - "name": "" -}, { - "location": { - "latitude": 404306372, - "longitude": -741079661 - }, - "name": "" -}, { - "location": { - "latitude": 403966326, - "longitude": -748519297 - }, - "name": "" -}, { - "location": { - "latitude": 405002031, - "longitude": -748407866 - }, - "name": "" -}, { - "location": { - "latitude": 409532885, - "longitude": -742200683 - }, - "name": "" -}, { - "location": { - "latitude": 416851321, - "longitude": -742674555 - }, - "name": "" -}, { - "location": { - "latitude": 406411633, - "longitude": -741722051 - }, - "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" -}, { - "location": { - "latitude": 413069058, - "longitude": -744597778 - }, - "name": "261 Van Sickle Road, Goshen, NY 10924, USA" -}, { - "location": { - "latitude": 418465462, - "longitude": -746859398 - }, - "name": "" -}, { - "location": { - "latitude": 411733222, - "longitude": -744228360 - }, - "name": "" -}, { - "location": { - "latitude": 410248224, - "longitude": -747127767 - }, - "name": "3 Hasta Way, Newton, NJ 07860, USA" -}] diff --git a/grpc-common/python/route_guide/route_guide_pb2.py b/grpc-common/python/route_guide/route_guide_pb2.py deleted file mode 100644 index 2a4532bb75..0000000000 --- a/grpc-common/python/route_guide/route_guide_pb2.py +++ /dev/null @@ -1,370 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: route_guide.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='route_guide.proto', - package='', - serialized_pb=_b('\n\x11route_guide.proto\",\n\x05Point\x12\x10\n\x08latitude\x18\x01 \x01(\x05\x12\x11\n\tlongitude\x18\x02 \x01(\x05\"3\n\tRectangle\x12\x12\n\x02lo\x18\x01 \x01(\x0b\x32\x06.Point\x12\x12\n\x02hi\x18\x02 \x01(\x0b\x32\x06.Point\"1\n\x07\x46\x65\x61ture\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x18\n\x08location\x18\x02 \x01(\x0b\x32\x06.Point\"6\n\tRouteNote\x12\x18\n\x08location\x18\x01 \x01(\x0b\x32\x06.Point\x12\x0f\n\x07message\x18\x02 \x01(\t\"b\n\x0cRouteSummary\x12\x13\n\x0bpoint_count\x18\x01 \x01(\x05\x12\x15\n\rfeature_count\x18\x02 \x01(\x05\x12\x10\n\x08\x64istance\x18\x03 \x01(\x05\x12\x14\n\x0c\x65lapsed_time\x18\x04 \x01(\x05\x32\xad\x01\n\nRouteGuide\x12 \n\nGetFeature\x12\x06.Point\x1a\x08.Feature\"\x00\x12(\n\x0cListFeatures\x12\n.Rectangle\x1a\x08.Feature\"\x00\x30\x01\x12(\n\x0bRecordRoute\x12\x06.Point\x1a\r.RouteSummary\"\x00(\x01\x12)\n\tRouteChat\x12\n.RouteNote\x1a\n.RouteNote\"\x00(\x01\x30\x01') -) -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - - - - -_POINT = _descriptor.Descriptor( - name='Point', - full_name='Point', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='latitude', full_name='Point.latitude', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='longitude', full_name='Point.longitude', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - serialized_start=21, - serialized_end=65, -) - - -_RECTANGLE = _descriptor.Descriptor( - name='Rectangle', - full_name='Rectangle', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='lo', full_name='Rectangle.lo', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='hi', full_name='Rectangle.hi', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - serialized_start=67, - serialized_end=118, -) - - -_FEATURE = _descriptor.Descriptor( - name='Feature', - full_name='Feature', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='Feature.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='location', full_name='Feature.location', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - serialized_start=120, - serialized_end=169, -) - - -_ROUTENOTE = _descriptor.Descriptor( - name='RouteNote', - full_name='RouteNote', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='location', full_name='RouteNote.location', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='message', full_name='RouteNote.message', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - serialized_start=171, - serialized_end=225, -) - - -_ROUTESUMMARY = _descriptor.Descriptor( - name='RouteSummary', - full_name='RouteSummary', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='point_count', full_name='RouteSummary.point_count', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='feature_count', full_name='RouteSummary.feature_count', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='distance', full_name='RouteSummary.distance', index=2, - number=3, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='elapsed_time', full_name='RouteSummary.elapsed_time', index=3, - number=4, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - serialized_start=227, - serialized_end=325, -) - -_RECTANGLE.fields_by_name['lo'].message_type = _POINT -_RECTANGLE.fields_by_name['hi'].message_type = _POINT -_FEATURE.fields_by_name['location'].message_type = _POINT -_ROUTENOTE.fields_by_name['location'].message_type = _POINT -DESCRIPTOR.message_types_by_name['Point'] = _POINT -DESCRIPTOR.message_types_by_name['Rectangle'] = _RECTANGLE -DESCRIPTOR.message_types_by_name['Feature'] = _FEATURE -DESCRIPTOR.message_types_by_name['RouteNote'] = _ROUTENOTE -DESCRIPTOR.message_types_by_name['RouteSummary'] = _ROUTESUMMARY - -Point = _reflection.GeneratedProtocolMessageType('Point', (_message.Message,), dict( - DESCRIPTOR = _POINT, - __module__ = 'route_guide_pb2' - # @@protoc_insertion_point(class_scope:Point) - )) -_sym_db.RegisterMessage(Point) - -Rectangle = _reflection.GeneratedProtocolMessageType('Rectangle', (_message.Message,), dict( - DESCRIPTOR = _RECTANGLE, - __module__ = 'route_guide_pb2' - # @@protoc_insertion_point(class_scope:Rectangle) - )) -_sym_db.RegisterMessage(Rectangle) - -Feature = _reflection.GeneratedProtocolMessageType('Feature', (_message.Message,), dict( - DESCRIPTOR = _FEATURE, - __module__ = 'route_guide_pb2' - # @@protoc_insertion_point(class_scope:Feature) - )) -_sym_db.RegisterMessage(Feature) - -RouteNote = _reflection.GeneratedProtocolMessageType('RouteNote', (_message.Message,), dict( - DESCRIPTOR = _ROUTENOTE, - __module__ = 'route_guide_pb2' - # @@protoc_insertion_point(class_scope:RouteNote) - )) -_sym_db.RegisterMessage(RouteNote) - -RouteSummary = _reflection.GeneratedProtocolMessageType('RouteSummary', (_message.Message,), dict( - DESCRIPTOR = _ROUTESUMMARY, - __module__ = 'route_guide_pb2' - # @@protoc_insertion_point(class_scope:RouteSummary) - )) -_sym_db.RegisterMessage(RouteSummary) - - -import abc -from grpc._adapter import fore -from grpc._adapter import rear -from grpc.framework.assembly import implementations -from grpc.framework.assembly import utilities -class EarlyAdopterRouteGuideServicer(object): - """""" - __metaclass__ = abc.ABCMeta - @abc.abstractmethod - def GetFeature(self, request): - raise NotImplementedError() - @abc.abstractmethod - def ListFeatures(self, request): - raise NotImplementedError() - @abc.abstractmethod - def RecordRoute(self, request_iterator): - raise NotImplementedError() - @abc.abstractmethod - def RouteChat(self, request_iterator): - raise NotImplementedError() -class EarlyAdopterRouteGuideServer(object): - """""" - __metaclass__ = abc.ABCMeta - @abc.abstractmethod - def start(self): - raise NotImplementedError() - @abc.abstractmethod - def stop(self): - raise NotImplementedError() -class EarlyAdopterRouteGuideStub(object): - """""" - __metaclass__ = abc.ABCMeta - @abc.abstractmethod - def GetFeature(self, request): - raise NotImplementedError() - GetFeature.async = None - @abc.abstractmethod - def ListFeatures(self, request): - raise NotImplementedError() - ListFeatures.async = None - @abc.abstractmethod - def RecordRoute(self, request_iterator): - raise NotImplementedError() - RecordRoute.async = None - @abc.abstractmethod - def RouteChat(self, request_iterator): - raise NotImplementedError() - RouteChat.async = None -def early_adopter_create_RouteGuide_server(servicer, port, root_certificates, key_chain_pairs): - method_implementations = { - "GetFeature": utilities.unary_unary_inline(servicer.GetFeature), - "ListFeatures": utilities.unary_stream_inline(servicer.ListFeatures), - "RecordRoute": utilities.stream_unary_inline(servicer.RecordRoute), - "RouteChat": utilities.stream_stream_inline(servicer.RouteChat), - } - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - request_deserializers = { - "GetFeature": route_guide_pb2.Point.FromString, - "ListFeatures": route_guide_pb2.Rectangle.FromString, - "RecordRoute": route_guide_pb2.Point.FromString, - "RouteChat": route_guide_pb2.RouteNote.FromString, - } - response_serializers = { - "GetFeature": lambda x: x.SerializeToString(), - "ListFeatures": lambda x: x.SerializeToString(), - "RecordRoute": lambda x: x.SerializeToString(), - "RouteChat": lambda x: x.SerializeToString(), - } - link = fore.activated_fore_link(port, request_deserializers, response_serializers, root_certificates, key_chain_pairs) - return implementations.assemble_service(method_implementations, link) -def early_adopter_create_RouteGuide_stub(host, port): - method_implementations = { - "GetFeature": utilities.unary_unary_inline(None), - "ListFeatures": utilities.unary_stream_inline(None), - "RecordRoute": utilities.stream_unary_inline(None), - "RouteChat": utilities.stream_stream_inline(None), - } - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - response_deserializers = { - "GetFeature": route_guide_pb2.Feature.FromString, - "ListFeatures": route_guide_pb2.Feature.FromString, - "RecordRoute": route_guide_pb2.RouteSummary.FromString, - "RouteChat": route_guide_pb2.RouteNote.FromString, - } - request_serializers = { - "GetFeature": lambda x: x.SerializeToString(), - "ListFeatures": lambda x: x.SerializeToString(), - "RecordRoute": lambda x: x.SerializeToString(), - "RouteChat": lambda x: x.SerializeToString(), - } - link = rear.activated_rear_link(host, port, request_serializers, response_deserializers) - return implementations.assemble_dynamic_inline_stub(method_implementations, link) -# @@protoc_insertion_point(module_scope) diff --git a/grpc-common/python/route_guide/route_guide_resources.py b/grpc-common/python/route_guide/route_guide_resources.py deleted file mode 100755 index 30c7711019..0000000000 --- a/grpc-common/python/route_guide/route_guide_resources.py +++ /dev/null @@ -1,53 +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. - -"""Common resources used in the gRPC route guide example.""" - -import json - -import route_guide_pb2 - - -def read_route_guide_database(): - """Reads the route guide database. - - Returns: - The full contents of the route guide database as a sequence of - route_guide_pb2.Features. - """ - feature_list = [] - with open("route_guide_db.json") as route_guide_db_file: - for item in json.load(route_guide_db_file): - feature = route_guide_pb2.Feature( - name=item["name"], - location=route_guide_pb2.Point( - latitude=item["location"]["latitude"], - longitude=item["location"]["longitude"])) - feature_list.append(feature) - return feature_list diff --git a/grpc-common/python/route_guide/route_guide_server.py b/grpc-common/python/route_guide/route_guide_server.py deleted file mode 100644 index 44bbacf5f3..0000000000 --- a/grpc-common/python/route_guide/route_guide_server.py +++ /dev/null @@ -1,134 +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. - -"""The Python implementation of the gRPC route guide server.""" - -import time -import math - -import route_guide_pb2 -import route_guide_resources - -_ONE_DAY_IN_SECONDS = 60 * 60 * 24 - - -def get_feature(feature_db, point): - """Returns Feature at given location or None.""" - for feature in feature_db: - if feature.location == point: - return feature - return None - - -def get_distance(start, end): - """Distance between two points.""" - coord_factor = 10000000.0 - lat_1 = start.latitude / coord_factor - lat_2 = end.latitude / coord_factor - lon_1 = start.latitude / coord_factor - lon_2 = end.longitude / coord_factor - lat_rad_1 = math.radians(lat_1) - lat_rad_2 = math.radians(lat_2) - delta_lat_rad = math.radians(lat_2 - lat_1) - delta_lon_rad = math.radians(lon_2 - lon_1) - - a = (pow(math.sin(delta_lat_rad / 2), 2) + - (math.cos(lat_rad_1) * math.cos(lat_rad_2) * - pow(math.sin(delta_lon_rad / 2), 2))) - c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) - R = 6371000; # metres - return R * c; - -class RouteGuideServicer(route_guide_pb2.EarlyAdopterRouteGuideServicer): - """Provides methods that implement functionality of route guide server.""" - - def __init__(self): - self.db = route_guide_resources.read_route_guide_database() - - def GetFeature(self, request, context): - feature = get_feature(self.db, request) - if feature is None: - return route_guide_pb2.Feature(name="", location=request) - else: - return feature - - def ListFeatures(self, request, context): - left = min(request.lo.longitude, request.hi.longitude) - right = max(request.lo.longitude, request.hi.longitude) - top = max(request.lo.latitude, request.hi.latitude) - bottom = min(request.lo.latitude, request.hi.latitude) - for feature in self.db: - if (feature.location.longitude >= left and - feature.location.longitude <= right and - feature.location.latitude >= bottom and - feature.location.latitude <= top): - yield feature - - def RecordRoute(self, request_iterator, context): - point_count = 0 - feature_count = 0 - distance = 0.0 - prev_point = None - - start_time = time.time() - for point in request_iterator: - point_count += 1 - if get_feature(self.db, point): - feature_count += 1 - if prev_point: - distance += get_distance(prev_point, point) - prev_point = point - - elapsed_time = time.time() - start_time - return route_guide_pb2.RouteSummary(point_count=point_count, - feature_count=feature_count, - distance=int(distance), - elapsed_time=int(elapsed_time)) - - def RouteChat(self, request_iterator, context): - prev_notes = [] - for new_note in request_iterator: - for prev_note in prev_notes: - if prev_note.location == new_note.location: - yield prev_note - prev_notes.append(new_note) - - -def serve(): - server = route_guide_pb2.early_adopter_create_RouteGuide_server( - RouteGuideServicer(), 50051, None, None) - server.start() - try: - while True: - time.sleep(_ONE_DAY_IN_SECONDS) - except KeyboardInterrupt: - server.stop() - -if __name__ == '__main__': - serve() diff --git a/grpc-common/python/route_guide/run_client.sh b/grpc-common/python/route_guide/run_client.sh deleted file mode 100755 index d2552c2858..0000000000 --- a/grpc-common/python/route_guide/run_client.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -# This is where you have cloned out the https://github.com/grpc/grpc repository -# And built gRPC Python. -# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS -GRPC_ROOT=~/github/grpc - -$GRPC_ROOT/python2.7_virtual_environment/bin/python -B route_guide_client.py diff --git a/grpc-common/python/route_guide/run_codegen.sh b/grpc-common/python/route_guide/run_codegen.sh deleted file mode 100755 index 689e0978de..0000000000 --- a/grpc-common/python/route_guide/run_codegen.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -# Runs the protoc with gRPC plugin to generate protocol messages and gRPC stubs. -protoc -I . --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` route_guide.proto diff --git a/grpc-common/python/route_guide/run_server.sh b/grpc-common/python/route_guide/run_server.sh deleted file mode 100755 index 8f759250c8..0000000000 --- a/grpc-common/python/route_guide/run_server.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -# This is where you have cloned out the https://github.com/grpc/grpc repository -# And built gRPC Python. -# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS -GRPC_ROOT=~/github/grpc - -$GRPC_ROOT/python2.7_virtual_environment/bin/python -B route_guide_server.py diff --git a/grpc-common/ruby/.gitignore b/grpc-common/ruby/.gitignore deleted file mode 100644 index 62fcb4fa94..0000000000 --- a/grpc-common/ruby/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -/.bundle/ -/.yardoc -/Gemfile.lock -/_yardoc/ -/coverage/ -/doc/ -/pkg/ -/spec/reports/ -/tmp/ -*.bundle -*.so -*.o -*.a -mkmf.log -vendor diff --git a/grpc-common/ruby/Gemfile b/grpc-common/ruby/Gemfile deleted file mode 100644 index 65d3f0ad4a..0000000000 --- a/grpc-common/ruby/Gemfile +++ /dev/null @@ -1,6 +0,0 @@ -# -*- ruby -*- -# encoding: utf-8 - -source 'https://rubygems.org/' - -gem 'grpc', :git => 'https://github.com/grpc/grpc.git', :submodules => true, glob: 'src/ruby/*.gemspec' diff --git a/grpc-common/ruby/README.md b/grpc-common/ruby/README.md deleted file mode 100644 index fecd8041e0..0000000000 --- a/grpc-common/ruby/README.md +++ /dev/null @@ -1,61 +0,0 @@ -gRPC in 3 minutes (Ruby) -======================== - -BACKGROUND -------------- -For this sample, we've already generated the server and client stubs from [helloworld.proto][] - -PREREQUISITES -------------- - -- Ruby 2.x -This requires Ruby 2.x, as the gRPC API surface uses keyword args. -If you don't have that installed locally, you can use [RVM][] to use Ruby 2.x for testing without upgrading the version of Ruby on your whole system. -RVM is also useful if you don't have the necessary privileges to update your system's Ruby. - - ```sh - $ # RVM installation as specified at https://rvm.io/rvm/install - $ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 - $ \curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2 - $ - $ # follow the instructions to ensure that your're using the latest stable version of Ruby - $ # and that the rvm command is installed - ``` -- *N.B* Make sure your run `source $HOME/.rvm/scripts/rvm` as instructed to complete the set-up of RVM. - -INSTALL -------- - -- Clone this repository -- Use bundler to install the example package's dependencies - - ```sh - $ # from this directory - $ gem install bundler # if you don't already have bundler available - $ bundle install - ``` - -Try it! -------- - -- Run the server - - ```sh - $ # from this directory - $ bundle exec ./greeter_server.rb & - ``` - -- Run the client - - ```sh - $ # from this directory - $ bundle exec ./greeter_client.rb - ``` - -Tutorial --------- - -You can find a more detailed tutorial in [gRPC Basics: Ruby](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/README.md) - -[helloworld.proto]:https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto -[RVM]:https://www.rvm.io/ diff --git a/grpc-common/ruby/greeter_client.rb b/grpc-common/ruby/greeter_client.rb deleted file mode 100755 index e6cb4bad33..0000000000 --- a/grpc-common/ruby/greeter_client.rb +++ /dev/null @@ -1,50 +0,0 @@ -#!/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/grpc-common/ruby/greeter_server.rb b/grpc-common/ruby/greeter_server.rb deleted file mode 100755 index d4f9cf7d0f..0000000000 --- a/grpc-common/ruby/greeter_server.rb +++ /dev/null @@ -1,60 +0,0 @@ -#!/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/grpc-common/ruby/grpc-demo.gemspec b/grpc-common/ruby/grpc-demo.gemspec deleted file mode 100644 index fa69eb20c1..0000000000 --- a/grpc-common/ruby/grpc-demo.gemspec +++ /dev/null @@ -1,23 +0,0 @@ -# -*- ruby -*- -# encoding: utf-8 - -Gem::Specification.new do |s| - s.name = 'grpc-demo' - s.version = '0.5.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 ruby/route_guide/*.rb`.split("\n").map do |f| - File.basename(f) - end - s.require_paths = ['lib'] - s.platform = Gem::Platform::RUBY - - s.add_dependency 'grpc', '~> 0.6' - - s.add_development_dependency 'bundler', '~> 1.7' -end diff --git a/grpc-common/ruby/lib/helloworld.rb b/grpc-common/ruby/lib/helloworld.rb deleted file mode 100644 index 82bdd78e2a..0000000000 --- a/grpc-common/ruby/lib/helloworld.rb +++ /dev/null @@ -1,18 +0,0 @@ -# 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/grpc-common/ruby/lib/helloworld_services.rb b/grpc-common/ruby/lib/helloworld_services.rb deleted file mode 100644 index 7da45ebc6b..0000000000 --- a/grpc-common/ruby/lib/helloworld_services.rb +++ /dev/null @@ -1,24 +0,0 @@ -# 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 diff --git a/grpc-common/ruby/lib/route_guide.rb b/grpc-common/ruby/lib/route_guide.rb deleted file mode 100644 index 98bac8395c..0000000000 --- a/grpc-common/ruby/lib/route_guide.rb +++ /dev/null @@ -1,37 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: route_guide.proto - -require 'google/protobuf' - -Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "examples.Point" do - optional :latitude, :int32, 1 - optional :longitude, :int32, 2 - end - add_message "examples.Rectangle" do - optional :lo, :message, 1, "examples.Point" - optional :hi, :message, 2, "examples.Point" - end - add_message "examples.Feature" do - optional :name, :string, 1 - optional :location, :message, 2, "examples.Point" - end - add_message "examples.RouteNote" do - optional :location, :message, 1, "examples.Point" - optional :message, :string, 2 - end - add_message "examples.RouteSummary" do - optional :point_count, :int32, 1 - optional :feature_count, :int32, 2 - optional :distance, :int32, 3 - optional :elapsed_time, :int32, 4 - end -end - -module Examples - Point = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.Point").msgclass - Rectangle = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.Rectangle").msgclass - Feature = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.Feature").msgclass - RouteNote = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.RouteNote").msgclass - RouteSummary = Google::Protobuf::DescriptorPool.generated_pool.lookup("examples.RouteSummary").msgclass -end diff --git a/grpc-common/ruby/lib/route_guide_services.rb b/grpc-common/ruby/lib/route_guide_services.rb deleted file mode 100644 index 6e07653c42..0000000000 --- a/grpc-common/ruby/lib/route_guide_services.rb +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# Source: route_guide.proto for package 'examples' - -require 'grpc' -require 'route_guide' - -module Examples - module RouteGuide - - # TODO: add proto service documentation here - class Service - - include GRPC::GenericService - - self.marshal_class_method = :encode - self.unmarshal_class_method = :decode - self.service_name = 'examples.RouteGuide' - - rpc :GetFeature, Point, Feature - rpc :ListFeatures, Rectangle, stream(Feature) - rpc :RecordRoute, stream(Point), RouteSummary - rpc :RouteChat, stream(RouteNote), stream(RouteNote) - end - - Stub = Service.rpc_stub_class - end -end diff --git a/grpc-common/ruby/route_guide/README.md b/grpc-common/ruby/route_guide/README.md deleted file mode 100644 index d22874799f..0000000000 --- a/grpc-common/ruby/route_guide/README.md +++ /dev/null @@ -1,285 +0,0 @@ -#gRPC Basics: Ruby - -This tutorial provides a basic Ruby programmer's introduction to working with gRPC. By walking through this example you'll learn how to: - -- Define a service in a .proto file. -- Generate server and client code using the protocol buffer compiler. -- Use the Ruby gRPC API to write a simple client and server for your service. - -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. - -This isn't a comprehensive guide to using gRPC in Ruby: more reference documentation is coming soon. - -## Why use gRPC? - -Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. - -With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. - -## Example code and setup - -The example code for our tutorial is in [grpc/grpc-common/ruby/route_guide](https://github.com/grpc/grpc-common/tree/master/ruby/route_guide). To download the example, clone the `grpc-common` repository by running the following command: -```shell -$ git clone https://github.com/grpc/grpc-common.git -``` - -Then change your current directory to `grpc-common/ruby/route_guide`: -```shell -$ cd grpc-common/ruby/route_guide -``` - -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Ruby quick start guide](https://github.com/grpc/grpc-common/tree/master/ruby). - - -## Defining the service - -Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). - -To define a service, you specify a named `service` in your .proto file: - -```protobuf -service RouteGuide { - ... -} -``` - -Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: - -- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. -```protobuf - // Obtains the feature at a given position. - rpc GetFeature(Point) returns (Feature) {} -``` - -- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. -```protobuf - // Obtains the Features available within the given Rectangle. Results are - // streamed rather than returned at once (e.g. in a response message with a - // repeated field), as the rectangle may cover a large area and contain a - // huge number of features. - rpc ListFeatures(Rectangle) returns (stream Feature) {} -``` - -- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type. -```protobuf - // Accepts a stream of Points on a route being traversed, returning a - // RouteSummary when traversal is completed. - rpc RecordRoute(stream Point) returns (RouteSummary) {} -``` - -- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -```protobuf - // Accepts a stream of RouteNotes sent while a route is being traversed, - // while receiving other RouteNotes (e.g. from other users). - rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} -``` - -Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -```protobuf -// 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; -} -``` - - -## Generating client and server code - -Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC Ruby plugin. - -If you want to run this yourself, make sure you've installed protoc and followed the gRPC Ruby plugin [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): - -Once that's done, the following command can be used to generate the ruby code. - -```shell -$ protoc -I ../../protos --ruby_out=lib --grpc_out=lib --plugin=protoc-gen-grpc=`which grpc_ruby_plugin` ../../protos/route_guide.proto -``` - -Running this command regenerates the following files in the lib directory: -- `lib/route_guide.pb` defines a module `Examples::RouteGuide` - - This contain all the protocol buffer code to populate, serialize, and retrieve our request and response message types -- `lib/route_guide_services.pb`, extends `Examples::RouteGuide` with stub and service classes - - a class `Service` for use as a base class when defining RouteGuide service implementations - - a class `Stub` that can be used to access remote RouteGuide instances - - - -## Creating the server - -First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). - -There are two parts to making our `RouteGuide` service do its job: -- Implementing the service interface generated from our service definition: doing the actual "work" of our service. -- Running a gRPC server to listen for requests from clients and return the service responses. - -You can find our example `RouteGuide` server in [grpc-common/ruby/route_guide/route_guide_server.rb](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/route_guide_server.rb). Let's take a closer look at how it works. - -### Implementing RouteGuide - -As you can see, our server has a `ServerImpl` class that extends the generated `RouteGuide::Service`: - -```ruby -# ServerImpl provides an implementation of the RouteGuide service. -class ServerImpl < RouteGuide::Service -``` - -`ServerImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. - -```ruby - def get_feature(point, _call) - name = @feature_db[{ - 'longitude' => point.longitude, - 'latitude' => point.latitude }] || '' - Feature.new(location: point, name: name) - end -``` - -The method is passed a _call for the RPC, the client's `Point` protocol buffer request, and returns a `Feature` protocol buffer. In the method we create the `Feature` with the appropriate information, and then `return` it. - -Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. - -```ruby -# in ServerImpl - - def list_features(rectangle, _call) - RectangleEnum.new(@feature_db, rectangle).each - end -``` - -As you can see, here the request object is a `Rectangle` in which our client wants to find `Feature`s, but instead of returning a simple response we need to return an [Enumerator](http://ruby-doc.org//core-2.2.0/Enumerator.html) that yields the responses. In the method, we use a helper class `RectangleEnum`, to act as an Enumerator implementation. - -Similarly, the client-side streaming method `record_route` uses an [Enumerable](http://ruby-doc.org//core-2.2.0/Enumerable.html), but here it's obtained from the call object, which we've ignored in the earlier examples. `call.each_remote_read` yields each message sent by the client in turn. - -```ruby - call.each_remote_read do |point| - ... - end -``` -Finally, let's look at our bidirectional streaming RPC `route_chat`. - -```ruby - def route_chat(notes) - q = EnumeratorQueue.new(self) - t = Thread.new do - begin - notes.each do |n| - ... - end - end - q = EnumeratorQueue.new(self) - ... - return q.each_item - end -``` - -Here the method receives an [Enumerable](http://ruby-doc.org//core-2.2.0/Enumerable.html), but also returns an [Enumerator](http://ruby-doc.org//core-2.2.0/Enumerator.html) that yields the responses. The implementation demonstrates how to set these up so that the requests and responses can be handled concurrently. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. - -### Starting the server - -Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: - -```ruby - s = GRPC::RpcServer.new - s.add_http2_port(port) - logger.info("... running insecurely on #{port}") - s.handle(ServerImpl.new(feature_db)) - s.run -``` -As you can see, we build and start our server using a `GRPC::RpcServer`. To do this, we: - -1. Create an instance of our service implementation class `ServerImpl`. -2. Specify the address and port we want to use to listen for client requests using the builder's `add_http2_port` method. -3. Register our service implementation with the `GRPC::RpcServer`. -4. Call `run` on the`GRPC::RpcServer` to create and start an RPC server for our service. - - -## Creating the client - -In this section, we'll look at creating a Ruby client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/ruby/route_guide/route_guide_client.rb](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/route_guide_client.rb). - -### Creating a stub - -To call service methods, we first need to create a *stub*. - -We use the `Stub` class of the `RouteGuide` module generated from our .proto. - -```ruby - stub = RouteGuide::Stub.new('localhost:50051') -``` - -### Calling service methods - -Now let's look at how we call our service methods. Note that the gRPC Ruby only provides *blocking/synchronous* versions of each method: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception. - -#### Simple RPC - -Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. - -```ruby -GET_FEATURE_POINTS = [ - Point.new(latitude: 409_146_138, longitude: -746_188_906), - Point.new(latitude: 0, longitude: 0) -] -.. - GET_FEATURE_POINTS.each do |pt| - resp = stub.get_feature(pt) - ... - p "- found '#{resp.name}' at #{pt.inspect}" - end -``` - -As you can see, we create and populate a request protocol buffer object (in our case `Point`), and create a response protocol buffer object for the server to fill in. Finally, we call the method on the stub, passing it the context, request, and response. If the method returns `OK`, then we can read the response information from the server from our response object. - - -#### Streaming RPCs - -Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `list_features`, which returns an `Enumerable` of `Features` - -```ruby - resps = stub.list_features(LIST_FEATURES_RECT) - resps.each do |r| - p "- found '#{r.name}' at #{r.location.inspect}" - end -``` - -The client-side streaming method `record_route` is similar, except there we pass the server an `Enumerable`. - -```ruby - ... - reqs = RandomRoute.new(features, points_on_route) - resp = stub.record_route(reqs.each, deadline) - ... -``` - -Finally, let's look at our bidirectional streaming RPC `route_chat`. In this case, we pass `Enumerable` to the method and get back an `Enumerable`. - -```ruby - resps = stub.route_chat(ROUTE_CHAT_NOTES) - resps.each { |r| p "received #{r.inspect}" } -``` - -Although it's not shown well by this example, each enumerable is independent of the other - both the client and server can read and write in any order — the streams operate completely independently. - -## Try it out! - -Build client and server: - -```shell -$ # from grpc-common/ruby -$ gem install bundler && bundle install -``` -Run the server, which will listen on port 50051: -```shell -$ # from grpc-common/ruby -$ bundle exec route_guide/route_guide_server.rb ../node/route_guide/route_guide_db.json & -``` -Run the client (in a different terminal): -```shell -$ # from grpc-common/ruby -$ bundle exec route_guide/route_guide_client.rb ../node/route_guide/route_guide_db.json & -``` - diff --git a/grpc-common/ruby/route_guide/route_guide_client.rb b/grpc-common/ruby/route_guide/route_guide_client.rb deleted file mode 100755 index 181623a68a..0000000000 --- a/grpc-common/ruby/route_guide/route_guide_client.rb +++ /dev/null @@ -1,165 +0,0 @@ -#!/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 Route Guide service. -# -# Usage: $ path/to/route_guide_client.rb path/to/route_guide_db.json & - -this_dir = File.expand_path(File.dirname(__FILE__)) -lib_dir = File.join(File.dirname(this_dir), 'lib') -$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) - -require 'grpc' -require 'route_guide_services' - -include Examples - -GET_FEATURE_POINTS = [ - Point.new(latitude: 409_146_138, longitude: -746_188_906), - Point.new(latitude: 0, longitude: 0) -] - -# runs a GetFeature rpc. -# -# - once with a point known to be present in the sample route database -# - once with a point that is not in the sample database -def run_get_feature(stub) - p 'GetFeature' - p '----------' - GET_FEATURE_POINTS.each do |pt| - resp = stub.get_feature(pt) - if resp.name != '' - p "- found '#{resp.name}' at #{pt.inspect}" - else - p "- found nothing at #{pt.inspect}" - end - end -end - -LIST_FEATURES_RECT = Rectangle.new( - lo: Point.new(latitude: 400_000_000, longitude: -750_000_000), - hi: Point.new(latitude: 420_000_000, longitude: -730_000_000)) - -# runs a ListFeatures rpc. -# -# - the rectangle to chosen to include most of the known features -# in the sample db. -def run_list_features(stub) - p 'ListFeatures' - p '------------' - resps = stub.list_features(LIST_FEATURES_RECT) - resps.each do |r| - p "- found '#{r.name}' at #{r.location.inspect}" - end -end - -# RandomRoute provides an Enumerable that yields a random 'route' of points -# from a list of Features. -class RandomRoute - def initialize(features, size) - @features = features - @size = size - end - - # yields a point, waiting between 0 and 1 seconds between each yield - # - # @return an Enumerable that yields a random point - def each - return enum_for(:each) unless block_given? - @size.times do - json_feature = @features[rand(0..@features.length)] - next if json_feature.nil? - location = json_feature['location'] - pt = Point.new( - Hash[location.each_pair.map { |k, v| [k.to_sym, v] }]) - p "- next point is #{pt.inspect}" - yield pt - sleep(rand(0..1)) - end - end -end - -# runs a RecordRoute rpc. -# -# - the rectangle to chosen to include most of the known features -# in the sample db. -def run_record_route(stub, features) - p 'RecordRoute' - p '-----------' - points_on_route = 10 # arbitrary - deadline = points_on_route # as delay b/w each is max 1 second - reqs = RandomRoute.new(features, points_on_route) - resp = stub.record_route(reqs.each, deadline) - p "summary: #{resp.inspect}" -end - -ROUTE_CHAT_NOTES = [ - RouteNote.new(message: 'doh - a deer', - location: Point.new(latitude: 0, longitude: 0)), - RouteNote.new(message: 'ray - a drop of golden sun', - location: Point.new(latitude: 0, longitude: 1)), - RouteNote.new(message: 'me - the name I call myself', - location: Point.new(latitude: 1, longitude: 0)), - RouteNote.new(message: 'fa - a longer way to run', - location: Point.new(latitude: 1, longitude: 1)), - RouteNote.new(message: 'soh - with needle and a thread', - location: Point.new(latitude: 0, longitude: 1)) -] - -# runs a RouteChat rpc. -# -# sends a canned set of route notes and prints out the responses. -def run_route_chat(stub) - p 'Route Chat' - p '----------' - # TODO: decouple sending and receiving, i.e have the response enumerator run - # on its own thread. - resps = stub.route_chat(ROUTE_CHAT_NOTES) - resps.each { |r| p "received #{r.inspect}" } -end - -def main - stub = RouteGuide::Stub.new('localhost:50051') - run_get_feature(stub) - run_list_features(stub) - run_route_chat(stub) - if ARGV.length == 0 - p 'no feature database; skipping record_route' - exit - end - raw_data = [] - File.open(ARGV[0]) do |f| - raw_data = MultiJson.load(f.read) - end - run_record_route(stub, raw_data) -end - -main diff --git a/grpc-common/ruby/route_guide/route_guide_server.rb b/grpc-common/ruby/route_guide/route_guide_server.rb deleted file mode 100755 index 2b2b8084ef..0000000000 --- a/grpc-common/ruby/route_guide/route_guide_server.rb +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/env ruby -# -*- coding: utf-8 -*- - -# 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 Route Guide service. -# -# Usage: $ path/to/route_guide_server.rb path/to/route_guide_db.json & - -this_dir = File.expand_path(File.dirname(__FILE__)) -lib_dir = File.join(File.dirname(this_dir), 'lib') -$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) - -require 'grpc' -require 'multi_json' -require 'route_guide_services' - -include Examples -COORD_FACTOR = 1e7 -RADIUS = 637_100 - -# Determines the distance between two points. -def calculate_distance(point_a, point_b) - to_radians = proc { |x| x * Math::PI / 180 } - lat_a = point_a.latitude / COORD_FACTOR - lat_b = point_b.latitude / COORD_FACTOR - long_a = point_a.longitude / COORD_FACTOR - long_b = point_b.longitude / COORD_FACTOR - φ1 = to_radians.call(lat_a) - φ2 = to_radians.call(lat_b) - Δφ = to_radians.call(lat_a - lat_b) - Δλ = to_radians.call(long_a - long_b) - a = Math.sin(Δφ / 2)**2 + - Math.cos(φ1) * Math.cos(φ2) + - Math.sin(Δλ / 2)**2 - (2 * RADIUS * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))).to_i -end - -# RectangleEnum provides an Enumerator of the points in a feature_db within a -# given Rectangle. -class RectangleEnum - # @param [Hash] feature_db - # @param [Rectangle] bounds - def initialize(feature_db, bounds) - @feature_db = feature_db - @bounds = bounds - lats = [@bounds.lo.latitude, @bounds.hi.latitude] - longs = [@bounds.lo.longitude, @bounds.hi.longitude] - @lo_lat, @hi_lat = lats.min, lats.max - @lo_long, @hi_long = longs.min, longs.max - end - - # in? determines if location lies within the bounds of this instances - # Rectangle. - def in?(location) - location['longitude'] >= @lo_long && - location['longitude'] <= @hi_long && - location['latitude'] >= @lo_lat && - location['latitude'] <= @hi_lat - end - - # each yields the features in the instances feature_db that lie within the - # instance rectangle. - def each - return enum_for(:each) unless block_given? - @feature_db.each_pair do |location, name| - next unless in?(location) - next if name.nil? || name == '' - pt = Point.new( - Hash[location.each_pair.map { |k, v| [k.to_sym, v] }]) - yield Feature.new(location: pt, name: name) - end - end -end - -# A EnumeratorQueue wraps a Queue to yield the items added to it. -class EnumeratorQueue - extend Forwardable - def_delegators :@q, :push - - def initialize(sentinel) - @q = Queue.new - @sentinel = sentinel - @received_notes = {} - end - - def each_item - return enum_for(:each_item) unless block_given? - loop do - r = @q.pop - break if r.equal?(@sentinel) - fail r if r.is_a? Exception - yield r - end - end -end - -# ServerImpl provides an implementation of the RouteGuide service. -class ServerImpl < RouteGuide::Service - # @param [Hash] feature_db {location => name} - def initialize(feature_db) - @feature_db = feature_db - @received_notes = Hash.new { |h, k| h[k] = [] } - end - - def get_feature(point, _call) - name = @feature_db[{ - 'longitude' => point.longitude, - 'latitude' => point.latitude }] || '' - Feature.new(location: point, name: name) - end - - def list_features(rectangle, _call) - RectangleEnum.new(@feature_db, rectangle).each - end - - def record_route(call) - started, elapsed_time = 0, 0 - distance, count, features, last = 0, 0, 0, nil - call.each_remote_read do |point| - count += 1 - name = @feature_db[{ - 'longitude' => point.longitude, - 'latitude' => point.latitude }] || '' - features += 1 unless name == '' - if last.nil? - last = point - started = Time.now.to_i - next - end - elapsed_time = Time.now.to_i - started - distance += calculate_distance(point, last) - last = point - end - RouteSummary.new(point_count: count, - feature_count: features, - distance: distance, - elapsed_time: elapsed_time) - end - - def route_chat(notes) - q = EnumeratorQueue.new(self) - # run a separate thread that processes the incoming requests - t = Thread.new do - begin - notes.each do |n| - key = { - 'latitude' => n.location.latitude, - 'longitude' => n.location.longitude - } - earlier_msgs = @received_notes[key] - @received_notes[key] << n.message - # send back the earlier messages at this point - earlier_msgs.each do |r| - q.push(RouteNote.new(location: n.location, message: r)) - end - end - q.push(self) # signal completion - rescue StandardError => e - q.push(e) # signal completion via an error - end - end - q.each_item - end -end - -def main - if ARGV.length == 0 - fail 'Please specify the path to the route_guide json database' - end - raw_data = [] - File.open(ARGV[0]) do |f| - raw_data = MultiJson.load(f.read) - end - feature_db = Hash[raw_data.map { |x| [x['location'], x['name']] }] - port = '0.0.0.0:50051' - s = GRPC::RpcServer.new - s.add_http2_port(port) - GRPC.logger.info("... running insecurely on #{port}") - s.handle(ServerImpl.new(feature_db)) - s.run -end - -main -- cgit v1.2.3 From 0a268216c2c8e112351b7ed038da04bf50b9eb5a Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Thu, 27 Aug 2015 14:38:38 -0700 Subject: replace all grpc-common occurances with examples --- README.md | 4 ++-- doc/grpc-auth-support.md | 2 +- doc/interop-test-descriptions.md | 2 +- examples/README.md | 31 +++++++++++++++-------------- examples/cpp/README.md | 18 ++++++++--------- examples/cpp/cpptutorial.md | 20 +++++++++---------- examples/cpp/helloworld/README.md | 20 +++++++++---------- examples/csharp/README.md | 2 +- examples/csharp/route_guide/README.md | 18 ++++++++--------- examples/node/README.md | 6 +++--- examples/node/route_guide/README.md | 18 ++++++++--------- examples/objective-c/auth_sample/README.md | 14 ++++++------- examples/objective-c/helloworld/README.md | 14 ++++++------- examples/objective-c/route_guide/README.md | 18 ++++++++--------- examples/php/README.md | 10 +++++----- examples/php/route_guide/README.md | 16 +++++++-------- examples/python/helloworld/README.md | 16 +++++++-------- examples/python/route_guide/README.md | 18 ++++++++--------- examples/ruby/README.md | 4 ++-- examples/ruby/grpc-demo.gemspec | 2 +- examples/ruby/route_guide/README.md | 24 +++++++++++----------- src/csharp/README.md | 6 +++--- src/objective-c/README.md | 2 +- src/objective-c/tests/LocalClearTextTests.m | 2 +- 24 files changed, 144 insertions(+), 143 deletions(-) diff --git a/README.md b/README.md index f830629816..599e6bcee0 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Copyright 2015 Google Inc. #Documentation -You can find more detailed documentation and examples in the [grpc-common repository](http://github.com/grpc/grpc-common). +You can find more detailed documentation and examples in the [doc](doc) and [examples](examples) directories respectively. #Installation @@ -95,7 +95,7 @@ messages are delivered in the order they were sent. #Protocol -The [gRPC protocol](https://github.com/grpc/grpc-common/blob/master/PROTOCOL-HTTP2.md) specifies the abstract requirements for communication between +The [gRPC protocol](examples/PROTOCOL-HTTP2.md) specifies the abstract requirements for communication between clients and servers. A concrete embedding over HTTP/2 completes the picture by fleshing out the details of each of the required operations. diff --git a/doc/grpc-auth-support.md b/doc/grpc-auth-support.md index b9ef299332..800fbedd80 100644 --- a/doc/grpc-auth-support.md +++ b/doc/grpc-auth-support.md @@ -264,7 +264,7 @@ call.requestMetadata[@"Authorization"] = [@"Bearer " stringByAppendingString:acc [call start]; ``` -You can see a working example app, with a more detailed explanation, [here](https://github.com/grpc/grpc-common/tree/master/objective-c/auth_sample). +You can see a working example app, with a more detailed explanation, [here](examples/objective-c/auth_sample). ### Authenticating with Google (Python) ```python diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md index 75110e8977..aa14a7cfdf 100644 --- a/doc/interop-test-descriptions.md +++ b/doc/interop-test-descriptions.md @@ -4,7 +4,7 @@ Interoperability Test Case Descriptions Client and server use [test.proto](https://github.com/grpc/grpc/blob/master/test/proto/test.proto) and the [gRPC over HTTP/2 v2 -protocol](https://github.com/grpc/grpc-common/blob/master/PROTOCOL-HTTP2.md). +protocol](examples/doc/PROTOCOL-HTTP2.md). Client ------ diff --git a/examples/README.md b/examples/README.md index 5939db3ab5..6465115e18 100644 --- a/examples/README.md +++ b/examples/README.md @@ -10,19 +10,20 @@ Hello World example. You'll find more tutorials and reference docs in this repos ## Quick start You can find quick start guides for each language, including installation instructions, examples, and tutorials here: -* [C++](https://github.com/grpc/grpc-common/tree/master/cpp) -* [Java](https://github.com/grpc/grpc-common/tree/master/java) -* [Go](https://github.com/grpc/grpc-common/tree/master/go) -* [Ruby](https://github.com/grpc/grpc-common/tree/master/ruby) -* [Node.js](https://github.com/grpc/grpc-common/tree/master/node) -* [Android Java](https://github.com/grpc/grpc-common/tree/master/java/android) -* [Python](https://github.com/grpc/grpc-common/tree/master/python/helloworld) -* [C#](https://github.com/grpc/grpc-common/tree/master/csharp) -* [Objective-C](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide) +* [C++](examples/cpp) +* [Java](https://github.com/grpc/grpc-java/tree/master/examples) +* [Go](https://github.com/grpc/grpc-go/tree/master/examples) +* [Ruby](examples/ruby) +* [Node.js](examples/node) +* [Android Java](examples/java/android) +* [Python](examples/python/helloworld) +* [C#](examples/csharp) +* [Objective-C](examples/objective-c/route_guide) +* [PHP](examples/php) ## What's in this repository? -The `grpc-common` repository contains documentation, resources, and examples +The `examples` directory contains documentation, resources, and examples for all gRPC users. You can find examples and instructions specific to your favourite language in the relevant subdirectory. @@ -93,8 +94,8 @@ Hello World method. - Create a Go client that accesses the same Java server. -The complete code for the example is available in the `grpc-common` GitHub -repository. We use the Git versioning system for source code management: +The complete code for the example is available in the `examples` +directory. We use the Git versioning system for source code management: however, you don't need to know anything about Git to follow along other than how to install and run a few git commands. @@ -400,8 +401,8 @@ and client uses interface code generated from the same proto that we used for the Java example. So, for example, if we visit the [`go` example -directory](https://github.com/grpc/grpc-common/tree/master/go) and look at the -[`greeter_client`](https://github.com/grpc/grpc-common/blob/master/go/greeter_client/main.go), +directory](https://github.com/grpc/grpc-go/tree/master/examples) and look at the +[`greeter_client`](https://github.com/grpc/grpc-go/blob/master/examples/greeter_client/main.go), we can see that like the Java client, it connects to a `Greeter` service at `localhost:50051` and uses a stub to call the `SayHello` method with a `HelloRequest`: @@ -446,4 +447,4 @@ $ greeter_client ## Read more! - You can find links to language-specific tutorials, examples, and other docs in each language's [quick start](#quickstart). -- [gRPC Authentication Support](https://github.com/grpc/grpc-common/blob/master/grpc-auth-support.md) introduces authentication support in gRPC with supported mechanisms and examples. +- [gRPC Authentication Support](doc/grpc-auth-support.md) introduces authentication support in gRPC with supported mechanisms and examples. diff --git a/examples/cpp/README.md b/examples/cpp/README.md index e0a09ff8b8..70418b4425 100644 --- a/examples/cpp/README.md +++ b/examples/cpp/README.md @@ -7,21 +7,21 @@ To install gRPC on your system, follow the instructions here: ## Hello C++ gRPC! -Here's how to build and run the C++ implementation of the [Hello World](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto) example used in [Getting started](https://github.com/grpc/grpc-common). +Here's how to build and run the C++ implementation of the [Hello World](examples/protos/helloworld.proto) example used in [Getting started](https://github.com/grpc/grpc/tree/master/examples). -The example code for this and our other examples lives in the `grpc-common` -GitHub repository. Clone this repository to your local machine by running the +The example code for this and our other examples lives in the `examples` +directory. Clone this repository to your local machine by running the following command: ```sh -$ git clone https://github.com/grpc/grpc-common.git +$ git clone https://github.com/grpc/grpc.git ``` -Change your current directory to grpc-common/cpp/helloworld +Change your current directory to examples/cpp/helloworld ```sh -$ cd grpc-common/cpp/helloworld/ +$ cd examples/cpp/helloworld/ ``` @@ -41,9 +41,9 @@ $ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto ### Client and server implementations -The client implementation is at [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). +The client implementation is at [greeter_client.cc](examples/cpp/helloworld/greeter_client.cc). -The server implementation is at [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). +The server implementation is at [greeter_server.cc](examples/cpp/helloworld/greeter_server.cc). ### Try it! Build client and server: @@ -62,4 +62,4 @@ If things go smoothly, you will see the "Greeter received: Hello world" in the c ## Tutorial -You can find a more detailed tutorial in [gRPC Basics: C++](https://github.com/grpc/grpc-common/blob/master/cpp/cpptutorial.md) +You can find a more detailed tutorial in [gRPC Basics: C++](examples/cpp/cpptutorial.md) diff --git a/examples/cpp/cpptutorial.md b/examples/cpp/cpptutorial.md index c19b472744..22be42d500 100644 --- a/examples/cpp/cpptutorial.md +++ b/examples/cpp/cpptutorial.md @@ -6,7 +6,7 @@ This tutorial provides a basic C++ programmer's introduction to working with gRP - Generate server and client code using the protocol buffer compiler. - Use the C++ gRPC API to write a simple client and server for your service. -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. +It assumes that you have read the [Getting started](https://github.com/grpc/grpc/tree/master/examples) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. This isn't a comprehensive guide to using gRPC in C++: more reference documentation is coming soon. @@ -18,22 +18,22 @@ With gRPC we can define our service once in a .proto file and implement clients ## Example code and setup -The example code for our tutorial is in [grpc/grpc-common/cpp/route_guide](https://github.com/grpc/grpc-common/tree/master/cpp/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +The example code for our tutorial is in [examples/cpp/route_guide](examples/cpp/route_guide). To download the example, clone this repository by running the following command: ```shell -$ git clone https://github.com/grpc/grpc-common.git +$ git clone https://github.com/grpc/grpc.git ``` -Then change your current directory to `grpc-common/cpp/route_guide`: +Then change your current directory to `examples/cpp/route_guide`: ```shell -$ cd grpc-common/cpp/route_guide +$ cd examples/cpp/route_guide ``` -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the C++ quick start guide](https://github.com/grpc/grpc-common/tree/master/cpp). +You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the C++ quick start guide](examples/cpp). ## Defining the service -Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). +Our first step (as you'll know from [Getting started](examples/) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`examples/protos/route_guide.proto`](examples/protos/route_guide.proto). To define a service, you specify a named `service` in your .proto file: @@ -91,7 +91,7 @@ message Point { Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. -For simplicity, we've provided a [makefile](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): +For simplicity, we've provided a [makefile](examples/cpp/route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): ```shell $ make route_guide.grpc.pb.cc route_guide.pb.cc @@ -126,7 +126,7 @@ There are two parts to making our `RouteGuide` service do its job: - Implementing the service interface generated from our service definition: doing the actual "work" of our service. - Running a gRPC server to listen for requests from clients and return the service responses. -You can find our example `RouteGuide` server in [grpc-common/cpp/route_guide/route_guide_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_server.cc). Let's take a closer look at how it works. +You can find our example `RouteGuide` server in [examples/cpp/route_guide/route_guide_server.cc](examples/cpp/route_guide/route_guide_server.cc). Let's take a closer look at how it works. ### Implementing RouteGuide @@ -236,7 +236,7 @@ As you can see, we build and start our server using a `ServerBuilder`. To do thi ## Creating the client -In this section, we'll look at creating a C++ client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/cpp/route_guide/route_guide_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/route_guide/route_guide_client.cc). +In this section, we'll look at creating a C++ client for our `RouteGuide` service. You can see our complete example client code in [examples/cpp/route_guide/route_guide_client.cc](examples/cpp/route_guide/route_guide_client.cc). ### Creating a stub diff --git a/examples/cpp/helloworld/README.md b/examples/cpp/helloworld/README.md index c406051e80..641aadd52d 100644 --- a/examples/cpp/helloworld/README.md +++ b/examples/cpp/helloworld/README.md @@ -6,19 +6,19 @@ Make sure you have installed gRPC on your system. Follow the instructions here: ### Get the tutorial source code -The example code for this and our other examples lives in the `grpc-common` -GitHub repository. Clone this repository to your local machine by running the +The example code for this and our other examples lives in the `examples` +directory. Clone this repository to your local machine by running the following command: ```sh -$ git clone https://github.com/grpc/grpc-common.git +$ git clone https://github.com/grpc/grpc.git ``` -Change your current directory to grpc-common/cpp/helloworld +Change your current directory to examples/cpp/helloworld ```sh -$ cd grpc-common/cpp/helloworld/ +$ cd examples/cpp/helloworld/ ``` ### Defining a service @@ -34,7 +34,7 @@ types as protocol buffer message types. Both the client and the server use interface code generated from the service definition. Here's our example service definition, defined using protocol buffers IDL in -[helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto). The `Greeting` +[helloworld.proto](examples/protos/helloworld.proto). The `Greeting` service has one method, `hello`, that lets the server receive a single `HelloRequest` message from the remote client containing the user's name, then send back @@ -124,7 +124,7 @@ $ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto } ``` -For a working example, refer to [greeter_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_client.cc). +For a working example, refer to [greeter_client.cc](examples/cpp/helloworld/greeter_client.cc). ### Writing a server @@ -152,7 +152,7 @@ For a working example, refer to [greeter_client.cc](https://github.com/grpc/grpc std::unique_ptr server(builder.BuildAndStart()); ``` -For a working example, refer to [greeter_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_server.cc). +For a working example, refer to [greeter_server.cc](examples/cpp/helloworld/greeter_server.cc). ### Writing asynchronous client and server @@ -194,7 +194,7 @@ The channel and stub creation code is the same as the sync client. } ``` -For a working example, refer to [greeter_async_client.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_async_client.cc). +For a working example, refer to [greeter_async_client.cc](examples/cpp/helloworld/greeter_async_client.cc). #### Async server @@ -253,7 +253,7 @@ maintain the state of each rpc and use the address of it as the unique tag. For simplicity the server only uses one completion queue for all events, and runs a main loop in `HandleRpcs` to query the queue. -For a working example, refer to [greeter_async_server.cc](https://github.com/grpc/grpc-common/blob/master/cpp/helloworld/greeter_async_server.cc). +For a working example, refer to [greeter_async_server.cc](examples/cpp/helloworld/greeter_async_server.cc). diff --git a/examples/csharp/README.md b/examples/csharp/README.md index 77d1aaf2e6..fcdcc735f9 100644 --- a/examples/csharp/README.md +++ b/examples/csharp/README.md @@ -69,4 +69,4 @@ On Linux or Mac, use `mono GreeterServer.exe` and `mono GreeterClient.exe` to ru Tutorial -------- -You can find a more detailed tutorial in [gRPC Basics: C#](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/README.md) +You can find a more detailed tutorial in [gRPC Basics: C#](examples/csharp/route_guide/README.md) diff --git a/examples/csharp/route_guide/README.md b/examples/csharp/route_guide/README.md index 35c6024bcf..c3262c9b8a 100644 --- a/examples/csharp/route_guide/README.md +++ b/examples/csharp/route_guide/README.md @@ -6,7 +6,7 @@ This tutorial provides a basic C# programmer's introduction to working with gRPC - Generate server and client code using the protocol buffer compiler. - Use the C# gRPC API to write a simple client and server for your service. -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial only uses the proto2 version of the protocol buffers language, as proto3 support for C# is not ready yet (see [protobuf C# README](https://github.com/google/protobuf/tree/master/csharp#proto2--proto3)). +It assumes that you have read the [Getting started](https://github.com/grpc/grpc/tree/master/examples) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial only uses the proto2 version of the protocol buffers language, as proto3 support for C# is not ready yet (see [protobuf C# README](https://github.com/google/protobuf/tree/master/csharp#proto2--proto3)). This isn't a comprehensive guide to using gRPC in C#: more reference documentation is coming soon. @@ -18,13 +18,13 @@ With gRPC we can define our service once in a .proto file and implement clients ## Example code and setup -The example code for our tutorial is in [grpc/grpc-common/csharp/route_guide](https://github.com/grpc/grpc-common/tree/master/csharp/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +The example code for our tutorial is in [examples/csharp/route_guide](examples/csharp/route_guide). To download the example, clone this repository by running the following command: ```shell -$ git clone https://github.com/google/grpc-common.git +$ git clone https://github.com/grpc/grpc.git ``` -All the files for this tutorial are in the directory `grpc-common/csharp/route_guide`. -Open the solution `grpc-common/csharp/route_guide/RouteGuide.sln` from Visual Studio (or Monodevelop on Linux). +All the files for this tutorial are in the directory `examples/csharp/route_guide`. +Open the solution `examples/csharp/route_guide/RouteGuide.sln` from Visual Studio (or Monodevelop on Linux). On Windows, you should not need to do anything besides opening the solution. All the needed dependencies will be restored for you automatically by the `Grpc` NuGet package upon building the solution. @@ -34,7 +34,7 @@ able to generate the server and client interface code and run the examples. Foll ## Defining the service -Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/csharp/route_guide/RouteGuide/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/sharp/route_guide/RouteGuide/protos/route_guide.proto). +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc/tree/master/examples)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`examples/csharp/route_guide/RouteGuide/protos/route_guide.proto`](examples/csharp/route_guide/RouteGuide/protos/route_guide.proto). To define a service, you specify a named `service` in your .proto file: @@ -127,7 +127,7 @@ There are two parts to making our `RouteGuide` service do its job: - Implementing the service interface generated from our service definition: doing the actual "work" of our service. - Running a gRPC server to listen for requests from clients and return the service responses. -You can find our example `RouteGuide` server in [grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/RouteGuideServer/RouteGuideServerImpl.cs). Let's take a closer look at how it works. +You can find our example `RouteGuide` server in [examples/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs](examples/csharp/route_guide/RouteGuideServer/RouteGuideServerImpl.cs). Let's take a closer look at how it works. ### Implementing RouteGuide @@ -288,7 +288,7 @@ As you can see, we build and start our server using `Grpc.Core.Server` class. To ## Creating the client -In this section, we'll look at creating a C# client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/csharp/route_guide/RouteGuideClient/Program.cs](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/RouteGuideClient/Program.cs). +In this section, we'll look at creating a C# client for our `RouteGuide` service. You can see our complete example client code in [examples/csharp/route_guide/RouteGuideClient/Program.cs](examples/csharp/route_guide/RouteGuideClient/Program.cs). ### Creating a stub @@ -390,7 +390,7 @@ Finally, let's look at our bidirectional streaming RPC `RouteChat`. In this case Build client and server: -Open the solution `grpc-common/csharp/route_guide/RouteGuide.sln` from Visual Studio (or Monodevelop on Linux) and hit "Build". +Open the solution `examples/csharp/route_guide/RouteGuide.sln` from Visual Studio (or Monodevelop on Linux) and hit "Build". Run the server, which will listen on port 50052: ``` diff --git a/examples/node/README.md b/examples/node/README.md index 8c24a960a3..045fe51ede 100644 --- a/examples/node/README.md +++ b/examples/node/README.md @@ -18,13 +18,13 @@ INSTALL - Clone this repository ```sh - $ git clone https://github.com/grpc/grpc-common.git + $ git clone https://github.com/grpc/grpc.git ``` - Install this package's dependencies ```sh - $ cd grpc-common/node + $ cd examples/node $ npm install ``` @@ -57,4 +57,4 @@ You can find a more detailed tutorial in [gRPC Basics: Node.js][] [homebrew]:http://brew.sh [linuxbrew]:https://github.com/Homebrew/linuxbrew#installation [gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install -[gRPC Basics: Node.js]:https://github.com/grpc/grpc-common/blob/master/node/route_guide/README.md +[gRPC Basics: Node.js]:https://github.com/grpc/grpc/blob/master/examples/node/route_guide/README.md diff --git a/examples/node/route_guide/README.md b/examples/node/route_guide/README.md index 5460c9905d..2efc5a5da5 100644 --- a/examples/node/route_guide/README.md +++ b/examples/node/route_guide/README.md @@ -5,7 +5,7 @@ This tutorial provides a basic Node.js programmer's introduction to working with - Define a service in a .proto file. - Use the Node.js gRPC API to write a simple client and server for your service. -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. +It assumes that you have read the [Getting started](https://github.com/grpc/grpc/tree/master/examples) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. This isn't a comprehensive guide to using gRPC in Node.js: more reference documentation is coming soon. @@ -17,22 +17,22 @@ With gRPC we can define our service once in a .proto file and implement clients ## Example code and setup -The example code for our tutorial is in [grpc/grpc-common/node/route_guide](https://github.com/grpc/grpc-common/tree/master/node/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +The example code for our tutorial is in [examples/node/route_guide](examples/node/route_guide). To download the example, clone this repository by running the following command: ```shell -$ git clone https://github.com/grpc/grpc-common.git +$ git clone https://github.com/grpc/grpc.git ``` -Then change your current directory to `grpc-common/node/route_guide`: +Then change your current directory to `examples/node/route_guide`: ```shell -$ cd grpc-common/node/route_guide +$ cd examples/node/route_guide ``` -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Node.js quick start guide](https://github.com/grpc/grpc-common/tree/master/node). +You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Node.js quick start guide](examples/node). ## Defining the service -Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc/tree/master/examples)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`examples/protos/route_guide.proto`](examples/protos/route_guide.proto). To define a service, you specify a named `service` in your .proto file: @@ -110,7 +110,7 @@ There are two parts to making our `RouteGuide` service do its job: - Implementing the service interface generated from our service definition: doing the actual "work" of our service. - Running a gRPC server to listen for requests from clients and return the service responses. -You can find our example `RouteGuide` server in [grpc-common/node/route_guide/route_guide_server.js](https://github.com/grpc/grpc-common/blob/master/node/route_guide/route_guide_server.js). Let's take a closer look at how it works. +You can find our example `RouteGuide` server in [examples/node/route_guide/route_guide_server.js](examples/node/route_guide/route_guide_server.js). Let's take a closer look at how it works. ### Implementing RouteGuide @@ -244,7 +244,7 @@ As you can see, we build and start our server with the following steps: ## Creating the client -In this section, we'll look at creating a Node.js client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/node/route_guide/route_guide_client.js](https://github.com/grpc/grpc-common/blob/master/node/route_guide/route_guide_client.js). +In this section, we'll look at creating a Node.js client for our `RouteGuide` service. You can see our complete example client code in [examples/node/route_guide/route_guide_client.js](examples/node/route_guide/route_guide_client.js). ### Creating a stub diff --git a/examples/objective-c/auth_sample/README.md b/examples/objective-c/auth_sample/README.md index 4ca4982f53..3dbe7e334c 100644 --- a/examples/objective-c/auth_sample/README.md +++ b/examples/objective-c/auth_sample/README.md @@ -9,8 +9,8 @@ headers. - Read response metadata from a call, which is equivalent to HTTP response headers and trailers. It assumes you know the basics on how to make gRPC API calls using the Objective-C client library, -as shown in the [Hello World](https://github.com/grpc/grpc-common/tree/master/objective-c/helloworld) -or [Route Guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide) tutorials, +as shown in the [Hello World](examples/objective-c/helloworld) +or [Route Guide](examples/objective-c/route_guide) tutorials, and are familiar with OAuth2 concepts like _access token_. - [Example code and setup](#setup) @@ -22,15 +22,15 @@ and are familiar with OAuth2 concepts like _access token_. ## Example code and setup -The example code for our tutorial is in [grpc/grpc-common/objective-c/auth_sample](https://github.com/grpc/grpc-common/tree/master/objective-c/auth_sample). -To download the example, clone the `grpc-common` repository by running the following command: +The example code for our tutorial is in [examples/objective-c/auth_sample](examples/objective-c/auth_sample). +To download the example, clone this repository by running the following command: ```shell -$ git clone https://github.com/grpc/grpc-common.git +$ git clone https://github.com/grpc/grpc.git ``` -Then change your current directory to `grpc-common/objective-c/auth_sample`: +Then change your current directory to `examples/objective-c/auth_sample`: ```shell -$ cd grpc-common/objective-c/auth_sample +$ cd examples/objective-c/auth_sample ``` Our example is a simple application with two views. The first one lets a user sign in and out using diff --git a/examples/objective-c/helloworld/README.md b/examples/objective-c/helloworld/README.md index 685339e84a..3b852f857f 100644 --- a/examples/objective-c/helloworld/README.md +++ b/examples/objective-c/helloworld/README.md @@ -8,21 +8,21 @@ testing). You can obtain the latter by following [these setup instructions](http ## Hello Objective-C gRPC! -Here's how to build and run the Objective-C implementation of the [Hello World](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto) -example used in [Getting started](https://github.com/grpc/grpc-common). +Here's how to build and run the Objective-C implementation of the [Hello World](examples/protos/helloworld.proto) +example used in [Getting started](https://github.com/grpc/grpc/tree/master/examples). -The example code for this and our other examples lives in the `grpc-common` GitHub repository. Clone +The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command: ```sh -$ git clone https://github.com/grpc/grpc-common.git +$ git clone https://github.com/grpc/grpc.git ``` -Change your current directory to `grpc-common/objective-c/helloworld` +Change your current directory to `examples/objective-c/helloworld` ```sh -$ cd grpc-common/objective-c/helloworld +$ cd examples/objective-c/helloworld ``` ### Try it! @@ -53,4 +53,4 @@ responds with a `HLWHelloResponse`, which contains a string that is then output ## Tutorial -You can find a more detailed tutorial in [gRPC Basics: Objective-C](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/README.md). +You can find a more detailed tutorial in [gRPC Basics: Objective-C](examples/objective-c/route_guide/README.md). diff --git a/examples/objective-c/route_guide/README.md b/examples/objective-c/route_guide/README.md index bbbd9e020d..dd20a07995 100644 --- a/examples/objective-c/route_guide/README.md +++ b/examples/objective-c/route_guide/README.md @@ -43,15 +43,15 @@ code is limited by the dynamic nature of the language. ## Example code and setup -The example code for our tutorial is in [grpc/grpc-common/objective-c/route_guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide). -To download the example, clone the `grpc-common` repository by running the following command: +The example code for our tutorial is in [examples/objective-c/route_guide](examples/objective-c/route_guide). +To download the example, clone this repository by running the following command: ```shell -$ git clone https://github.com/grpc/grpc-common.git +$ git clone https://github.com/grpc/grpc.git ``` -Then change your current directory to `grpc-common/objective-c/route_guide`: +Then change your current directory to `examples/objective-c/route_guide`: ```shell -$ cd grpc-common/objective-c/route_guide +$ cd examples/objective-c/route_guide ``` Our example is a simple route mapping application that lets clients get information about features @@ -97,7 +97,7 @@ a client library from it, and how to create an app that uses that library. First let's look at how the service we're using is defined. A gRPC *service* and its method *request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). -You can see the complete .proto file for our example in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). +You can see the complete .proto file for our example in [`examples/protos/route_guide.proto`](examples/protos/route_guide.proto). To define a service, you specify a named `service` in your .proto file: @@ -177,9 +177,9 @@ option objc_class_prefix = "RTG"; Next we need to generate the gRPC client interfaces from our .proto service definition. We do this using the protocol buffer compiler (`protoc`) with a special gRPC Objective-C plugin. -For simplicity, we've provided a [Podspec file](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/RouteGuide.podspec) +For simplicity, we've provided a [Podspec file](examples/objective-c/route_guide/RouteGuide.podspec) that runs `protoc` for you with the appropriate plugin, input, and output, and describes how to -compile the generated files. You just need to run in this directory (`grpc-common/objective-c/route_guide`): +compile the generated files. You just need to run in this directory (`examples/objective-c/route_guide`): ```shell $ pod install @@ -211,7 +211,7 @@ definition; just replace the name (matching the file name), version, and other m ## Creating the client In this section, we'll look at creating an Objective-C client for our `RouteGuide` service. You can -see our complete example client code in [grpc-common/objective-c/route_guide/ViewControllers.m](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/ViewControllers.m). +see our complete example client code in [examples/objective-c/route_guide/ViewControllers.m](examples/objective-c/route_guide/ViewControllers.m). (Note: In your apps, for maintainability and readability reasons, you shouldn't put all of your view controllers in a single file; it's done here only to simplify the learning process). diff --git a/examples/php/README.md b/examples/php/README.md index 247235adfd..5c327f10fa 100644 --- a/examples/php/README.md +++ b/examples/php/README.md @@ -18,13 +18,13 @@ INSTALL - Clone this repository ```sh - $ git clone https://github.com/grpc/grpc-common.git + $ git clone https://github.com/grpc/grpc.git ``` - Install composer ``` - $ cd grpc-common/php + $ cd examples/php $ curl -sS https://getcomposer.org/installer | php $ php composer.phar install ``` @@ -36,14 +36,14 @@ TRY IT! Please follow the instruction in [Node][] to run the server ``` - $ cd grpc-common/node + $ cd examples/node $ nodejs greeter_server.js ``` - Run the client ``` - $ cd grpc-common/php + $ cd examples/php $ ./run_greeter_client.sh ``` @@ -61,4 +61,4 @@ Coming soon [homebrew]:http://brew.sh [linuxbrew]:https://github.com/Homebrew/linuxbrew#installation [gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install -[Node]:https://github.com/grpc/grpc-common/tree/master/node +[Node]:https://github.com/grpc/grpc/tree/master/examples/node diff --git a/examples/php/route_guide/README.md b/examples/php/route_guide/README.md index 084661a5eb..e5230ae4e4 100644 --- a/examples/php/route_guide/README.md +++ b/examples/php/route_guide/README.md @@ -8,7 +8,7 @@ This tutorial provides a basic PHP programmer's introduction to working with gRP It assumes a passing familiarity with [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto2 version of the protocol buffers language. -Also note that currently you can only create clients in PHP for gRPC services - you can find out how to create gRPC servers in our other tutorials, e.g. [Node.js](https://github.com/grpc/grpc-common/tree/master/node/route_guide). +Also note that currently you can only create clients in PHP for gRPC services - you can find out how to create gRPC servers in our other tutorials, e.g. [Node.js](examples/node/route_guide). This isn't a comprehensive guide to using gRPC in PHP: more reference documentation is coming soon. @@ -29,14 +29,14 @@ With gRPC you can define your service once in a .proto file and implement client ## Example code and setup -The example code for our tutorial is in [grpc/grpc-common/php/route_guide](https://github.com/grpc/grpc-common/tree/master/php/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +The example code for our tutorial is in [examples/php/route_guide](examples/php/route_guide). To download the example, clone this repository by running the following command: ```shell -$ git clone https://github.com/grpc/grpc-common.git +$ git clone https://github.com/grpc/grpc.git ``` -Then change your current directory to `grpc-common/php/route_guide`: +Then change your current directory to `examples/php/route_guide`: ```shell -$ cd grpc-common/php/route_guide +$ cd examples/php/route_guide ``` Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. @@ -68,7 +68,7 @@ The next sections guide you step-by-step through how this proto service is defin ## Defining the service -First let's look at how the service we're using is defined. A gRPC *service* and its method *request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file for our example in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). +First let's look at how the service we're using is defined. A gRPC *service* and its method *request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file for our example in [`examples/protos/route_guide.proto`](examples/protos/route_guide.proto). To define a service, you specify a named `service` in your .proto file: @@ -128,7 +128,7 @@ message Point { The PHP client stub implementation of the proto files can be generated by the [`protoc-gen-php`](https://github.com/datto/protobuf-php) tool. To install the tool: ```sh -$ cd grpc-common/php +$ cd examples/php $ php composer.phar install $ cd vendor/datto/protobuf-php $ gem install rake ronn @@ -159,7 +159,7 @@ The file contains: ## Creating the client -In this section, we'll look at creating a PHP client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/php/route_guide/route_guide_client.php](https://github.com/grpc/grpc-common/blob/master/php/route_guide/route_guide_client.php). +In this section, we'll look at creating a PHP client for our `RouteGuide` service. You can see our complete example client code in [examples/php/route_guide/route_guide_client.php](examples/php/route_guide/route_guide_client.php). ### Constructing a client object diff --git a/examples/python/helloworld/README.md b/examples/python/helloworld/README.md index 0a6a718bae..d199c401ec 100644 --- a/examples/python/helloworld/README.md +++ b/examples/python/helloworld/README.md @@ -1,6 +1,6 @@ # gRPC Python Hello World -This is a quick introduction with a simple example and installation instructions: for a more complete tutorial see [gRPC Basics: Python](https://github.com/grpc/grpc-common/tree/master/python/route_guide). +This is a quick introduction with a simple example and installation instructions: for a more complete tutorial see [gRPC Basics: Python](examples/python/route_guide). ### Install gRPC Make sure you have built gRPC Python from source on your system. Follow the instructions here: @@ -12,19 +12,19 @@ have cloned the [gRPC git repo](https://github.com/grpc/grpc). ### Get the source code -The example code for our Hello World and our other examples live in the `grpc-common` -GitHub repository. Clone this repository to your local machine by running the +The example code for our Hello World and our other examples live in the `examples` +directory. Clone this repository to your local machine by running the following command: ```sh -$ git clone https://github.com/grpc/grpc-common.git +$ git clone https://github.com/grpc/grpc.git ``` -Change your current directory to grpc-common/python/helloworld +Change your current directory to examples/python/helloworld ```sh -$ cd grpc-common/python/helloworld/ +$ cd examples/python/helloworld/ ``` ### Defining a service @@ -96,7 +96,7 @@ been generated for you (helloworld_pb2.py). ### The client -Client-side code can be found in [greeter_client.py](https://github.com/grpc/grpc-common/blob/master/python/helloworld/greeter_client.py). +Client-side code can be found in [greeter_client.py](examples/python/helloworld/greeter_client.py). You can run the client using: @@ -107,7 +107,7 @@ $ ./run_client.sh ### The server -Server side code can be found in [greeter_server.py](https://github.com/grpc/grpc-common/blob/master/python/helloworld/greeter_server.py). +Server side code can be found in [greeter_server.py](examples/python/helloworld/greeter_server.py). You can run the server using: diff --git a/examples/python/route_guide/README.md b/examples/python/route_guide/README.md index 91bef0ac00..dc97892ea5 100644 --- a/examples/python/route_guide/README.md +++ b/examples/python/route_guide/README.md @@ -6,7 +6,7 @@ This tutorial provides a basic Python programmer's introduction to working with - Generate server and client code using the protocol buffer compiler. - Use the Python gRPC API to write a simple client and server for your service. -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. +It assumes that you have read the [Getting started](https://github.com/grpc/grpc/tree/master/examples) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. This isn't a comprehensive guide to using gRPC in Python: more reference documentation is coming soon. @@ -19,21 +19,21 @@ With gRPC you can define your service once in a .proto file and implement client ## Example code and setup -The example code for this tutorial is in [grpc/grpc-common/python/route_guide](https://github.com/grpc/grpc-common/tree/master/python/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +The example code for this tutorial is in [examples/python/route_guide](examples/python/route_guide). To download the example, clone this repository by running the following command: ```shell -$ git clone https://github.com/grpc/grpc-common.git +$ git clone https://github.com/grpc/grpc.git ``` -Then change your current directory to `grpc-common/python/route_guide`: +Then change your current directory to `examples/python/route_guide`: ```shell -$ cd grpc-common/python/route_guide +$ cd examples/python/route_guide ``` -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Python quick start guide](https://github.com/grpc/grpc-common/tree/master/python). +You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Python quick start guide](examples/python). ## Defining the service -Your first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). +Your first step (as you'll know from [Getting started](https://github.com/grpc/grpc/tree/master/examples)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`examples/protos/route_guide.proto`](examples/protos/route_guide.proto). To define a service, you specify a named `service` in your .proto file: @@ -115,7 +115,7 @@ Creating and running a `RouteGuide` server breaks down into two work items: - Implementing the servicer interface generated from our service definition with functions that perform the actual "work" of the service. - Running a gRPC server to listen for requests from clients and transmit responses. -You can find the example `RouteGuide` server in [grpc-common/python/route_guide/route_guide_server.py](https://github.com/grpc/grpc-common/blob/master/python/route_guide/route_guide_server.py). +You can find the example `RouteGuide` server in [examples/python/route_guide/route_guide_server.py](examples/python/route_guide/route_guide_server.py). ### Implementing RouteGuide @@ -222,7 +222,7 @@ Because `start()` does not block you may need to sleep-loop if there is nothing ## Creating the client -You can see the complete example client code in [grpc-common/python/route_guide/route_guide_client.py](https://github.com/grpc/grpc-common/blob/master/python/route_guide/route_guide_client.py). +You can see the complete example client code in [examples/python/route_guide/route_guide_client.py](examples/python/route_guide/route_guide_client.py). ### Creating a stub diff --git a/examples/ruby/README.md b/examples/ruby/README.md index fecd8041e0..dc21f5dd49 100644 --- a/examples/ruby/README.md +++ b/examples/ruby/README.md @@ -55,7 +55,7 @@ Try it! Tutorial -------- -You can find a more detailed tutorial in [gRPC Basics: Ruby](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/README.md) +You can find a more detailed tutorial in [gRPC Basics: Ruby](examples/ruby/route_guide/README.md) -[helloworld.proto]:https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto +[helloworld.proto]:examples/protos/helloworld.proto [RVM]:https://www.rvm.io/ diff --git a/examples/ruby/grpc-demo.gemspec b/examples/ruby/grpc-demo.gemspec index fa69eb20c1..2cc1eb8f41 100644 --- a/examples/ruby/grpc-demo.gemspec +++ b/examples/ruby/grpc-demo.gemspec @@ -6,7 +6,7 @@ Gem::Specification.new do |s| s.version = '0.5.0' s.authors = ['gRPC Authors'] s.email = 'temiola@google.com' - s.homepage = 'https://github.com/grpc/grpc-common' + s.homepage = 'https://github.com/grpc/grpc' s.summary = 'gRPC Ruby overview sample' s.description = 'Simple demo of using gRPC from Ruby' diff --git a/examples/ruby/route_guide/README.md b/examples/ruby/route_guide/README.md index d22874799f..c7231fb43f 100644 --- a/examples/ruby/route_guide/README.md +++ b/examples/ruby/route_guide/README.md @@ -6,7 +6,7 @@ This tutorial provides a basic Ruby programmer's introduction to working with gR - Generate server and client code using the protocol buffer compiler. - Use the Ruby gRPC API to write a simple client and server for your service. -It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. +It assumes that you have read the [Getting started](https://github.com/grpc/grpc/tree/master/examples) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release:you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. This isn't a comprehensive guide to using gRPC in Ruby: more reference documentation is coming soon. @@ -18,22 +18,22 @@ With gRPC we can define our service once in a .proto file and implement clients ## Example code and setup -The example code for our tutorial is in [grpc/grpc-common/ruby/route_guide](https://github.com/grpc/grpc-common/tree/master/ruby/route_guide). To download the example, clone the `grpc-common` repository by running the following command: +The example code for our tutorial is in [examples/ruby/route_guide](examples/ruby/route_guide). To download the example, clone this repository by running the following command: ```shell -$ git clone https://github.com/grpc/grpc-common.git +$ git clone https://github.com/grpc/grpc.git ``` -Then change your current directory to `grpc-common/ruby/route_guide`: +Then change your current directory to `examples/ruby/route_guide`: ```shell -$ cd grpc-common/ruby/route_guide +$ cd examples/ruby/route_guide ``` -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Ruby quick start guide](https://github.com/grpc/grpc-common/tree/master/ruby). +You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the Ruby quick start guide](examples/ruby). ## Defining the service -Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto). +Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc/tree/master/examples)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`examples/protos/route_guide.proto`](examples/protos/route_guide.proto). To define a service, you specify a named `service` in your .proto file: @@ -116,7 +116,7 @@ There are two parts to making our `RouteGuide` service do its job: - Implementing the service interface generated from our service definition: doing the actual "work" of our service. - Running a gRPC server to listen for requests from clients and return the service responses. -You can find our example `RouteGuide` server in [grpc-common/ruby/route_guide/route_guide_server.rb](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/route_guide_server.rb). Let's take a closer look at how it works. +You can find our example `RouteGuide` server in [examples/ruby/route_guide/route_guide_server.rb](examples/ruby/route_guide/route_guide_server.rb). Let's take a closer look at how it works. ### Implementing RouteGuide @@ -199,7 +199,7 @@ As you can see, we build and start our server using a `GRPC::RpcServer`. To do t ## Creating the client -In this section, we'll look at creating a Ruby client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/ruby/route_guide/route_guide_client.rb](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/route_guide_client.rb). +In this section, we'll look at creating a Ruby client for our `RouteGuide` service. You can see our complete example client code in [examples/ruby/route_guide/route_guide_client.rb](examples/ruby/route_guide/route_guide_client.rb). ### Creating a stub @@ -269,17 +269,17 @@ Although it's not shown well by this example, each enumerable is independent of Build client and server: ```shell -$ # from grpc-common/ruby +$ # from examples/ruby $ gem install bundler && bundle install ``` Run the server, which will listen on port 50051: ```shell -$ # from grpc-common/ruby +$ # from examples/ruby $ bundle exec route_guide/route_guide_server.rb ../node/route_guide/route_guide_db.json & ``` Run the client (in a different terminal): ```shell -$ # from grpc-common/ruby +$ # from examples/ruby $ bundle exec route_guide/route_guide_client.rb ../node/route_guide/route_guide_db.json & ``` diff --git a/src/csharp/README.md b/src/csharp/README.md index bb5e165986..30523b3bd2 100644 --- a/src/csharp/README.md +++ b/src/csharp/README.md @@ -19,7 +19,7 @@ Usage: Windows That will also pull all the transitive dependencies (including the native libraries that gRPC C# is internally using). -- Helloworld project example can be found in https://github.com/grpc/grpc-common/tree/master/csharp. +- Helloworld project example can be found in https://github.com/grpc/grpc/tree/master/examples/csharp. Usage: Linux (Mono) -------------- @@ -50,7 +50,7 @@ Usage: Linux (Mono) - Add NuGet package `Grpc` as a dependency (Project -> Add NuGet packages). -- Helloworld project example can be found in https://github.com/grpc/grpc-common/tree/master/csharp. +- Helloworld project example can be found in https://github.com/grpc/grpc/tree/master/examples/csharp. Usage: MacOS (Mono) -------------- @@ -73,7 +73,7 @@ Usage: MacOS (Mono) - *You will be able to build your project in Xamarin Studio, but to run or test it, you will need to run it under 64-bit version of Mono.* -- Helloworld project example can be found in https://github.com/grpc/grpc-common/tree/master/csharp. +- Helloworld project example can be found in https://github.com/grpc/grpc/tree/master/examples/csharp. Building: Windows ----------------- diff --git a/src/objective-c/README.md b/src/objective-c/README.md index e997b76d14..6c27657def 100644 --- a/src/objective-c/README.md +++ b/src/objective-c/README.md @@ -30,7 +30,7 @@ proceed. ## Write your API declaration in proto format For this you can consult the [Protocol Buffers][]' official documentation, or learn from a quick -example [here](https://github.com/grpc/grpc-common#defining-a-service). +example [here](https://github.com/grpc/grpc/tree/master/examples#defining-a-service). ## Integrate a proto library in your project diff --git a/src/objective-c/tests/LocalClearTextTests.m b/src/objective-c/tests/LocalClearTextTests.m index 4317614dd9..d01fe91afa 100644 --- a/src/objective-c/tests/LocalClearTextTests.m +++ b/src/objective-c/tests/LocalClearTextTests.m @@ -42,7 +42,7 @@ #import // These tests require a gRPC "RouteGuide" sample server to be running locally. You can compile and -// run one by following the instructions here: https://github.com/grpc/grpc-common/blob/master/cpp/cpptutorial.md#try-it-out +// run one by following the instructions here: https://github.com/grpc/grpc/blob/master/examples/cpp/cpptutorial.md#try-it-out // Be sure to have the C gRPC library installed in your system (for example, by having followed the // instructions at https://github.com/grpc/homebrew-grpc -- cgit v1.2.3 From 23b371214154233153e95478f31f7b83dc850360 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Thu, 27 Aug 2015 14:40:38 -0700 Subject: remove examples/pubsub --- examples/pubsub/README | 22 ------ examples/pubsub/main.cc | 146 ----------------------------------- examples/pubsub/publisher.cc | 121 ----------------------------- examples/pubsub/publisher.h | 66 ---------------- examples/pubsub/publisher_test.cc | 153 ------------------------------------- examples/pubsub/subscriber.cc | 115 ---------------------------- examples/pubsub/subscriber.h | 67 ---------------- examples/pubsub/subscriber_test.cc | 152 ------------------------------------ 8 files changed, 842 deletions(-) delete mode 100644 examples/pubsub/README delete mode 100644 examples/pubsub/main.cc delete mode 100644 examples/pubsub/publisher.cc delete mode 100644 examples/pubsub/publisher.h delete mode 100644 examples/pubsub/publisher_test.cc delete mode 100644 examples/pubsub/subscriber.cc delete mode 100644 examples/pubsub/subscriber.h delete mode 100644 examples/pubsub/subscriber_test.cc diff --git a/examples/pubsub/README b/examples/pubsub/README deleted file mode 100644 index 36fcb08483..0000000000 --- a/examples/pubsub/README +++ /dev/null @@ -1,22 +0,0 @@ -NOTE: This example does not build and is being updated. -Experimental example code, likely to change. -Users should not attempt to run this code till this warning is removed. - -C++ Client implementation for Cloud Pub/Sub service -(https://developers.google.com/apis-explorer/#p/pubsub/v1beta1/). - -"Google Cloud Pub/Sub" API needs to be enabled at -https://console.developers.google.com/project to open the access for a client. -Select the project name, select the "APIs" under "APIs & auth", and turn -on "Google Cloud Pub/Sub" API. - -To run the client from Google Compute Engine (GCE), the GCE instance needs to -be created with scope "https://www.googleapis.com/auth/cloud-platform" as below: - -gcloud compute instances create instance-name - --image debian-7 --scopes https://www.googleapis.com/auth/cloud-platform - - -To run the client: -make pubsub_client -bins/opt/pubsub_client --project_id="your project id" diff --git a/examples/pubsub/main.cc b/examples/pubsub/main.cc deleted file mode 100644 index 32102dcb5c..0000000000 --- a/examples/pubsub/main.cc +++ /dev/null @@ -1,146 +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. - * - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "examples/pubsub/publisher.h" -#include "examples/pubsub/subscriber.h" -#include "test/cpp/util/test_config.h" - -DEFINE_int32(server_port, 443, "Server port."); -DEFINE_string(server_host, "pubsub-staging.googleapis.com", - "Server host to connect to"); -DEFINE_string(project_id, "", "GCE project id such as stoked-keyword-656"); - -namespace { - -const char kTopic[] = "testtopics"; -const char kSubscriptionName[] = "testsubscription"; -const char kMessageData[] = "Test Data"; - -} // namespace - -int main(int argc, char** argv) { - grpc::testing::InitTest(&argc, &argv, true); - gpr_log(GPR_INFO, "Start PUBSUB client"); - - std::ostringstream ss; - - ss << FLAGS_server_host << ":" << FLAGS_server_port; - - std::shared_ptr creds = grpc::GoogleDefaultCredentials(); - std::shared_ptr channel = - grpc::CreateChannel(ss.str(), creds, grpc::ChannelArguments()); - - grpc::examples::pubsub::Publisher publisher(channel); - grpc::examples::pubsub::Subscriber subscriber(channel); - - GPR_ASSERT(FLAGS_project_id != ""); - ss.str(""); - ss << "/topics/" << FLAGS_project_id << "/" << kTopic; - grpc::string topic = ss.str(); - - ss.str(""); - ss << FLAGS_project_id << "/" << kSubscriptionName; - grpc::string subscription_name = ss.str(); - - // Clean up test topic and subcription if they exist before. - grpc::string subscription_topic; - if (subscriber.GetSubscription(subscription_name, &subscription_topic) - .IsOk()) { - subscriber.DeleteSubscription(subscription_name); - } - - if (publisher.GetTopic(topic).IsOk()) publisher.DeleteTopic(topic); - - grpc::Status s = publisher.CreateTopic(topic); - gpr_log(GPR_INFO, "Create topic returns code %d, %s", s.code(), - s.details().c_str()); - GPR_ASSERT(s.IsOk()); - - s = publisher.GetTopic(topic); - gpr_log(GPR_INFO, "Get topic returns code %d, %s", s.code(), - s.details().c_str()); - GPR_ASSERT(s.IsOk()); - - std::vector topics; - s = publisher.ListTopics(FLAGS_project_id, &topics); - gpr_log(GPR_INFO, "List topic returns code %d, %s", s.code(), - s.details().c_str()); - bool topic_found = false; - for (unsigned int i = 0; i < topics.size(); i++) { - if (topics[i] == topic) topic_found = true; - gpr_log(GPR_INFO, "topic: %s", topics[i].c_str()); - } - GPR_ASSERT(s.IsOk()); - GPR_ASSERT(topic_found); - - s = subscriber.CreateSubscription(topic, subscription_name); - gpr_log(GPR_INFO, "create subscrption returns code %d, %s", s.code(), - s.details().c_str()); - GPR_ASSERT(s.IsOk()); - - s = publisher.Publish(topic, kMessageData); - gpr_log(GPR_INFO, "Publish %s returns code %d, %s", kMessageData, s.code(), - s.details().c_str()); - GPR_ASSERT(s.IsOk()); - - grpc::string data; - s = subscriber.Pull(subscription_name, &data); - gpr_log(GPR_INFO, "Pull %s", data.c_str()); - - s = subscriber.DeleteSubscription(subscription_name); - gpr_log(GPR_INFO, "Delete subscription returns code %d, %s", s.code(), - s.details().c_str()); - GPR_ASSERT(s.IsOk()); - - s = publisher.DeleteTopic(topic); - gpr_log(GPR_INFO, "Delete topic returns code %d, %s", s.code(), - s.details().c_str()); - GPR_ASSERT(s.IsOk()); - - subscriber.Shutdown(); - publisher.Shutdown(); - return 0; -} diff --git a/examples/pubsub/publisher.cc b/examples/pubsub/publisher.cc deleted file mode 100644 index fd38ca92ed..0000000000 --- a/examples/pubsub/publisher.cc +++ /dev/null @@ -1,121 +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. - * - */ - -#include - -#include - -#include "examples/pubsub/publisher.h" - -using tech::pubsub::Topic; -using tech::pubsub::DeleteTopicRequest; -using tech::pubsub::GetTopicRequest; -using tech::pubsub::PublisherService; -using tech::pubsub::ListTopicsRequest; -using tech::pubsub::ListTopicsResponse; -using tech::pubsub::PublishRequest; -using tech::pubsub::PubsubMessage; - -namespace grpc { -namespace examples { -namespace pubsub { - -Publisher::Publisher(std::shared_ptr channel) - : stub_(PublisherService::NewStub(channel)) {} - -void Publisher::Shutdown() { stub_.reset(); } - -Status Publisher::CreateTopic(const grpc::string& topic) { - Topic request; - Topic response; - request.set_name(topic); - ClientContext context; - - return stub_->CreateTopic(&context, request, &response); -} - -Status Publisher::ListTopics(const grpc::string& project_id, - std::vector* topics) { - ListTopicsRequest request; - ListTopicsResponse response; - ClientContext context; - - std::ostringstream ss; - ss << "cloud.googleapis.com/project in (/projects/" << project_id << ")"; - request.set_query(ss.str()); - - Status s = stub_->ListTopics(&context, request, &response); - - tech::pubsub::Topic topic; - for (int i = 0; i < response.topic_size(); i++) { - topic = response.topic(i); - topics->push_back(topic.name()); - } - - return s; -} - -Status Publisher::GetTopic(const grpc::string& topic) { - GetTopicRequest request; - Topic response; - ClientContext context; - - request.set_topic(topic); - - return stub_->GetTopic(&context, request, &response); -} - -Status Publisher::DeleteTopic(const grpc::string& topic) { - DeleteTopicRequest request; - proto2::Empty response; - ClientContext context; - - request.set_topic(topic); - - return stub_->DeleteTopic(&context, request, &response); -} - -Status Publisher::Publish(const grpc::string& topic, const grpc::string& data) { - PublishRequest request; - proto2::Empty response; - ClientContext context; - - request.mutable_message()->set_data(data); - request.set_topic(topic); - - return stub_->Publish(&context, request, &response); -} - -} // namespace pubsub -} // namespace examples -} // namespace grpc diff --git a/examples/pubsub/publisher.h b/examples/pubsub/publisher.h deleted file mode 100644 index 02e6194b0b..0000000000 --- a/examples/pubsub/publisher.h +++ /dev/null @@ -1,66 +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. - * - */ - -#ifndef GRPC_EXAMPLES_PUBSUB_PUBLISHER_H -#define GRPC_EXAMPLES_PUBSUB_PUBLISHER_H - -#include - -#include "examples/pubsub/pubsub.grpc.pb.h" - -namespace grpc { -namespace examples { -namespace pubsub { - -class Publisher { - public: - Publisher(std::shared_ptr channel); - void Shutdown(); - - Status CreateTopic(const grpc::string& topic); - Status GetTopic(const grpc::string& topic); - Status DeleteTopic(const grpc::string& topic); - Status ListTopics(const grpc::string& project_id, - std::vector* topics); - - Status Publish(const grpc::string& topic, const grpc::string& data); - - private: - std::unique_ptr stub_; -}; - -} // namespace pubsub -} // namespace examples -} // namespace grpc - -#endif // GRPC_EXAMPLES_PUBSUB_PUBLISHER_H diff --git a/examples/pubsub/publisher_test.cc b/examples/pubsub/publisher_test.cc deleted file mode 100644 index c2eb295ef2..0000000000 --- a/examples/pubsub/publisher_test.cc +++ /dev/null @@ -1,153 +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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "examples/pubsub/publisher.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -using grpc::Channel; - -namespace grpc { -namespace testing { -namespace { - -const char kProjectId[] = "project id"; -const char kTopic[] = "test topic"; -const char kMessageData[] = "test message data"; - -class PublisherServiceImpl : public tech::pubsub::PublisherService::Service { - public: - Status CreateTopic(::grpc::ServerContext* context, - const ::tech::pubsub::Topic* request, - ::tech::pubsub::Topic* response) GRPC_OVERRIDE { - EXPECT_EQ(request->name(), kTopic); - return Status::OK; - } - - Status Publish(ServerContext* context, - const ::tech::pubsub::PublishRequest* request, - ::proto2::Empty* response) GRPC_OVERRIDE { - EXPECT_EQ(request->message().data(), kMessageData); - return Status::OK; - } - - Status GetTopic(ServerContext* context, - const ::tech::pubsub::GetTopicRequest* request, - ::tech::pubsub::Topic* response) GRPC_OVERRIDE { - EXPECT_EQ(request->topic(), kTopic); - return Status::OK; - } - - Status ListTopics( - ServerContext* context, const ::tech::pubsub::ListTopicsRequest* request, - ::tech::pubsub::ListTopicsResponse* response) GRPC_OVERRIDE { - std::ostringstream ss; - ss << "cloud.googleapis.com/project in (/projects/" << kProjectId << ")"; - EXPECT_EQ(request->query(), ss.str()); - response->add_topic()->set_name(kTopic); - return Status::OK; - } - - Status DeleteTopic(ServerContext* context, - const ::tech::pubsub::DeleteTopicRequest* request, - ::proto2::Empty* response) GRPC_OVERRIDE { - EXPECT_EQ(request->topic(), kTopic); - return Status::OK; - } -}; - -class PublisherTest : public ::testing::Test { - protected: - // Setup a server and a client for PublisherService. - void SetUp() GRPC_OVERRIDE { - int port = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << port; - ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), - grpc::InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - - channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(), - ChannelArguments()); - - publisher_.reset(new grpc::examples::pubsub::Publisher(channel_)); - } - - void TearDown() GRPC_OVERRIDE { - server_->Shutdown(); - publisher_->Shutdown(); - } - - std::ostringstream server_address_; - std::unique_ptr server_; - PublisherServiceImpl service_; - - std::shared_ptr channel_; - - std::unique_ptr publisher_; -}; - -TEST_F(PublisherTest, TestPublisher) { - EXPECT_TRUE(publisher_->CreateTopic(kTopic).IsOk()); - - EXPECT_TRUE(publisher_->Publish(kTopic, kMessageData).IsOk()); - - EXPECT_TRUE(publisher_->GetTopic(kTopic).IsOk()); - - std::vector topics; - EXPECT_TRUE(publisher_->ListTopics(kProjectId, &topics).IsOk()); - EXPECT_EQ(topics.size(), static_cast(1)); - EXPECT_EQ(topics[0], kTopic); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - gpr_log(GPR_INFO, "Start test ..."); - int result = RUN_ALL_TESTS(); - return result; -} diff --git a/examples/pubsub/subscriber.cc b/examples/pubsub/subscriber.cc deleted file mode 100644 index 0818f501db..0000000000 --- a/examples/pubsub/subscriber.cc +++ /dev/null @@ -1,115 +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. - * - */ - -#include - -#include "examples/pubsub/subscriber.h" - -using tech::pubsub::Topic; -using tech::pubsub::DeleteTopicRequest; -using tech::pubsub::GetTopicRequest; -using tech::pubsub::SubscriberService; -using tech::pubsub::ListTopicsRequest; -using tech::pubsub::ListTopicsResponse; -using tech::pubsub::PublishRequest; -using tech::pubsub::PubsubMessage; - -namespace grpc { -namespace examples { -namespace pubsub { - -Subscriber::Subscriber(std::shared_ptr channel) - : stub_(SubscriberService::NewStub(channel)) {} - -void Subscriber::Shutdown() { stub_.reset(); } - -Status Subscriber::CreateSubscription(const grpc::string& topic, - const grpc::string& name) { - tech::pubsub::Subscription request; - tech::pubsub::Subscription response; - ClientContext context; - - request.set_topic(topic); - request.set_name(name); - - return stub_->CreateSubscription(&context, request, &response); -} - -Status Subscriber::GetSubscription(const grpc::string& name, - grpc::string* topic) { - tech::pubsub::GetSubscriptionRequest request; - tech::pubsub::Subscription response; - ClientContext context; - - request.set_subscription(name); - - Status s = stub_->GetSubscription(&context, request, &response); - *topic = response.topic(); - return s; -} - -Status Subscriber::DeleteSubscription(const grpc::string& name) { - tech::pubsub::DeleteSubscriptionRequest request; - proto2::Empty response; - ClientContext context; - - request.set_subscription(name); - - return stub_->DeleteSubscription(&context, request, &response); -} - -Status Subscriber::Pull(const grpc::string& name, grpc::string* data) { - tech::pubsub::PullRequest request; - tech::pubsub::PullResponse response; - ClientContext context; - - request.set_subscription(name); - Status s = stub_->Pull(&context, request, &response); - if (s.IsOk()) { - tech::pubsub::PubsubEvent event = response.pubsub_event(); - if (event.has_message()) { - *data = event.message().data(); - } - tech::pubsub::AcknowledgeRequest ack; - proto2::Empty empty; - ClientContext ack_context; - ack.set_subscription(name); - ack.add_ack_id(response.ack_id()); - stub_->Acknowledge(&ack_context, ack, &empty); - } - return s; -} - -} // namespace pubsub -} // namespace examples -} // namespace grpc diff --git a/examples/pubsub/subscriber.h b/examples/pubsub/subscriber.h deleted file mode 100644 index c5b1df0d3e..0000000000 --- a/examples/pubsub/subscriber.h +++ /dev/null @@ -1,67 +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. - * - */ - -#ifndef GRPC_EXAMPLES_PUBSUB_SUBSCRIBER_H -#define GRPC_EXAMPLES_PUBSUB_SUBSCRIBER_H - -#include - -#include "examples/pubsub/pubsub.grpc.pb.h" - -namespace grpc { -namespace examples { -namespace pubsub { - -class Subscriber { - public: - Subscriber(std::shared_ptr channel); - void Shutdown(); - - Status CreateSubscription(const grpc::string& topic, - const grpc::string& name); - - Status GetSubscription(const grpc::string& name, grpc::string* topic); - - Status DeleteSubscription(const grpc::string& name); - - Status Pull(const grpc::string& name, grpc::string* data); - - private: - std::unique_ptr stub_; -}; - -} // namespace pubsub -} // namespace examples -} // namespace grpc - -#endif // GRPC_EXAMPLES_PUBSUB_SUBSCRIBER_H diff --git a/examples/pubsub/subscriber_test.cc b/examples/pubsub/subscriber_test.cc deleted file mode 100644 index c5a077f407..0000000000 --- a/examples/pubsub/subscriber_test.cc +++ /dev/null @@ -1,152 +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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "examples/pubsub/subscriber.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -namespace grpc { -namespace testing { -namespace { - -const char kTopic[] = "test topic"; -const char kSubscriptionName[] = "subscription name"; -const char kData[] = "Message data"; - -class SubscriberServiceImpl : public tech::pubsub::SubscriberService::Service { - public: - Status CreateSubscription( - ServerContext* context, const tech::pubsub::Subscription* request, - tech::pubsub::Subscription* response) GRPC_OVERRIDE { - EXPECT_EQ(request->topic(), kTopic); - EXPECT_EQ(request->name(), kSubscriptionName); - return Status::OK; - } - - Status GetSubscription(ServerContext* context, - const tech::pubsub::GetSubscriptionRequest* request, - tech::pubsub::Subscription* response) GRPC_OVERRIDE { - EXPECT_EQ(request->subscription(), kSubscriptionName); - response->set_topic(kTopic); - return Status::OK; - } - - Status DeleteSubscription( - ServerContext* context, - const tech::pubsub::DeleteSubscriptionRequest* request, - proto2::Empty* response) GRPC_OVERRIDE { - EXPECT_EQ(request->subscription(), kSubscriptionName); - return Status::OK; - } - - Status Pull(ServerContext* context, const tech::pubsub::PullRequest* request, - tech::pubsub::PullResponse* response) GRPC_OVERRIDE { - EXPECT_EQ(request->subscription(), kSubscriptionName); - response->set_ack_id("1"); - response->mutable_pubsub_event()->mutable_message()->set_data(kData); - return Status::OK; - } - - Status Acknowledge(ServerContext* context, - const tech::pubsub::AcknowledgeRequest* request, - proto2::Empty* response) GRPC_OVERRIDE { - return Status::OK; - } -}; - -class SubscriberTest : public ::testing::Test { - protected: - // Setup a server and a client for SubscriberService. - void SetUp() GRPC_OVERRIDE { - int port = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << port; - ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), - grpc::InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - - channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(), - ChannelArguments()); - - subscriber_.reset(new grpc::examples::pubsub::Subscriber(channel_)); - } - - void TearDown() GRPC_OVERRIDE { - server_->Shutdown(); - subscriber_->Shutdown(); - } - - std::ostringstream server_address_; - std::unique_ptr server_; - SubscriberServiceImpl service_; - - std::shared_ptr channel_; - - std::unique_ptr subscriber_; -}; - -TEST_F(SubscriberTest, TestSubscriber) { - EXPECT_TRUE( - subscriber_->CreateSubscription(kTopic, kSubscriptionName).IsOk()); - - grpc::string topic; - EXPECT_TRUE(subscriber_->GetSubscription(kSubscriptionName, &topic).IsOk()); - EXPECT_EQ(topic, kTopic); - - grpc::string data; - EXPECT_TRUE(subscriber_->Pull(kSubscriptionName, &data).IsOk()); - - EXPECT_TRUE(subscriber_->DeleteSubscription(kSubscriptionName).IsOk()); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - gpr_log(GPR_INFO, "Start test ..."); - int result = RUN_ALL_TESTS(); - return result; -} -- cgit v1.2.3 From 43f1bf84aae3c753f1b797227e13075891431a56 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Thu, 27 Aug 2015 14:57:28 -0700 Subject: fix links --- README.md | 2 +- doc/interop-test-descriptions.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 599e6bcee0..ab1004f9d5 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ messages are delivered in the order they were sent. #Protocol -The [gRPC protocol](examples/PROTOCOL-HTTP2.md) specifies the abstract requirements for communication between +The [gRPC protocol](doc/PROTOCOL-HTTP2.md) specifies the abstract requirements for communication between clients and servers. A concrete embedding over HTTP/2 completes the picture by fleshing out the details of each of the required operations. diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md index aa14a7cfdf..98cd5ab4fc 100644 --- a/doc/interop-test-descriptions.md +++ b/doc/interop-test-descriptions.md @@ -4,7 +4,7 @@ Interoperability Test Case Descriptions Client and server use [test.proto](https://github.com/grpc/grpc/blob/master/test/proto/test.proto) and the [gRPC over HTTP/2 v2 -protocol](examples/doc/PROTOCOL-HTTP2.md). +protocol](doc/PROTOCOL-HTTP2.md). Client ------ -- cgit v1.2.3 From 240b7db1ca666a01f359fa1509be9c495b728827 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 27 Aug 2015 15:35:32 -0700 Subject: Outlaw comma in non-binary metadata values --- src/core/transport/metadata.c | 2 +- tools/codegen/core/gen_legal_metadata_characters.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c index 3fd21a2f5d..61638764a6 100644 --- a/src/core/transport/metadata.c +++ b/src/core/transport/metadata.c @@ -703,7 +703,7 @@ int grpc_mdstr_is_legal_header(grpc_mdstr *s) { int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s) { static const gpr_uint8 legal_header_bits[256 / 8] = { - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; return conforms_to(s, legal_header_bits); diff --git a/tools/codegen/core/gen_legal_metadata_characters.c b/tools/codegen/core/gen_legal_metadata_characters.c index 5c290f2923..0fbc545d8d 100644 --- a/tools/codegen/core/gen_legal_metadata_characters.c +++ b/tools/codegen/core/gen_legal_metadata_characters.c @@ -66,7 +66,10 @@ int main(void) { dump(); clear(); - for (i = 32; i <= 126; i++) legal(i); + for (i = 32; i <= 126; i++) { + if (i == ',') continue; + legal(i); + } dump(); return 0; -- cgit v1.2.3 From 4eaeb992d34f58148e9d00d7dbca7724382f8997 Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Thu, 27 Aug 2015 15:41:52 -0700 Subject: Addressing comments. --- test/cpp/interop/interop_client.cc | 18 ------------------ test/cpp/interop/interop_client.h | 3 --- 2 files changed, 21 deletions(-) diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index ca13cdc53d..73d1a143c4 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -179,24 +179,6 @@ void InteropClient::DoComputeEngineCreds( gpr_log(GPR_INFO, "Large unary with compute engine creds done."); } -void InteropClient::DoServiceAccountCreds(const grpc::string& username, - const grpc::string& oauth_scope) { - gpr_log(GPR_INFO, - "Sending a large unary rpc with service account credentials ..."); - SimpleRequest request; - SimpleResponse response; - request.set_fill_username(true); - request.set_fill_oauth_scope(true); - request.set_response_type(PayloadType::COMPRESSABLE); - PerformLargeUnary(&request, &response); - GPR_ASSERT(!response.username().empty()); - GPR_ASSERT(!response.oauth_scope().empty()); - GPR_ASSERT(username.find(response.username()) != grpc::string::npos); - const char* oauth_scope_str = response.oauth_scope().c_str(); - GPR_ASSERT(oauth_scope.find(oauth_scope_str) != grpc::string::npos); - gpr_log(GPR_INFO, "Large unary with service account creds done."); -} - void InteropClient::DoOauth2AuthToken(const grpc::string& username, const grpc::string& oauth_scope) { gpr_log(GPR_INFO, diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h index 5e26cc82e6..5a085c4c02 100644 --- a/test/cpp/interop/interop_client.h +++ b/test/cpp/interop/interop_client.h @@ -69,9 +69,6 @@ class InteropClient { void DoComputeEngineCreds(const grpc::string& default_service_account, const grpc::string& oauth_scope); // username is a string containing the user email - void DoServiceAccountCreds(const grpc::string& username, - const grpc::string& oauth_scope); - // username is a string containing the user email void DoOauth2AuthToken(const grpc::string& username, const grpc::string& oauth_scope); // username is a string containing the user email -- cgit v1.2.3 From 7d58abae60a829c5c763fbd5bf8aca85287f9d05 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 27 Aug 2015 16:11:08 -0700 Subject: Emit proper status when failing to parse server stream --- src/node/ext/call.cc | 23 +++++++++++++++++++++++ src/node/ext/call.h | 1 + src/node/src/client.js | 3 ++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc index fddc1e214f..560869e6fa 100644 --- a/src/node/ext/call.cc +++ b/src/node/ext/call.cc @@ -461,6 +461,9 @@ void Call::Init(Handle exports) { NanNew(StartBatch)->GetFunction()); NanSetPrototypeTemplate(tpl, "cancel", NanNew(Cancel)->GetFunction()); + NanSetPrototypeTemplate( + tpl, "cancelWithStatus", + NanNew(CancelWithStatus)->GetFunction()); NanSetPrototypeTemplate(tpl, "getPeer", NanNew(GetPeer)->GetFunction()); NanAssignPersistent(fun_tpl, tpl); @@ -643,6 +646,26 @@ NAN_METHOD(Call::Cancel) { NanReturnUndefined(); } +NAN_METHOD(Call::CancelWithStatus) { + NanScope(); + if (!HasInstance(args.This())) { + return NanThrowTypeError("cancel can only be called on Call objects"); + } + if (!args[0]->IsUint32()) { + return NanThrowTypeError( + "cancelWithStatus's first argument must be a status code"); + } + if (!args[1]->IsString()) { + return NanThrowTypeError( + "cancelWithStatus's second argument must be a string"); + } + Call *call = ObjectWrap::Unwrap(args.This()); + grpc_status_code code = static_cast(args[0]->Uint32Value()); + NanUtf8String details(args[0]); + grpc_call_cancel_with_status(call->wrapped_call, code, *details, NULL); + NanReturnUndefined(); +} + NAN_METHOD(Call::GetPeer) { NanScope(); if (!HasInstance(args.This())) { diff --git a/src/node/ext/call.h b/src/node/ext/call.h index ef6e5fcd21..89f81dcf4d 100644 --- a/src/node/ext/call.h +++ b/src/node/ext/call.h @@ -133,6 +133,7 @@ class Call : public ::node::ObjectWrap { static NAN_METHOD(New); static NAN_METHOD(StartBatch); static NAN_METHOD(Cancel); + static NAN_METHOD(CancelWithStatus); static NAN_METHOD(GetPeer); static NanCallback *constructor; // Used for typechecking instances of this javascript class diff --git a/src/node/src/client.js b/src/node/src/client.js index 2323caecc0..6a49490910 100644 --- a/src/node/src/client.js +++ b/src/node/src/client.js @@ -146,7 +146,8 @@ function _read(size) { try { deserialized = self.deserialize(data); } catch (e) { - self.cancel(); + self.call.cancelWithStatus(grpc.status.INTERNAL, + 'Failed to parse server response'); } if (self.push(deserialized) && data !== null) { var read_batch = {}; -- cgit v1.2.3 From 12577a7f7f1f50a0af6c98eca8767e450473329c Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 27 Aug 2015 16:20:44 -0700 Subject: Fix build --- Makefile | 223 ------------------------------- build.json | 73 ---------- tools/run_tests/sources_and_headers.json | 76 ----------- 3 files changed, 372 deletions(-) diff --git a/Makefile b/Makefile index 543bc0952b..135d38ccd8 100644 --- a/Makefile +++ b/Makefile @@ -875,9 +875,6 @@ interop_client: $(BINDIR)/$(CONFIG)/interop_client interop_server: $(BINDIR)/$(CONFIG)/interop_server interop_test: $(BINDIR)/$(CONFIG)/interop_test mock_test: $(BINDIR)/$(CONFIG)/mock_test -pubsub_client: $(BINDIR)/$(CONFIG)/pubsub_client -pubsub_publisher_test: $(BINDIR)/$(CONFIG)/pubsub_publisher_test -pubsub_subscriber_test: $(BINDIR)/$(CONFIG)/pubsub_subscriber_test qps_driver: $(BINDIR)/$(CONFIG)/qps_driver qps_interarrival_test: $(BINDIR)/$(CONFIG)/qps_interarrival_test qps_openloop_test: $(BINDIR)/$(CONFIG)/qps_openloop_test @@ -3488,51 +3485,6 @@ $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc: $(Q) mkdir -p $(@D) $(Q) echo "$(GRPCXX_UNSECURE_PC_FILE)" | tr , '\n' >$@ -ifeq ($(NO_PROTOC),true) -$(GENDIR)/examples/pubsub/empty.pb.cc: protoc_dep_error -$(GENDIR)/examples/pubsub/empty.grpc.pb.cc: protoc_dep_error -else -$(GENDIR)/examples/pubsub/empty.pb.cc: examples/pubsub/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) - $(E) "[PROTOC] Generating protobuf CC file from $<" - $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< - -$(GENDIR)/examples/pubsub/empty.grpc.pb.cc: examples/pubsub/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) - $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" - $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< -endif - -ifeq ($(NO_PROTOC),true) -$(GENDIR)/examples/pubsub/label.pb.cc: protoc_dep_error -$(GENDIR)/examples/pubsub/label.grpc.pb.cc: protoc_dep_error -else -$(GENDIR)/examples/pubsub/label.pb.cc: examples/pubsub/label.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) - $(E) "[PROTOC] Generating protobuf CC file from $<" - $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< - -$(GENDIR)/examples/pubsub/label.grpc.pb.cc: examples/pubsub/label.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) - $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" - $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< -endif - -ifeq ($(NO_PROTOC),true) -$(GENDIR)/examples/pubsub/pubsub.pb.cc: protoc_dep_error -$(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc: protoc_dep_error -else -$(GENDIR)/examples/pubsub/pubsub.pb.cc: examples/pubsub/pubsub.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) - $(E) "[PROTOC] Generating protobuf CC file from $<" - $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< - -$(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc: examples/pubsub/pubsub.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) - $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" - $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< -endif - ifeq ($(NO_PROTOC),true) $(GENDIR)/test/cpp/qps/perf_db.pb.cc: protoc_dep_error $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc: protoc_dep_error @@ -5205,59 +5157,6 @@ endif $(OBJDIR)/$(CONFIG)/test/cpp/interop/server.o: $(GENDIR)/test/proto/empty.pb.cc $(GENDIR)/test/proto/empty.grpc.pb.cc $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/test.pb.cc $(GENDIR)/test/proto/test.grpc.pb.cc -LIBPUBSUB_CLIENT_LIB_SRC = \ - $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc \ - $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc \ - $(GENDIR)/examples/pubsub/pubsub.pb.cc $(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc \ - examples/pubsub/publisher.cc \ - examples/pubsub/subscriber.cc \ - - -LIBPUBSUB_CLIENT_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBPUBSUB_CLIENT_LIB_SRC)))) - -ifeq ($(NO_SECURE),true) - -# You can't build secure libraries if you don't have OpenSSL. - -$(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a: openssl_dep_error - - -else - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBPUBSUB_CLIENT_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a - $(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBPUBSUB_CLIENT_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a -endif - - - - -endif - -endif - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(LIBPUBSUB_CLIENT_LIB_OBJS:.o=.dep) -endif -endif -$(OBJDIR)/$(CONFIG)/examples/pubsub/publisher.o: $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc $(GENDIR)/examples/pubsub/pubsub.pb.cc $(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/examples/pubsub/subscriber.o: $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc $(GENDIR)/examples/pubsub/pubsub.pb.cc $(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc - - LIBQPS_SRC = \ $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc \ $(GENDIR)/test/cpp/qps/perf_db.pb.cc $(GENDIR)/test/cpp/qps/perf_db.grpc.pb.cc \ @@ -9752,126 +9651,6 @@ endif endif -PUBSUB_CLIENT_SRC = \ - examples/pubsub/main.cc \ - -PUBSUB_CLIENT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PUBSUB_CLIENT_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/pubsub_client: openssl_dep_error - -else - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. - -$(BINDIR)/$(CONFIG)/pubsub_client: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/pubsub_client: $(PROTOBUF_DEP) $(PUBSUB_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(PUBSUB_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/pubsub_client - -endif - -endif - -$(OBJDIR)/$(CONFIG)/examples/pubsub/main.o: $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -deps_pubsub_client: $(PUBSUB_CLIENT_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(PUBSUB_CLIENT_OBJS:.o=.dep) -endif -endif - - -PUBSUB_PUBLISHER_TEST_SRC = \ - examples/pubsub/publisher_test.cc \ - -PUBSUB_PUBLISHER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PUBSUB_PUBLISHER_TEST_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/pubsub_publisher_test: openssl_dep_error - -else - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. - -$(BINDIR)/$(CONFIG)/pubsub_publisher_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/pubsub_publisher_test: $(PROTOBUF_DEP) $(PUBSUB_PUBLISHER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(PUBSUB_PUBLISHER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/pubsub_publisher_test - -endif - -endif - -$(OBJDIR)/$(CONFIG)/examples/pubsub/publisher_test.o: $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a -deps_pubsub_publisher_test: $(PUBSUB_PUBLISHER_TEST_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(PUBSUB_PUBLISHER_TEST_OBJS:.o=.dep) -endif -endif - - -PUBSUB_SUBSCRIBER_TEST_SRC = \ - examples/pubsub/subscriber_test.cc \ - -PUBSUB_SUBSCRIBER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PUBSUB_SUBSCRIBER_TEST_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/pubsub_subscriber_test: openssl_dep_error - -else - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. - -$(BINDIR)/$(CONFIG)/pubsub_subscriber_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/pubsub_subscriber_test: $(PROTOBUF_DEP) $(PUBSUB_SUBSCRIBER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(PUBSUB_SUBSCRIBER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/pubsub_subscriber_test - -endif - -endif - -$(OBJDIR)/$(CONFIG)/examples/pubsub/subscriber_test.o: $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a -deps_pubsub_subscriber_test: $(PUBSUB_SUBSCRIBER_TEST_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(PUBSUB_SUBSCRIBER_TEST_OBJS:.o=.dep) -endif -endif - - QPS_DRIVER_SRC = \ test/cpp/qps/qps_driver.cc \ @@ -20646,8 +20425,6 @@ ifneq ($(OPENSSL_DEP),) # This is to ensure the embedded OpenSSL is built beforehand, properly # installing headers to their final destination on the drive. We need this # otherwise parallel compilation will fail if a source is compiled first. -examples/pubsub/publisher.cc: $(OPENSSL_DEP) -examples/pubsub/subscriber.cc: $(OPENSSL_DEP) src/core/httpcli/httpcli_security_connector.c: $(OPENSSL_DEP) src/core/security/base64.c: $(OPENSSL_DEP) src/core/security/client_auth_filter.c: $(OPENSSL_DEP) diff --git a/build.json b/build.json index a5be837f66..a451fc342f 100644 --- a/build.json +++ b/build.json @@ -813,27 +813,6 @@ "grpc++_test_config" ] }, - { - "name": "pubsub_client_lib", - "build": "do_not_build", - "language": "c++", - "headers": [ - "examples/pubsub/publisher.h", - "examples/pubsub/subscriber.h" - ], - "src": [ - "examples/pubsub/label.proto", - "examples/pubsub/empty.proto", - "examples/pubsub/pubsub.proto", - "examples/pubsub/publisher.cc", - "examples/pubsub/subscriber.cc" - ], - "deps": [ - "grpc++", - "grpc", - "gpr" - ] - }, { "name": "qps", "build": "private", @@ -2369,58 +2348,6 @@ "gpr" ] }, - { - "name": "pubsub_client", - "build": "do_not_build", - "run": false, - "language": "c++", - "src": [ - "examples/pubsub/main.cc" - ], - "deps": [ - "pubsub_client_lib", - "grpc_test_util", - "grpc++", - "grpc", - "gpr_test_util", - "gpr", - "grpc++_test_config" - ] - }, - { - "name": "pubsub_publisher_test", - "build": "do_not_build", - "language": "c++", - "src": [ - "examples/pubsub/publisher_test.cc" - ], - "deps": [ - "pubsub_client_lib", - "grpc++_test_util", - "grpc_test_util", - "grpc++", - "grpc", - "gpr_test_util", - "gpr" - ] - }, - { - "name": "pubsub_subscriber_test", - "build": "do_not_build", - "language": "c++", - "src": [ - "examples/pubsub/subscriber_test.cc" - ], - "deps": [ - "pubsub_client_lib", - "grpc++_test_util", - "grpc_test_util", - "grpc++", - "grpc", - "gpr_test_util", - "gpr" - ] - }, { "name": "qps_driver", "build": "benchmark", diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 42942e4e0c..0585b8268f 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -1388,57 +1388,6 @@ "test/cpp/end2end/mock_test.cc" ] }, - { - "deps": [ - "gpr", - "gpr_test_util", - "grpc", - "grpc++", - "grpc++_test_config", - "grpc_test_util", - "pubsub_client_lib" - ], - "headers": [], - "language": "c++", - "name": "pubsub_client", - "src": [ - "examples/pubsub/main.cc" - ] - }, - { - "deps": [ - "gpr", - "gpr_test_util", - "grpc", - "grpc++", - "grpc++_test_util", - "grpc_test_util", - "pubsub_client_lib" - ], - "headers": [], - "language": "c++", - "name": "pubsub_publisher_test", - "src": [ - "examples/pubsub/publisher_test.cc" - ] - }, - { - "deps": [ - "gpr", - "gpr_test_util", - "grpc", - "grpc++", - "grpc++_test_util", - "grpc_test_util", - "pubsub_client_lib" - ], - "headers": [], - "language": "c++", - "name": "pubsub_subscriber_test", - "src": [ - "examples/pubsub/subscriber_test.cc" - ] - }, { "deps": [ "gpr", @@ -13570,31 +13519,6 @@ "test/cpp/interop/server.cc" ] }, - { - "deps": [ - "gpr", - "grpc", - "grpc++" - ], - "headers": [ - "examples/pubsub/empty.grpc.pb.h", - "examples/pubsub/empty.pb.h", - "examples/pubsub/label.grpc.pb.h", - "examples/pubsub/label.pb.h", - "examples/pubsub/publisher.h", - "examples/pubsub/pubsub.grpc.pb.h", - "examples/pubsub/pubsub.pb.h", - "examples/pubsub/subscriber.h" - ], - "language": "c++", - "name": "pubsub_client_lib", - "src": [ - "examples/pubsub/publisher.cc", - "examples/pubsub/publisher.h", - "examples/pubsub/subscriber.cc", - "examples/pubsub/subscriber.h" - ] - }, { "deps": [ "grpc++", -- cgit v1.2.3 From 421738b5291979818aa040524c8da69f1de99731 Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Thu, 27 Aug 2015 16:34:44 -0700 Subject: Addressing comments, round 2. --- test/cpp/interop/client.cc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index cb5232153b..20fe1c515f 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -68,7 +68,6 @@ DEFINE_string(test_case, "large_unary", "cancel_after_begin : cancel stream after starting it; " "cancel_after_first_response: cancel on first response; " "timeout_on_sleeping_server: deadline exceeds on stream; " - "service_account_creds : large_unary with service_account auth; " "compute_engine_creds: large_unary with compute engine auth; " "jwt_token_creds: large_unary with JWT token auth; " "oauth2_auth_token: raw oauth2 access token auth; " @@ -114,9 +113,6 @@ int main(int argc, char** argv) { client.DoCancelAfterFirstResponse(); } else if (FLAGS_test_case == "timeout_on_sleeping_server") { client.DoTimeoutOnSleepingServer(); - } else if (FLAGS_test_case == "service_account_creds") { - grpc::string json_key = GetServiceAccountJsonKey(); - client.DoServiceAccountCreds(json_key, FLAGS_oauth_scope); } else if (FLAGS_test_case == "compute_engine_creds") { client.DoComputeEngineCreds(FLAGS_default_service_account, FLAGS_oauth_scope); @@ -146,7 +142,6 @@ int main(int argc, char** argv) { // service_account_creds and jwt_token_creds can only run with ssl. if (FLAGS_enable_ssl) { grpc::string json_key = GetServiceAccountJsonKey(); - client.DoServiceAccountCreds(json_key, FLAGS_oauth_scope); client.DoJwtTokenCreds(json_key); client.DoOauth2AuthToken(json_key, FLAGS_oauth_scope); client.DoPerRpcCreds(json_key, FLAGS_oauth_scope); @@ -159,8 +154,7 @@ int main(int argc, char** argv) { "large_unary|large_compressed_unary|client_streaming|server_streaming|" "server_compressed_streaming|half_duplex|ping_pong|cancel_after_begin|" "cancel_after_first_response|timeout_on_sleeping_server|" - "service_account_creds|compute_engine_creds|jwt_token_creds|" - "oauth2_auth_token|per_rpc_creds", + "compute_engine_creds|jwt_token_creds|oauth2_auth_token|per_rpc_creds", FLAGS_test_case.c_str()); ret = 1; } -- cgit v1.2.3 From 63720d4ecf690051744e331e2afb6e0a5a9d45cc Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Thu, 27 Aug 2015 17:22:16 -0700 Subject: Python service account cleanup. --- src/python/grpcio/grpc/_adapter/_c/types.h | 2 -- .../grpc/_adapter/_c/types/client_credentials.c | 2 -- .../grpcio/grpc/_cython/_cygrpc/credentials.pyx | 20 -------------------- src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd | 2 -- src/python/grpcio/grpc/_cython/adapter_low.py | 4 ---- src/python/grpcio_test/grpc_interop/methods.py | 17 ----------------- 6 files changed, 47 deletions(-) diff --git a/src/python/grpcio/grpc/_adapter/_c/types.h b/src/python/grpcio/grpc/_adapter/_c/types.h index f6ff957baa..ec0687a9fd 100644 --- a/src/python/grpcio/grpc/_adapter/_c/types.h +++ b/src/python/grpcio/grpc/_adapter/_c/types.h @@ -57,8 +57,6 @@ ClientCredentials *pygrpc_ClientCredentials_composite( PyTypeObject *type, PyObject *args, PyObject *kwargs); ClientCredentials *pygrpc_ClientCredentials_compute_engine( PyTypeObject *type, PyObject *ignored); -ClientCredentials *pygrpc_ClientCredentials_service_account( - PyTypeObject *type, PyObject *args, PyObject *kwargs); ClientCredentials *pygrpc_ClientCredentials_jwt( PyTypeObject *type, PyObject *args, PyObject *kwargs); ClientCredentials *pygrpc_ClientCredentials_refresh_token( diff --git a/src/python/grpcio/grpc/_adapter/_c/types/client_credentials.c b/src/python/grpcio/grpc/_adapter/_c/types/client_credentials.c index 9554796631..90652b7b47 100644 --- a/src/python/grpcio/grpc/_adapter/_c/types/client_credentials.c +++ b/src/python/grpcio/grpc/_adapter/_c/types/client_credentials.c @@ -48,8 +48,6 @@ PyMethodDef pygrpc_ClientCredentials_methods[] = { METH_CLASS|METH_KEYWORDS, ""}, {"compute_engine", (PyCFunction)pygrpc_ClientCredentials_compute_engine, METH_CLASS|METH_NOARGS, ""}, - {"service_account", (PyCFunction)pygrpc_ClientCredentials_service_account, - METH_CLASS|METH_KEYWORDS, ""}, {"jwt", (PyCFunction)pygrpc_ClientCredentials_jwt, METH_CLASS|METH_KEYWORDS, ""}, {"refresh_token", (PyCFunction)pygrpc_ClientCredentials_refresh_token, diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx index 2d74702fbd..dc40a7a611 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx @@ -106,26 +106,6 @@ def client_credentials_compute_engine(): credentials.c_credentials = grpc.grpc_compute_engine_credentials_create() return credentials -def client_credentials_service_account( - json_key, scope, records.Timespec token_lifetime not None): - if isinstance(json_key, bytes): - pass - elif isinstance(json_key, basestring): - json_key = json_key.encode() - else: - raise TypeError("expected json_key to be str or bytes") - if isinstance(scope, bytes): - pass - elif isinstance(scope, basestring): - scope = scope.encode() - else: - raise TypeError("expected scope to be str or bytes") - cdef ClientCredentials credentials = ClientCredentials() - credentials.c_credentials = grpc.grpc_service_account_credentials_create( - json_key, scope, token_lifetime.c_time) - credentials.references.extend([json_key, scope]) - return credentials - #TODO rename to something like client_credentials_service_account_jwt_access. def client_credentials_jwt(json_key, records.Timespec token_lifetime not None): if isinstance(json_key, bytes): diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd index c793774c8d..8b46972490 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd @@ -311,8 +311,6 @@ cdef extern from "grpc/grpc_security.h": grpc_credentials *grpc_composite_credentials_create(grpc_credentials *creds1, grpc_credentials *creds2) grpc_credentials *grpc_compute_engine_credentials_create() - grpc_credentials *grpc_service_account_credentials_create( - const char *json_key, const char *scope, gpr_timespec token_lifetime) grpc_credentials *grpc_service_account_jwt_access_credentials_create(const char *json_key, gpr_timespec token_lifetime) grpc_credentials *grpc_refresh_token_credentials_create( diff --git a/src/python/grpcio/grpc/_cython/adapter_low.py b/src/python/grpcio/grpc/_cython/adapter_low.py index 2bb468eece..4f24da330f 100644 --- a/src/python/grpcio/grpc/_cython/adapter_low.py +++ b/src/python/grpcio/grpc/_cython/adapter_low.py @@ -59,10 +59,6 @@ class ClientCredentials(object): def compute_engine(): raise NotImplementedError() - @staticmethod - def service_account(): - raise NotImplementedError() - @staticmethod def jwt(): raise NotImplementedError() diff --git a/src/python/grpcio_test/grpc_interop/methods.py b/src/python/grpcio_test/grpc_interop/methods.py index 7a831f3cbd..19a1e17c3e 100644 --- a/src/python/grpcio_test/grpc_interop/methods.py +++ b/src/python/grpcio_test/grpc_interop/methods.py @@ -346,20 +346,6 @@ def _compute_engine_creds(stub, args): response.username)) -def _service_account_creds(stub, args): - json_key_filename = os.environ[ - oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS] - wanted_email = json.load(open(json_key_filename, 'rb'))['client_email'] - response = _large_unary_common_behavior(stub, True, True) - if wanted_email != response.username: - raise ValueError( - 'expected username %s, got %s' % (wanted_email, response.username)) - if args.oauth_scope.find(response.oauth_scope) == -1: - raise ValueError( - 'expected to find oauth scope "%s" in received "%s"' % - (response.oauth_scope, args.oauth_scope)) - - @enum.unique class TestCase(enum.Enum): EMPTY_UNARY = 'empty_unary' @@ -370,7 +356,6 @@ class TestCase(enum.Enum): CANCEL_AFTER_BEGIN = 'cancel_after_begin' CANCEL_AFTER_FIRST_RESPONSE = 'cancel_after_first_response' COMPUTE_ENGINE_CREDS = 'compute_engine_creds' - SERVICE_ACCOUNT_CREDS = 'service_account_creds' TIMEOUT_ON_SLEEPING_SERVER = 'timeout_on_sleeping_server' def test_interoperability(self, stub, args): @@ -392,7 +377,5 @@ class TestCase(enum.Enum): _timeout_on_sleeping_server(stub) elif self is TestCase.COMPUTE_ENGINE_CREDS: _compute_engine_creds(stub, args) - elif self is TestCase.SERVICE_ACCOUNT_CREDS: - _service_account_creds(stub, args) else: raise NotImplementedError('Test case "%s" not implemented!' % self.name) -- cgit v1.2.3 From 0908c23c442f0fdf586dae064ad9adf551e4f028 Mon Sep 17 00:00:00 2001 From: Nathaniel Manista Date: Fri, 28 Aug 2015 03:04:04 +0000 Subject: Expand force_client_auth to old ServerCredentials --- src/python/grpcio/grpc/_adapter/_intermediary_low.py | 4 ++-- src/python/grpcio/grpc/_adapter/fore.py | 2 +- src/python/grpcio/grpc/_links/service.py | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/python/grpcio/grpc/_adapter/_intermediary_low.py b/src/python/grpcio/grpc/_adapter/_intermediary_low.py index 1fb6a2b27d..06358e72bc 100644 --- a/src/python/grpcio/grpc/_adapter/_intermediary_low.py +++ b/src/python/grpcio/grpc/_adapter/_intermediary_low.py @@ -255,6 +255,6 @@ class ClientCredentials(object): class ServerCredentials(object): """Adapter from old _low.ServerCredentials interface to new _low.ServerCredentials.""" - def __init__(self, root_credentials, pair_sequence): + def __init__(self, root_credentials, pair_sequence, force_client_auth): self._internal = _low.ServerCredentials.ssl( - root_credentials, list(pair_sequence), False) + root_credentials, list(pair_sequence), force_client_auth) diff --git a/src/python/grpcio/grpc/_adapter/fore.py b/src/python/grpcio/grpc/_adapter/fore.py index 7d88bda263..daa41e8bde 100644 --- a/src/python/grpcio/grpc/_adapter/fore.py +++ b/src/python/grpcio/grpc/_adapter/fore.py @@ -288,7 +288,7 @@ class ForeLink(base_interfaces.ForeLink, activated.Activated): self._port = self._server.add_http2_addr(address) else: server_credentials = _low.ServerCredentials( - self._root_certificates, self._key_chain_pairs) + self._root_certificates, self._key_chain_pairs, False) self._server = _low.Server(self._completion_queue) self._port = self._server.add_secure_http2_addr( address, server_credentials) diff --git a/src/python/grpcio/grpc/_links/service.py b/src/python/grpcio/grpc/_links/service.py index 43c4c0e80c..10634e43b5 100644 --- a/src/python/grpcio/grpc/_links/service.py +++ b/src/python/grpcio/grpc/_links/service.py @@ -366,10 +366,10 @@ class ServiceLink(links.Link): """Adds a port on which to service RPCs after this link has been started. Args: - port: The port on which to service RPCs, or zero to request that a port be - automatically selected and used. - server_credentials: A ServerCredentials object, or None for insecure - service. + port: The port on which to service RPCs, or zero to request that a port + be automatically selected and used. + server_credentials: An _intermediary_low.ServerCredentials object, or + None for insecure service. Returns: A port on which RPCs will be serviced after this link has been started. -- cgit v1.2.3 From 67c4587c88018ab5dc8919d9e5a7416cc88bd69a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 27 Aug 2015 18:12:39 -0700 Subject: error spec compliance and marshalling tests --- src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj | 1 + .../Grpc.Core.Tests/MarshallingErrorsTest.cs | 176 +++++++++++++++++++++ src/csharp/Grpc.Core.Tests/MockServiceHelper.cs | 80 +++++----- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 17 +- src/csharp/Grpc.Core/Internal/AsyncCallBase.cs | 50 +++--- src/csharp/Grpc.Core/Internal/AsyncCallServer.cs | 5 + src/csharp/Grpc.Core/Marshaller.cs | 2 +- .../Grpc.Examples.Tests/MathClientServerTests.cs | 2 +- .../HealthClientServerTest.cs | 2 +- .../HealthServiceImplTest.cs | 2 +- .../Grpc.IntegrationTesting/InteropClient.cs | 5 +- 11 files changed, 273 insertions(+), 69 deletions(-) create mode 100644 src/csharp/Grpc.Core.Tests/MarshallingErrorsTest.cs diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index b571fe9025..f730936062 100644 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -64,6 +64,7 @@ Version.cs + diff --git a/src/csharp/Grpc.Core.Tests/MarshallingErrorsTest.cs b/src/csharp/Grpc.Core.Tests/MarshallingErrorsTest.cs new file mode 100644 index 0000000000..83707e0c6d --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/MarshallingErrorsTest.cs @@ -0,0 +1,176 @@ +#region Copyright notice and license + +// 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. + +#endregion + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +using Grpc.Core; +using Grpc.Core.Internal; +using Grpc.Core.Utils; +using NUnit.Framework; + +namespace Grpc.Core.Tests +{ + public class MarshallingErrorsTest + { + const string Host = "127.0.0.1"; + + MockServiceHelper helper; + Server server; + Channel channel; + + [SetUp] + public void Init() + { + var marshaller = new Marshaller( + (str) => + { + if (str == "UNSERIALIZABLE_VALUE") + { + // Google.Protobuf throws exception inherited from IOException + throw new IOException("Error serializing the message."); + } + return System.Text.Encoding.UTF8.GetBytes(str); + }, + (payload) => + { + var s = System.Text.Encoding.UTF8.GetString(payload); + if (s == "UNPARSEABLE_VALUE") + { + // Google.Protobuf throws exception inherited from IOException + throw new IOException("Error parsing the message."); + } + return s; + }); + helper = new MockServiceHelper(Host, marshaller); + server = helper.GetServer(); + server.Start(); + channel = helper.GetChannel(); + } + + [TearDown] + public void Cleanup() + { + channel.ShutdownAsync().Wait(); + server.ShutdownAsync().Wait(); + } + + [Test] + public void ResponseParsingError_UnaryResponse() + { + helper.UnaryHandler = new UnaryServerMethod((request, context) => + { + return Task.FromResult("UNPARSEABLE_VALUE"); + }); + + var ex = Assert.Throws(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "REQUEST")); + Assert.AreEqual(StatusCode.Internal, ex.Status.StatusCode); + } + + [Test] + public void ResponseParsingError_StreamingResponse() + { + helper.ServerStreamingHandler = new ServerStreamingServerMethod(async (request, responseStream, context) => + { + await responseStream.WriteAsync("UNPARSEABLE_VALUE"); + await Task.Delay(10000); + }); + + var call = Calls.AsyncServerStreamingCall(helper.CreateServerStreamingCall(), "REQUEST"); + var ex = Assert.Throws(async () => await call.ResponseStream.MoveNext()); + Assert.AreEqual(StatusCode.Internal, ex.Status.StatusCode); + } + + [Test] + public void RequestParsingError_UnaryRequest() + { + helper.UnaryHandler = new UnaryServerMethod((request, context) => + { + return Task.FromResult("RESPONSE"); + }); + + var ex = Assert.Throws(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "UNPARSEABLE_VALUE")); + // Spec doesn't define the behavior. With the current implementation server handler throws exception which results in StatusCode.Unknown. + Assert.AreEqual(StatusCode.Unknown, ex.Status.StatusCode); + } + + [Test] + public async Task RequestParsingError_StreamingRequest() + { + helper.ClientStreamingHandler = new ClientStreamingServerMethod(async (requestStream, context) => + { + Assert.Throws(async () => await requestStream.MoveNext()); + return "RESPONSE"; + }); + + var call = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall()); + await call.RequestStream.WriteAsync("UNPARSEABLE_VALUE"); + + Assert.AreEqual("RESPONSE", await call); + } + + [Test] + public void RequestSerializationError_BlockingUnary() + { + Assert.Throws(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "UNSERIALIZABLE_VALUE")); + } + + [Test] + public void RequestSerializationError_AsyncUnary() + { + Assert.Throws(async () => await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "UNSERIALIZABLE_VALUE")); + } + + [Test] + public async Task RequestSerializationError_ClientStreaming() + { + helper.ClientStreamingHandler = new ClientStreamingServerMethod(async (requestStream, context) => + { + CollectionAssert.AreEqual(new [] {"A", "B"}, await requestStream.ToListAsync()); + return "RESPONSE"; + }); + var call = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall()); + await call.RequestStream.WriteAsync("A"); + Assert.Throws(async () => await call.RequestStream.WriteAsync("UNSERIALIZABLE_VALUE")); + await call.RequestStream.WriteAsync("B"); + await call.RequestStream.CompleteAsync(); + + Assert.AreEqual("RESPONSE", await call); + } + } +} diff --git a/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs b/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs index bb69648d8b..765732c768 100644 --- a/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs +++ b/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs @@ -50,37 +50,14 @@ namespace Grpc.Core.Tests { public const string ServiceName = "tests.Test"; - public static readonly Method UnaryMethod = new Method( - MethodType.Unary, - ServiceName, - "Unary", - Marshallers.StringMarshaller, - Marshallers.StringMarshaller); - - public static readonly Method ClientStreamingMethod = new Method( - MethodType.ClientStreaming, - ServiceName, - "ClientStreaming", - Marshallers.StringMarshaller, - Marshallers.StringMarshaller); - - public static readonly Method ServerStreamingMethod = new Method( - MethodType.ServerStreaming, - ServiceName, - "ServerStreaming", - Marshallers.StringMarshaller, - Marshallers.StringMarshaller); - - public static readonly Method DuplexStreamingMethod = new Method( - MethodType.DuplexStreaming, - ServiceName, - "DuplexStreaming", - Marshallers.StringMarshaller, - Marshallers.StringMarshaller); - readonly string host; readonly ServerServiceDefinition serviceDefinition; + readonly Method unaryMethod; + readonly Method clientStreamingMethod; + readonly Method serverStreamingMethod; + readonly Method duplexStreamingMethod; + UnaryServerMethod unaryHandler; ClientStreamingServerMethod clientStreamingHandler; ServerStreamingServerMethod serverStreamingHandler; @@ -89,15 +66,44 @@ namespace Grpc.Core.Tests Server server; Channel channel; - public MockServiceHelper(string host = null) + public MockServiceHelper(string host = null, Marshaller marshaller = null) { this.host = host ?? "localhost"; + marshaller = marshaller ?? Marshallers.StringMarshaller; + + unaryMethod = new Method( + MethodType.Unary, + ServiceName, + "Unary", + marshaller, + marshaller); + + clientStreamingMethod = new Method( + MethodType.ClientStreaming, + ServiceName, + "ClientStreaming", + marshaller, + marshaller); + + serverStreamingMethod = new Method( + MethodType.ServerStreaming, + ServiceName, + "ServerStreaming", + marshaller, + marshaller); + + duplexStreamingMethod = new Method( + MethodType.DuplexStreaming, + ServiceName, + "DuplexStreaming", + marshaller, + marshaller); serviceDefinition = ServerServiceDefinition.CreateBuilder(ServiceName) - .AddMethod(UnaryMethod, (request, context) => unaryHandler(request, context)) - .AddMethod(ClientStreamingMethod, (requestStream, context) => clientStreamingHandler(requestStream, context)) - .AddMethod(ServerStreamingMethod, (request, responseStream, context) => serverStreamingHandler(request, responseStream, context)) - .AddMethod(DuplexStreamingMethod, (requestStream, responseStream, context) => duplexStreamingHandler(requestStream, responseStream, context)) + .AddMethod(unaryMethod, (request, context) => unaryHandler(request, context)) + .AddMethod(clientStreamingMethod, (requestStream, context) => clientStreamingHandler(requestStream, context)) + .AddMethod(serverStreamingMethod, (request, responseStream, context) => serverStreamingHandler(request, responseStream, context)) + .AddMethod(duplexStreamingMethod, (requestStream, responseStream, context) => duplexStreamingHandler(requestStream, responseStream, context)) .Build(); var defaultStatus = new Status(StatusCode.Unknown, "Default mock implementation. Please provide your own."); @@ -155,22 +161,22 @@ namespace Grpc.Core.Tests public CallInvocationDetails CreateUnaryCall(CallOptions options = default(CallOptions)) { - return new CallInvocationDetails(channel, UnaryMethod, options); + return new CallInvocationDetails(channel, unaryMethod, options); } public CallInvocationDetails CreateClientStreamingCall(CallOptions options = default(CallOptions)) { - return new CallInvocationDetails(channel, ClientStreamingMethod, options); + return new CallInvocationDetails(channel, clientStreamingMethod, options); } public CallInvocationDetails CreateServerStreamingCall(CallOptions options = default(CallOptions)) { - return new CallInvocationDetails(channel, ServerStreamingMethod, options); + return new CallInvocationDetails(channel, serverStreamingMethod, options); } public CallInvocationDetails CreateDuplexStreamingCall(CallOptions options = default(CallOptions)) { - return new CallInvocationDetails(channel, DuplexStreamingMethod, options); + return new CallInvocationDetails(channel, duplexStreamingMethod, options); } public string Host diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index be5d611a53..e3b00781c6 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -322,6 +322,11 @@ namespace Grpc.Core.Internal details.Channel.RemoveCallReference(this); } + protected override bool IsClient + { + get { return true; } + } + private void Initialize(CompletionQueueSafeHandle cq) { var call = CreateNativeCall(cq); @@ -376,9 +381,17 @@ namespace Grpc.Core.Internal /// private void HandleUnaryResponse(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders) { + TResponse msg = default(TResponse); + var deserializeException = success ? TryDeserialize(receivedMessage, out msg) : null; + lock (myLock) { finished = true; + + if (deserializeException != null && receivedStatus.Status.StatusCode == StatusCode.OK) + { + receivedStatus = new ClientSideStatus(DeserializeResponseFailureStatus, receivedStatus.Trailers); + } finishedStatus = receivedStatus; ReleaseResourcesIfPossible(); @@ -394,10 +407,6 @@ namespace Grpc.Core.Internal return; } - // TODO: handle deserialization error - TResponse msg; - TryDeserialize(receivedMessage, out msg); - unaryResponseTcs.SetResult(msg); } diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs index 4d20394644..3e2c57c9b5 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs @@ -33,10 +33,12 @@ using System; using System.Diagnostics; +using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; + using Grpc.Core.Internal; using Grpc.Core.Logging; using Grpc.Core.Utils; @@ -50,6 +52,7 @@ namespace Grpc.Core.Internal internal abstract class AsyncCallBase { static readonly ILogger Logger = GrpcEnvironment.Logger.ForType>(); + protected static readonly Status DeserializeResponseFailureStatus = new Status(StatusCode.Internal, "Failed to deserialize response message."); readonly Func serializer; readonly Func deserializer; @@ -100,11 +103,10 @@ namespace Grpc.Core.Internal /// /// Requests cancelling the call with given status. /// - public void CancelWithStatus(Status status) + protected void CancelWithStatus(Status status) { lock (myLock) { - Preconditions.CheckState(started); cancelRequested = true; if (!disposed) @@ -177,6 +179,11 @@ namespace Grpc.Core.Internal return false; } + protected abstract bool IsClient + { + get; + } + private void ReleaseResources() { if (call != null) @@ -224,33 +231,31 @@ namespace Grpc.Core.Internal return serializer(msg); } - protected bool TrySerialize(TWrite msg, out byte[] payload) + protected Exception TrySerialize(TWrite msg, out byte[] payload) { try { payload = serializer(msg); - return true; + return null; } catch (Exception e) { - Logger.Error(e, "Exception occured while trying to serialize message"); payload = null; - return false; + return e; } } - protected bool TryDeserialize(byte[] payload, out TRead msg) + protected Exception TryDeserialize(byte[] payload, out TRead msg) { try { msg = deserializer(payload); - return true; + return null; } catch (Exception e) { - Logger.Error(e, "Exception occured while trying to deserialize message."); msg = default(TRead); - return false; + return e; } } @@ -319,6 +324,9 @@ namespace Grpc.Core.Internal /// protected void HandleReadFinished(bool success, byte[] receivedMessage) { + TRead msg = default(TRead); + var deserializeException = (success && receivedMessage != null) ? TryDeserialize(receivedMessage, out msg) : null; + AsyncCompletionDelegate origCompletionDelegate = null; lock (myLock) { @@ -331,23 +339,23 @@ namespace Grpc.Core.Internal readingDone = true; } + if (deserializeException != null && IsClient) + { + readingDone = true; + CancelWithStatus(DeserializeResponseFailureStatus); + } + ReleaseResourcesIfPossible(); } - // TODO: handle the case when error occured... + // TODO: handle the case when success==false - if (receivedMessage != null) - { - // TODO: handle deserialization error - TRead msg; - TryDeserialize(receivedMessage, out msg); - - FireCompletion(origCompletionDelegate, msg, null); - } - else + if (deserializeException != null && !IsClient) { - FireCompletion(origCompletionDelegate, default(TRead), null); + FireCompletion(origCompletionDelegate, default(TRead), new IOException("Failed to deserialize request message.", deserializeException)); + return; } + FireCompletion(origCompletionDelegate, msg, null); } } } \ No newline at end of file diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs index 5c47251030..46ca459349 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs @@ -169,6 +169,11 @@ namespace Grpc.Core.Internal } } + protected override bool IsClient + { + get { return false; } + } + protected override void CheckReadingAllowed() { base.CheckReadingAllowed(); diff --git a/src/csharp/Grpc.Core/Marshaller.cs b/src/csharp/Grpc.Core/Marshaller.cs index f38cb0863f..3493d2d38f 100644 --- a/src/csharp/Grpc.Core/Marshaller.cs +++ b/src/csharp/Grpc.Core/Marshaller.cs @@ -39,7 +39,7 @@ namespace Grpc.Core /// /// Encapsulates the logic for serializing and deserializing messages. /// - public struct Marshaller + public class Marshaller { readonly Func serializer; readonly Func deserializer; diff --git a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs index d8547758d2..e2975b5da9 100644 --- a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs +++ b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs @@ -162,7 +162,7 @@ namespace Math.Tests { using (var call = client.Sum()) { - var numbers = new List { 10, 20, 30 }.ConvertAll(n => new Num{ Num_ = n }); + var numbers = new List { 10, 20, 30 }.ConvertAll(n => new Num { Num_ = n }); await call.RequestStream.WriteAllAsync(numbers); var result = await call.ResponseAsync; diff --git a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs index 95f742cc99..6c3a53bec0 100644 --- a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs +++ b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs @@ -88,7 +88,7 @@ namespace Grpc.HealthCheck.Tests [Test] public void ServiceDoesntExist() { - Assert.Throws(Is.TypeOf(typeof(RpcException)).And.Property("Status").Property("StatusCode").EqualTo(StatusCode.NotFound), () => client.Check(new HealthCheckRequest{ Host = "", Service = "nonexistent.service" })); + Assert.Throws(Is.TypeOf(typeof(RpcException)).And.Property("Status").Property("StatusCode").EqualTo(StatusCode.NotFound), () => client.Check(new HealthCheckRequest { Host = "", Service = "nonexistent.service" })); } // TODO(jtattermusch): add test with timeout once timeouts are supported diff --git a/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs b/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs index 8de8645cd1..2097c0dc8c 100644 --- a/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs +++ b/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs @@ -101,7 +101,7 @@ namespace Grpc.HealthCheck.Tests private static HealthCheckResponse.Types.ServingStatus GetStatusHelper(HealthServiceImpl impl, string host, string service) { - return impl.Check(new HealthCheckRequest{ Host = host, Service = service}, null).Result.Status; + return impl.Check(new HealthCheckRequest { Host = host, Service = service }, null).Result.Status; } } } diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs index ed51af1942..8343e54122 100644 --- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs +++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs @@ -37,13 +37,12 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; +using Google.Apis.Auth.OAuth2; +using Google.Protobuf; using Grpc.Auth; using Grpc.Core; using Grpc.Core.Utils; using Grpc.Testing; -using Google.Protobuf; -using Google.Apis.Auth.OAuth2; - using NUnit.Framework; namespace Grpc.IntegrationTesting -- cgit v1.2.3 From 4b41ba249df4f290b3551b82b6004a0ce77bf2cf Mon Sep 17 00:00:00 2001 From: Nathaniel Manista Date: Fri, 28 Aug 2015 15:48:23 +0000 Subject: Two fixes in grpc.framework.core._end (1) Call "cancel" on each future, not on the list of futures. (2) If and when futures mature their actions should simply abort all outstanding operations and cancel any other futures. They should not shut down the _End's internal thread pool; only the termination action of the last operation to terminate should shut down the pool (in the case of their having been active operations at the time at which the _End's stop(grace) method was called). --- src/python/grpcio/grpc/framework/core/_end.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/python/grpcio/grpc/framework/core/_end.py b/src/python/grpcio/grpc/framework/core/_end.py index fb2c532df6..5ef2f6d3a3 100644 --- a/src/python/grpcio/grpc/framework/core/_end.py +++ b/src/python/grpcio/grpc/framework/core/_end.py @@ -30,7 +30,6 @@ """Implementation of base.End.""" import abc -import enum import threading import uuid @@ -75,7 +74,7 @@ def _abort(operations): def _cancel_futures(futures): for future in futures: - futures.cancel() + future.cancel() def _future_shutdown(lock, cycle, event): @@ -83,8 +82,6 @@ def _future_shutdown(lock, cycle, event): with lock: _abort(cycle.operations.values()) _cancel_futures(cycle.futures) - pool = cycle.pool - cycle.pool.shutdown(wait=True) return in_future @@ -113,6 +110,7 @@ def _termination_action(lock, stats, operation_id, cycle): cycle.idle_actions = [] if cycle.grace: _cancel_futures(cycle.futures) + cycle.pool.shutdown(wait=False) return termination_action -- cgit v1.2.3 From 727956741da9e79b1f8c725ee61bc184e72e701e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 28 Aug 2015 08:54:26 -0700 Subject: check for allowed characters in metadata key --- src/csharp/Grpc.Core.Tests/MetadataTest.cs | 11 +++++++++++ src/csharp/Grpc.Core/Metadata.cs | 7 ++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core.Tests/MetadataTest.cs b/src/csharp/Grpc.Core.Tests/MetadataTest.cs index c00f945d6a..ddeb7d0926 100644 --- a/src/csharp/Grpc.Core.Tests/MetadataTest.cs +++ b/src/csharp/Grpc.Core.Tests/MetadataTest.cs @@ -74,6 +74,17 @@ namespace Grpc.Core.Tests Assert.AreEqual("[Entry: key=abc-bin, valueBytes=System.Byte[]]", entry.ToString()); } + [Test] + public void AsciiEntry_KeyValidity() + { + new Metadata.Entry("ABC", "XYZ"); + new Metadata.Entry("0123456789abc", "XYZ"); + new Metadata.Entry("-abc", "XYZ"); + new Metadata.Entry("a_bc_", "XYZ"); + Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc[", "xyz")); + Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc/", "xyz")); + } + [Test] public void Entry_ConstructionPreconditions() { diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core/Metadata.cs index 2b08e0de51..21bdf4f114 100644 --- a/src/csharp/Grpc.Core/Metadata.cs +++ b/src/csharp/Grpc.Core/Metadata.cs @@ -36,6 +36,7 @@ using System.Collections.Specialized; using System.Globalization; using System.Runtime.InteropServices; using System.Text; +using System.Text.RegularExpressions; using Grpc.Core.Utils; @@ -189,6 +190,7 @@ namespace Grpc.Core public struct Entry { private static readonly Encoding Encoding = Encoding.ASCII; + private static readonly Regex ValidKeyRegex = new Regex("^[a-z0-9_-]+$"); readonly string key; readonly string value; @@ -321,7 +323,10 @@ namespace Grpc.Core private static string NormalizeKey(string key) { - return Preconditions.CheckNotNull(key, "key").ToLower(CultureInfo.InvariantCulture); + var normalized = Preconditions.CheckNotNull(key, "key").ToLower(CultureInfo.InvariantCulture); + Preconditions.CheckArgument(ValidKeyRegex.IsMatch(normalized), + "Metadata entry key not valid. Keys can only contain lowercase alphanumeric characters, underscores and hyphens."); + return normalized; } } } -- cgit v1.2.3 From 6e6ddbec9183b0081c199908b2ef36d6d954de87 Mon Sep 17 00:00:00 2001 From: Nathaniel Manista Date: Fri, 28 Aug 2015 16:37:38 +0000 Subject: Accept addresses rather than ports in add_port --- src/python/grpcio/grpc/_links/service.py | 18 ++++++++++-------- .../grpc_test/_core_over_links_base_interface_test.py | 2 +- .../_crust_over_core_over_links_face_interface_test.py | 2 +- .../grpcio_test/grpc_test/_links/_transmission_test.py | 6 +++--- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/python/grpcio/grpc/_links/service.py b/src/python/grpcio/grpc/_links/service.py index 10634e43b5..393f80c1cc 100644 --- a/src/python/grpcio/grpc/_links/service.py +++ b/src/python/grpcio/grpc/_links/service.py @@ -316,9 +316,8 @@ class _Kernel(object): call.status(status, call) self._rpc_states.pop(call, None) - def add_port(self, port, server_credentials): + def add_port(self, address, server_credentials): with self._lock: - address = '[::]:%d' % port if self._server is None: self._completion_queue = _intermediary_low.CompletionQueue() self._server = _intermediary_low.Server(self._completion_queue) @@ -362,17 +361,20 @@ class ServiceLink(links.Link): """ @abc.abstractmethod - def add_port(self, port, server_credentials): + def add_port(self, address, server_credentials): """Adds a port on which to service RPCs after this link has been started. Args: - port: The port on which to service RPCs, or zero to request that a port - be automatically selected and used. + address: The address on which to service RPCs with a port number of zero + requesting that a port number be automatically selected and used. server_credentials: An _intermediary_low.ServerCredentials object, or None for insecure service. Returns: - A port on which RPCs will be serviced after this link has been started. + A integer port on which RPCs will be serviced after this link has been + started. This is typically the same number as the port number contained + in the passed address, but will likely be different if the port number + contained in the passed address was zero. """ raise NotImplementedError() @@ -417,8 +419,8 @@ class _ServiceLink(ServiceLink): def join_link(self, link): self._relay.set_behavior(link.accept_ticket) - def add_port(self, port, server_credentials): - return self._kernel.add_port(port, server_credentials) + def add_port(self, address, server_credentials): + return self._kernel.add_port(address, server_credentials) def start(self): self._relay.start() diff --git a/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py b/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py index 7fa90fe35f..9c095d670c 100644 --- a/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py +++ b/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py @@ -95,7 +95,7 @@ class _Implementation(test_interfaces.Implementation): service_grpc_link = service.service_link( serialization_behaviors.request_deserializers, serialization_behaviors.response_serializers) - port = service_grpc_link.add_port(0, None) + port = service_grpc_link.add_port('[::]:0', None) channel = _intermediary_low.Channel('localhost:%d' % port, None) invocation_grpc_link = invocation.invocation_link( channel, b'localhost', diff --git a/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py b/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py index 25b99cbbaf..1659a58325 100644 --- a/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py +++ b/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py @@ -85,7 +85,7 @@ class _Implementation(test_interfaces.Implementation): service_grpc_link = service.service_link( serialization_behaviors.request_deserializers, serialization_behaviors.response_serializers) - port = service_grpc_link.add_port(0, None) + port = service_grpc_link.add_port('[::]:0', None) channel = _intermediary_low.Channel('localhost:%d' % port, None) invocation_grpc_link = invocation.invocation_link( channel, b'localhost', diff --git a/src/python/grpcio_test/grpc_test/_links/_transmission_test.py b/src/python/grpcio_test/grpc_test/_links/_transmission_test.py index db011bca66..0fef9b0c5a 100644 --- a/src/python/grpcio_test/grpc_test/_links/_transmission_test.py +++ b/src/python/grpcio_test/grpc_test/_links/_transmission_test.py @@ -50,7 +50,7 @@ class TransmissionTest(test_cases.TransmissionTest, unittest.TestCase): service_link = service.service_link( {self.group_and_method(): self.deserialize_request}, {self.group_and_method(): self.serialize_response}) - port = service_link.add_port(0, None) + port = service_link.add_port('[::]:0', None) service_link.start() channel = _intermediary_low.Channel('localhost:%d' % port, None) invocation_link = invocation.invocation_link( @@ -116,7 +116,7 @@ class RoundTripTest(unittest.TestCase): identity_transformation, identity_transformation) service_mate = test_utilities.RecordingLink() service_link.join_link(service_mate) - port = service_link.add_port(0, None) + port = service_link.add_port('[::]:0', None) service_link.start() channel = _intermediary_low.Channel('localhost:%d' % port, None) invocation_link = invocation.invocation_link( @@ -160,7 +160,7 @@ class RoundTripTest(unittest.TestCase): {(test_group, test_method): scenario.serialize_response}) service_mate = test_utilities.RecordingLink() service_link.join_link(service_mate) - port = service_link.add_port(0, None) + port = service_link.add_port('[::]:0', None) service_link.start() channel = _intermediary_low.Channel('localhost:%d' % port, None) invocation_link = invocation.invocation_link( -- cgit v1.2.3 From 4a6bbdddd392b06370c0fc56868855d05c0c66ec Mon Sep 17 00:00:00 2001 From: Nathaniel Manista Date: Fri, 28 Aug 2015 17:38:05 +0000 Subject: Python test clean-up (1) Move metadata and details constants for gRPC-on-the-wire tests into grpc.test_common. (2) Drop definitions of setUpModule and tearDownModule from a unit test module that, because it uses the load_tests protocol, never had those methods called anyway. :-( --- .../_core_over_links_base_interface_test.py | 20 +++++--------------- ...crust_over_core_over_links_face_interface_test.py | 11 +++++------ src/python/grpcio_test/grpc_test/test_common.py | 5 +++++ 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py b/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py index 7fa90fe35f..c8e325aea0 100644 --- a/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py +++ b/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py @@ -45,11 +45,7 @@ from grpc_test.framework.common import test_constants from grpc_test.framework.interfaces.base import test_cases from grpc_test.framework.interfaces.base import test_interfaces -_INVOCATION_INITIAL_METADATA = ((b'0', b'abc'), (b'1', b'def'), (b'2', b'ghi'),) -_SERVICE_INITIAL_METADATA = ((b'3', b'jkl'), (b'4', b'mno'), (b'5', b'pqr'),) -_SERVICE_TERMINAL_METADATA = ((b'6', b'stu'), (b'7', b'vwx'), (b'8', b'yza'),) _CODE = _intermediary_low.Code.OK -_MESSAGE = b'test message' class _SerializationBehaviors( @@ -117,16 +113,18 @@ class _Implementation(test_interfaces.Implementation): service_grpc_link.stop_gracefully() def invocation_initial_metadata(self): - return _INVOCATION_INITIAL_METADATA + return grpc_test_common.INVOCATION_INITIAL_METADATA def service_initial_metadata(self): - return _SERVICE_INITIAL_METADATA + return grpc_test_common.SERVICE_INITIAL_METADATA def invocation_completion(self): return utilities.completion(None, None, None) def service_completion(self): - return utilities.completion(_SERVICE_TERMINAL_METADATA, _CODE, _MESSAGE) + return utilities.completion( + grpc_test_common.SERVICE_TERMINAL_METADATA, _CODE, + grpc_test_common.DETAILS) def metadata_transmitted(self, original_metadata, transmitted_metadata): return original_metadata is None or grpc_test_common.metadata_transmitted( @@ -146,14 +144,6 @@ class _Implementation(test_interfaces.Implementation): return True -def setUpModule(): - logging.warn('setUpModule!') - - -def tearDownModule(): - logging.warn('tearDownModule!') - - def load_tests(loader, tests, pattern): return unittest.TestSuite( tests=tuple( diff --git a/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py b/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py index 25b99cbbaf..5ba6d4afe6 100644 --- a/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py +++ b/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py @@ -39,11 +39,10 @@ from grpc.framework.core import implementations as core_implementations from grpc.framework.crust import implementations as crust_implementations from grpc.framework.foundation import logging_pool from grpc.framework.interfaces.links import utilities -from grpc_test import test_common +from grpc_test import test_common as grpc_test_common from grpc_test.framework.common import test_constants from grpc_test.framework.interfaces.face import test_cases from grpc_test.framework.interfaces.face import test_interfaces -from grpc_test.framework.interfaces.links import test_utilities class _SerializationBehaviors( @@ -130,19 +129,19 @@ class _Implementation(test_interfaces.Implementation): pool.shutdown(wait=True) def invocation_metadata(self): - return test_common.INVOCATION_INITIAL_METADATA + return grpc_test_common.INVOCATION_INITIAL_METADATA def initial_metadata(self): - return test_common.SERVICE_INITIAL_METADATA + return grpc_test_common.SERVICE_INITIAL_METADATA def terminal_metadata(self): - return test_common.SERVICE_TERMINAL_METADATA + return grpc_test_common.SERVICE_TERMINAL_METADATA def code(self): return _intermediary_low.Code.OK def details(self): - return test_common.DETAILS + return grpc_test_common.DETAILS def metadata_transmitted(self, original_metadata, transmitted_metadata): return original_metadata is None or grpc_test_common.metadata_transmitted( diff --git a/src/python/grpcio_test/grpc_test/test_common.py b/src/python/grpcio_test/grpc_test/test_common.py index f8e1f1e43f..44284be88b 100644 --- a/src/python/grpcio_test/grpc_test/test_common.py +++ b/src/python/grpcio_test/grpc_test/test_common.py @@ -31,6 +31,11 @@ import collections +INVOCATION_INITIAL_METADATA = ((b'0', b'abc'), (b'1', b'def'), (b'2', b'ghi'),) +SERVICE_INITIAL_METADATA = ((b'3', b'jkl'), (b'4', b'mno'), (b'5', b'pqr'),) +SERVICE_TERMINAL_METADATA = ((b'6', b'stu'), (b'7', b'vwx'), (b'8', b'yza'),) +DETAILS = b'test details' + def metadata_transmitted(original_metadata, transmitted_metadata): """Judges whether or not metadata was acceptably transmitted. -- cgit v1.2.3 From c3ee1d5eb4aa790db7c309627286be5d60ff60ec Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 28 Aug 2015 11:33:52 -0700 Subject: Do not include internal proto header --- src/compiler/csharp_generator.cc | 7 +++++-- src/compiler/csharp_generator.h | 3 --- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index 51d8d982e2..7b497df7f4 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -33,6 +33,7 @@ #include #include +#include #include #include "src/compiler/csharp_generator.h" @@ -44,7 +45,6 @@ using google::protobuf::compiler::csharp::GetFileNamespace; using google::protobuf::compiler::csharp::GetClassName; using google::protobuf::compiler::csharp::GetUmbrellaClassName; -using google::protobuf::SimpleItoa; using grpc::protobuf::FileDescriptor; using grpc::protobuf::Descriptor; using grpc::protobuf::ServiceDescriptor; @@ -228,11 +228,14 @@ void GenerateStaticMethodField(Printer* out, const MethodDescriptor *method) { } void GenerateServiceDescriptorProperty(Printer* out, const ServiceDescriptor *service) { + std::ostringstream index; + index << service->index(); out->Print("// service descriptor\n"); out->Print("public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor\n"); out->Print("{\n"); out->Print(" get { return $umbrella$.Descriptor.Services[$index$]; }\n", - "umbrella", GetUmbrellaClassName(service->file()), "index", SimpleItoa(service->index())); + "umbrella", GetUmbrellaClassName(service->file()), "index", + index.str()); out->Print("}\n"); out->Print("\n"); } diff --git a/src/compiler/csharp_generator.h b/src/compiler/csharp_generator.h index 67e3ee30b5..90eb7e2984 100644 --- a/src/compiler/csharp_generator.h +++ b/src/compiler/csharp_generator.h @@ -36,10 +36,7 @@ #include "src/compiler/config.h" -using namespace std; - #include -#include namespace grpc_csharp_generator { -- cgit v1.2.3 From 487a72b7262f0184c517093c2a8a6a7ef5fba046 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 28 Aug 2015 13:33:38 -0700 Subject: Provide troubleshooting instructions for 'cannot load grpc_csharp_ext.dll' problem. --- src/csharp/README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/csharp/README.md b/src/csharp/README.md index 30523b3bd2..3fbc1c5f05 100644 --- a/src/csharp/README.md +++ b/src/csharp/README.md @@ -158,3 +158,20 @@ Contents An example client that sends some requests to math server. - Grpc.IntegrationTesting: Cross-language gRPC implementation testing (interop testing). + +Troubleshooting +--------------- + +### Problem: Unable to load DLL 'grpc_csharp_ext.dll' + +Internally, gRPC C# uses a native library written in C (gRPC C core) and invokes its functionality via P/Invoke. `grpc_csharp_ext` library is a native extension library that facilitates this by wrapping some C core API into a form that's more digestible for P/Invoke. If you get the above error, it means that the native dependencies could not be located by the C# runtime (or they are incompatible with the current runtime, so they could not be loaded). The solution to this is environment specific. + +- If you are developing on Windows in Visual Studio, the `grpc_csharp_ext.dll` that is shipped by gRPC nuget packages should be automatically copied to your build destination folder once you build. By adjusting project properties in your VS project file, you can influence which exact configuration of `grpc_csharp_ext.dll` will be used (based on VS version, bitness, debug/release configuration). + +- If you are running your application that is using gRPC on Windows machine that doesn't have Visual Studio installed, you might need to install [Visual C++ 2013 redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=40784) that contains some system .dll libraries that `grpc_csharp_ext.dll` depends on (see #905 for more details). + +- On Linux (or Docker), you need to first install gRPC C core and `libgrpc_csharp_ext.so` shared libraries. Currently, the libraries can be installed by `make install_grpc_csharp_ext` or using Linuxbrew (a Debian package is coming soon). Installation on a machine where your application is going to be deployed is no different. + +- On Mac, you need to first install gRPC C core and `libgrpc_csharp_ext.dylib` shared libraries using Homebrew. See above for installation instruction. Installation on a machine where your application is going to be deployed is no different. + +- Possible cause for the problem is that the `grpc_csharp_ext` library is installed, but it has different bitness (32/64bit) than your C# runtime (in case you are using mono) or C# application. -- cgit v1.2.3 From 6afe53f2360a20a4d3abda60cfdde576c29b9857 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Fri, 28 Aug 2015 14:05:15 -0700 Subject: add functions for getting trace records --- include/grpc/census.h | 48 +++++++++++++++++++++++++++++++++++++++++++++-- src/core/census/tracing.c | 4 ++-- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/include/grpc/census.h b/include/grpc/census.h index ef6275fe58..d1a2978bd2 100644 --- a/include/grpc/census.h +++ b/include/grpc/census.h @@ -276,9 +276,53 @@ census_context *census_start_op(census_context *context, const char *family, */ void census_end_op(census_context *context, int status); +#define CENSUS_TRACE_RECORD_START_OP ((gpr_uint32)0) +#define CENSUS_TRACE_RECORD_END_OP ((gpr_uint32)1) + /** Insert a trace record into the trace stream. The record consists of an - * arbitrary size buffer, the size of which is provided in 'n'. */ -void census_trace_print(census_context *context, const char *buffer, size_t n); + arbitrary size buffer, the size of which is provided in 'n'. + @param context Trace context + @param type User-defined type to associate with trace entry. + @param buffer Pointer to buffer to use + @param n Number of bytes in buffer +*/ +void census_trace_print(census_context *context, gpr_uint32 type, + const char *buffer, size_t n); + +/** Trace record. */ +typedef struct { + census_timestamp timestamp; /* Time of record creation */ + gpr_uint64 trace_id; /* Trace ID associated with record */ + gpr_uint64 op_id; /* Operation ID associated with record */ + gpr_uint32 type; /* Type (as used in census_trace_print() */ + const char *buffer; /* Buffer (from census_trace_print() */ + size_t buf_size; /* Number of bytes inside buffer */ +} census_trace_record; + +/** Start a scan of existing trace records. While a scan is ongoing, addition + of new trace records will be blocked if the underlying trace buffers + fill up, so trace processing systems should endeavor to complete + reading as soon as possible. + @param consume if non-zero, indicates that reading records also "consumes" + the previously read record - i.e. releases space in the trace log + while scanning is ongoing. + @returns 0 on success, non-zero on failure (e.g. if a scan is already ongoing) +*/ +int census_trace_scan_start(int consume); + +/** Get a trace record. The data pointed to by the trace buffer is guaranteed + stable until the next census_get_trace_record() call (if the consume + argument to census_trace_scan_start was non-zero) or census_trace_scan_end() + is called (otherwise). + @param trace_record structure that will be filled in with oldest trace record. + @returns -1 if an error occurred (e.g. no previous call to + census_trace_scan_start()), 0 if there is no more trace data (and + trace_record will not be modified) or 1 otherwise. +*/ +int census_get_trace_record(census_trace_record *trace_record); + +/** End a scan previously started by census_trace_scan_start() */ +void census_trace_scan_end(); /* Max number of characters in tag key */ #define CENSUS_MAX_TAG_KEY_LENGTH 20 diff --git a/src/core/census/tracing.c b/src/core/census/tracing.c index 44db95653c..ae38773c0a 100644 --- a/src/core/census/tracing.c +++ b/src/core/census/tracing.c @@ -41,5 +41,5 @@ int census_trace_mask(const census_context *context) { void census_set_trace_mask(int trace_mask) {} -void census_trace_print(census_context *context, const char *buffer, size_t n) { -} +void census_trace_print(census_context *context, gpr_uint32 type, + const char *buffer, size_t n) {} -- cgit v1.2.3 From 4354f3e6809f12512d93b33e667133bc15f44029 Mon Sep 17 00:00:00 2001 From: Nathaniel Manista Date: Fri, 28 Aug 2015 16:07:23 +0000 Subject: Make ServiceLink shut-down a two step process --- src/python/grpcio/grpc/_links/service.py | 33 +++++++++++----------- .../_core_over_links_base_interface_test.py | 3 +- ...ust_over_core_over_links_face_interface_test.py | 3 +- .../grpc_test/_links/_transmission_test.py | 9 ++++-- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/python/grpcio/grpc/_links/service.py b/src/python/grpcio/grpc/_links/service.py index 10634e43b5..5ab8efb4c4 100644 --- a/src/python/grpcio/grpc/_links/service.py +++ b/src/python/grpcio/grpc/_links/service.py @@ -337,10 +337,13 @@ class _Kernel(object): self._server.start() self._server.service(None) - def graceful_stop(self): + def begin_stop(self): with self._lock: self._server.stop() self._server = None + + def end_stop(self): + with self._lock: self._completion_queue.stop() self._completion_queue = None pool = self._pool @@ -348,11 +351,6 @@ class _Kernel(object): self._rpc_states = None pool.shutdown(wait=True) - def immediate_stop(self): - # TODO(nathaniel): Implementation. - raise NotImplementedError( - 'TODO(nathaniel): after merge of rewritten lower layers') - class ServiceLink(links.Link): """A links.Link for use on the service-side of a gRPC connection. @@ -386,18 +384,20 @@ class ServiceLink(links.Link): raise NotImplementedError() @abc.abstractmethod - def stop_gracefully(self): - """Stops this link. + def begin_stop(self): + """Indicate imminent link stop and immediate rejection of new RPCs. New RPCs will be rejected as soon as this method is called, but ongoing RPCs - will be allowed to continue until they terminate. This method blocks until - all RPCs have terminated. + will be allowed to continue until they terminate. This method does not + block. """ raise NotImplementedError() @abc.abstractmethod - def stop_immediately(self): - """Stops this link. + def end_stop(self): + """Finishes stopping this link. + + begin_stop must have been called exactly once before calling this method. All in-progress RPCs will be terminated immediately. """ @@ -424,12 +424,11 @@ class _ServiceLink(ServiceLink): self._relay.start() return self._kernel.start() - def stop_gracefully(self): - self._kernel.graceful_stop() - self._relay.stop() + def begin_stop(self): + self._kernel.begin_stop() - def stop_immediately(self): - self._kernel.immediate_stop() + def end_stop(self): + self._kernel.end_stop() self._relay.stop() diff --git a/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py b/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py index 7fa90fe35f..91386f2697 100644 --- a/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py +++ b/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py @@ -114,7 +114,8 @@ class _Implementation(test_interfaces.Implementation): def destantiate(self, memo): invocation_grpc_link, service_grpc_link = memo invocation_grpc_link.stop() - service_grpc_link.stop_gracefully() + service_grpc_link.begin_stop() + service_grpc_link.end_stop() def invocation_initial_metadata(self): return _INVOCATION_INITIAL_METADATA diff --git a/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py b/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py index 25b99cbbaf..c619056170 100644 --- a/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py +++ b/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py @@ -121,8 +121,9 @@ class _Implementation(test_interfaces.Implementation): service_end_link, pool) = memo invocation_end_link.stop(0).wait() invocation_grpc_link.stop() - service_grpc_link.stop_gracefully() + service_grpc_link.begin_stop() service_end_link.stop(0).wait() + service_grpc_link.end_stop() invocation_end_link.join_link(utilities.NULL_LINK) invocation_grpc_link.join_link(utilities.NULL_LINK) service_grpc_link.join_link(utilities.NULL_LINK) diff --git a/src/python/grpcio_test/grpc_test/_links/_transmission_test.py b/src/python/grpcio_test/grpc_test/_links/_transmission_test.py index db011bca66..616d8a670d 100644 --- a/src/python/grpcio_test/grpc_test/_links/_transmission_test.py +++ b/src/python/grpcio_test/grpc_test/_links/_transmission_test.py @@ -62,7 +62,8 @@ class TransmissionTest(test_cases.TransmissionTest, unittest.TestCase): def destroy_transmitting_links(self, invocation_side_link, service_side_link): invocation_side_link.stop() - service_side_link.stop_gracefully() + service_side_link.begin_stop() + service_side_link.end_stop() def create_invocation_initial_metadata(self): return ( @@ -140,7 +141,8 @@ class RoundTripTest(unittest.TestCase): invocation_mate.block_until_tickets_satisfy(test_cases.terminated) invocation_link.stop() - service_link.stop_gracefully() + service_link.begin_stop() + service_link.end_stop() self.assertIs( service_mate.tickets()[-1].termination, @@ -206,7 +208,8 @@ class RoundTripTest(unittest.TestCase): invocation_mate.block_until_tickets_satisfy(test_cases.terminated) invocation_link.stop() - service_link.stop_gracefully() + service_link.begin_stop() + service_link.end_stop() observed_requests = tuple( ticket.payload for ticket in service_mate.tickets() -- cgit v1.2.3 From 0c711ad88b632bea173bdea9ea24372052aa231d Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Fri, 28 Aug 2015 14:10:58 -0700 Subject: Adding C++ metadata processor. - Had to chnage the core API to add a destroy function pointer in grpc_auth_metadata_processor. - Tested end to end. - Fixed some issues in the server_auth_filter (we were not checking the length which put us at risk of an overflow). --- include/grpc++/auth_metadata_processor.h | 5 +- include/grpc++/server_credentials.h | 10 +- include/grpc++/support/auth_context.h | 5 +- include/grpc/grpc_security.h | 1 + src/core/security/credentials.c | 15 +- src/core/security/security_context.c | 13 -- src/core/security/server_auth_filter.c | 10 +- src/core/security/server_secure_chttp2.c | 9 ++ src/cpp/client/create_channel.cc | 1 + src/cpp/common/secure_auth_context.cc | 15 +- src/cpp/common/secure_auth_context.h | 7 +- src/cpp/common/secure_create_auth_context.cc | 2 +- src/cpp/server/secure_server_credentials.cc | 17 +- src/cpp/server/secure_server_credentials.h | 2 + test/core/end2end/fixtures/chttp2_fake_security.c | 2 +- .../end2end/fixtures/chttp2_simple_ssl_fullstack.c | 2 +- .../chttp2_simple_ssl_fullstack_with_poll.c | 2 +- .../chttp2_simple_ssl_fullstack_with_proxy.c | 2 +- .../chttp2_simple_ssl_with_oauth2_fullstack.c | 45 ++++-- test/cpp/end2end/end2end_test.cc | 175 +++++++++++++++++++-- test/cpp/util/messages.proto | 1 + 21 files changed, 276 insertions(+), 65 deletions(-) diff --git a/include/grpc++/auth_metadata_processor.h b/include/grpc++/auth_metadata_processor.h index c0631bc11f..a42abef416 100644 --- a/include/grpc++/auth_metadata_processor.h +++ b/include/grpc++/auth_metadata_processor.h @@ -58,7 +58,10 @@ class AuthMetadataProcessor { // from the passed-in auth_metadata. // consumed_auth_metadata needs to be filled with metadata that has been // consumed by the processor and will be removed from the call. - // TODO(jboeuf). + // response_metadata is the metadata that will be sent as part of the + // response. + // If the return value is not Status::OK, the rpc call will be aborted with + // the error code and error message sent back to the client. virtual Status Process(const InputMetadata& auth_metadata, AuthContext* context, OutputMetadata* consumed_auth_metadata, diff --git a/include/grpc++/server_credentials.h b/include/grpc++/server_credentials.h index 486c35c56b..e006f3a180 100644 --- a/include/grpc++/server_credentials.h +++ b/include/grpc++/server_credentials.h @@ -50,16 +50,16 @@ class ServerCredentials { public: virtual ~ServerCredentials(); + // This method is not thread-safe and has to be called before the server is + // started. The last call to this function wins. + virtual void SetAuthMetadataProcessor( + const std::shared_ptr& processor) = 0; + private: friend class ::grpc::Server; virtual int AddPortToServer(const grpc::string& addr, grpc_server* server) = 0; - - // This method is not thread-safe and has to be called before the server is - // started. The last call to this function wins. - virtual void SetAuthMetadataProcessor( - const std::shared_ptr& processor) = 0; }; // Options to create ServerCredentials with SSL diff --git a/include/grpc++/support/auth_context.h b/include/grpc++/support/auth_context.h index 5d5f8e837d..fc2701e806 100644 --- a/include/grpc++/support/auth_context.h +++ b/include/grpc++/support/auth_context.h @@ -77,6 +77,9 @@ class AuthContext { public: virtual ~AuthContext() {} + // Returns true if the peer is authenticated. + virtual bool IsPeerAuthenticated() const = 0; + // A peer identity, in general is one or more properties (in which case they // have the same name). virtual std::vector GetPeerIdentity() const = 0; @@ -92,7 +95,7 @@ class AuthContext { // Mutation functions: should only be used by an AuthMetadataProcessor. virtual void AddProperty(const grpc::string& key, - const grpc::string& value) = 0; + const grpc::string_ref& value) = 0; virtual bool SetPeerIdentityPropertyName(const grpc::string& name) = 0; }; diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index e2205eea30..0b540c0e66 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -293,6 +293,7 @@ typedef struct { void (*process)(void *state, grpc_auth_context *context, const grpc_metadata *md, size_t num_md, grpc_process_auth_metadata_done_cb cb, void *user_data); + void (*destroy)(void *state); void *state; } grpc_auth_metadata_processor; diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c index 362d5f4b6f..cae80f0216 100644 --- a/src/core/security/credentials.c +++ b/src/core/security/credentials.c @@ -152,9 +152,20 @@ grpc_security_status grpc_server_credentials_create_security_connector( void grpc_server_credentials_set_auth_metadata_processor( grpc_server_credentials *creds, grpc_auth_metadata_processor processor) { if (creds == NULL) return; + if (creds->processor.destroy != NULL && creds->processor.state != NULL) { + creds->processor.destroy(creds->processor.state); + } creds->processor = processor; } +void grpc_server_credentials_destroy(grpc_server_credentials *creds) { + if (creds == NULL) return; + if (creds->processor.destroy != NULL && creds->processor.state != NULL) { + creds->processor.destroy(creds->processor.state); + } + gpr_free(creds); +} + /* -- Ssl credentials. -- */ static void ssl_destroy(grpc_credentials *creds) { @@ -185,7 +196,7 @@ static void ssl_server_destroy(grpc_server_credentials *creds) { gpr_free(c->config.pem_cert_chains_sizes); } if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs); - gpr_free(creds); + grpc_server_credentials_destroy(creds); } static int ssl_has_request_metadata(const grpc_credentials *creds) { return 0; } @@ -902,7 +913,7 @@ static void fake_transport_security_credentials_destroy( static void fake_transport_security_server_credentials_destroy( grpc_server_credentials *creds) { - gpr_free(creds); + grpc_server_credentials_destroy(creds); } static int fake_transport_security_has_request_metadata( diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c index c1b434f302..95d80ba122 100644 --- a/src/core/security/security_context.c +++ b/src/core/security/security_context.c @@ -42,19 +42,6 @@ #include #include -/* --- grpc_process_auth_metadata_func --- */ - -static grpc_auth_metadata_processor server_processor = {NULL, NULL}; - -grpc_auth_metadata_processor grpc_server_get_auth_metadata_processor(void) { - return server_processor; -} - -void grpc_server_register_auth_metadata_processor( - grpc_auth_metadata_processor processor) { - server_processor = processor; -} - /* --- grpc_call --- */ grpc_call_error grpc_call_set_credentials(grpc_call *call, diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c index 57729be32c..b767f85498 100644 --- a/src/core/security/server_auth_filter.c +++ b/src/core/security/server_auth_filter.c @@ -91,13 +91,17 @@ static grpc_mdelem *remove_consumed_md(void *user_data, grpc_mdelem *md) { call_data *calld = elem->call_data; size_t i; for (i = 0; i < calld->num_consumed_md; i++) { + const grpc_metadata *consumed_md = &calld->consumed_md[i]; /* Maybe we could do a pointer comparison but we do not have any guarantee that the metadata processor used the same pointers for consumed_md in the callback. */ - if (memcmp(GPR_SLICE_START_PTR(md->key->slice), calld->consumed_md[i].key, + if (GPR_SLICE_LENGTH(md->key->slice) != strlen(consumed_md->key) || + GPR_SLICE_LENGTH(md->value->slice) != consumed_md->value_length) { + continue; + } + if (memcmp(GPR_SLICE_START_PTR(md->key->slice), consumed_md->key, GPR_SLICE_LENGTH(md->key->slice)) == 0 && - memcmp(GPR_SLICE_START_PTR(md->value->slice), - calld->consumed_md[i].value, + memcmp(GPR_SLICE_START_PTR(md->value->slice), consumed_md->value, GPR_SLICE_LENGTH(md->value->slice)) == 0) { return NULL; /* Delete. */ } diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c index 8d9d036d80..96ca4cbd76 100644 --- a/src/core/security/server_secure_chttp2.c +++ b/src/core/security/server_secure_chttp2.c @@ -79,6 +79,9 @@ static void state_unref(grpc_server_secure_state *state) { gpr_mu_unlock(&state->mu); /* clean up */ GRPC_SECURITY_CONNECTOR_UNREF(state->sc, "server"); + if (state->processor.state != NULL && state->processor.destroy != NULL) { + state->processor.destroy(state->processor.state); + } gpr_free(state); } } @@ -262,7 +265,13 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, state->server = server; state->tcp = tcp; state->sc = sc; + + /* Transfer ownership of the processor. */ state->processor = creds->processor; + creds->processor.state = NULL; + creds->processor.destroy = NULL; + creds->processor.process = NULL; + state->handshaking_tcp_endpoints = NULL; state->is_shutdown = 0; gpr_mu_init(&state->mu); diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index 8c571cbbaa..4f6f2dd068 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -46,6 +46,7 @@ class ChannelArguments; std::shared_ptr CreateChannel( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args) { + GrpcLibrary init_lib; // We need to call init in case of a bad creds. ChannelArguments cp_args = args; std::ostringstream user_agent_prefix; user_agent_prefix << "grpc-c++/" << grpc_version_string(); diff --git a/src/cpp/common/secure_auth_context.cc b/src/cpp/common/secure_auth_context.cc index 823ad8b0e2..8615ac8aeb 100644 --- a/src/cpp/common/secure_auth_context.cc +++ b/src/cpp/common/secure_auth_context.cc @@ -37,9 +37,13 @@ namespace grpc { -SecureAuthContext::SecureAuthContext(grpc_auth_context* ctx) : ctx_(ctx) {} +SecureAuthContext::SecureAuthContext(grpc_auth_context* ctx, + bool take_ownership) + : ctx_(ctx), take_ownership_(take_ownership) {} -SecureAuthContext::~SecureAuthContext() { grpc_auth_context_release(ctx_); } +SecureAuthContext::~SecureAuthContext() { + if (take_ownership_) grpc_auth_context_release(ctx_); +} std::vector SecureAuthContext::GetPeerIdentity() const { if (!ctx_) { @@ -95,7 +99,7 @@ AuthPropertyIterator SecureAuthContext::end() const { } void SecureAuthContext::AddProperty(const grpc::string& key, - const grpc::string& value) { + const grpc::string_ref& value) { if (!ctx_) return; grpc_auth_context_add_property(ctx_, key.c_str(), value.data(), value.size()); } @@ -106,4 +110,9 @@ bool SecureAuthContext::SetPeerIdentityPropertyName(const grpc::string& name) { name.c_str()) != 0; } +bool SecureAuthContext::IsPeerAuthenticated() const { + if (!ctx_) return false; + return grpc_auth_context_peer_is_authenticated(ctx_) != 0; +} + } // namespace grpc diff --git a/src/cpp/common/secure_auth_context.h b/src/cpp/common/secure_auth_context.h index cc09a29ecb..6edab0cee1 100644 --- a/src/cpp/common/secure_auth_context.h +++ b/src/cpp/common/secure_auth_context.h @@ -42,10 +42,12 @@ namespace grpc { class SecureAuthContext GRPC_FINAL : public AuthContext { public: - SecureAuthContext(grpc_auth_context* ctx); + SecureAuthContext(grpc_auth_context* ctx, bool take_ownership); ~SecureAuthContext() GRPC_OVERRIDE; + bool IsPeerAuthenticated() const GRPC_OVERRIDE; + std::vector GetPeerIdentity() const GRPC_OVERRIDE; grpc::string GetPeerIdentityPropertyName() const GRPC_OVERRIDE; @@ -58,13 +60,14 @@ class SecureAuthContext GRPC_FINAL : public AuthContext { AuthPropertyIterator end() const GRPC_OVERRIDE; void AddProperty(const grpc::string& key, - const grpc::string& value) GRPC_OVERRIDE; + const grpc::string_ref& value) GRPC_OVERRIDE; virtual bool SetPeerIdentityPropertyName(const grpc::string& name) GRPC_OVERRIDE; private: grpc_auth_context* ctx_; + bool take_ownership_; }; } // namespace grpc diff --git a/src/cpp/common/secure_create_auth_context.cc b/src/cpp/common/secure_create_auth_context.cc index f13d25a1dd..5a907d0c0b 100644 --- a/src/cpp/common/secure_create_auth_context.cc +++ b/src/cpp/common/secure_create_auth_context.cc @@ -44,7 +44,7 @@ std::shared_ptr CreateAuthContext(grpc_call* call) { return std::shared_ptr(); } return std::shared_ptr( - new SecureAuthContext(grpc_call_auth_context(call))); + new SecureAuthContext(grpc_call_auth_context(call), true)); } } // namespace grpc diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc index f8847b80f7..0e2927bafe 100644 --- a/src/cpp/server/secure_server_credentials.cc +++ b/src/cpp/server/secure_server_credentials.cc @@ -43,6 +43,11 @@ namespace grpc { +void AuthMetadataProcessorAyncWrapper::Destroy(void *wrapper) { + auto* w = reinterpret_cast(wrapper); + delete w; +} + void AuthMetadataProcessorAyncWrapper::Process( void* wrapper, grpc_auth_context* context, const grpc_metadata* md, size_t num_md, grpc_process_auth_metadata_done_cb cb, void* user_data) { @@ -71,14 +76,14 @@ void AuthMetadataProcessorAyncWrapper::InvokeProcessor( metadata.insert(std::make_pair( md[i].key, grpc::string_ref(md[i].value, md[i].value_length))); } - SecureAuthContext context(ctx); + SecureAuthContext context(ctx, false); AuthMetadataProcessor::OutputMetadata consumed_metadata; AuthMetadataProcessor::OutputMetadata response_metadata; Status status = processor_->Process(metadata, &context, &consumed_metadata, &response_metadata); - std::vector consumed_md(consumed_metadata.size()); + std::vector consumed_md; for (auto it = consumed_metadata.begin(); it != consumed_metadata.end(); ++it) { consumed_md.push_back({it->first.c_str(), @@ -87,8 +92,7 @@ void AuthMetadataProcessorAyncWrapper::InvokeProcessor( 0, {{nullptr, nullptr, nullptr, nullptr}}}); } - - std::vector response_md(response_metadata.size()); + std::vector response_md; for (auto it = response_metadata.begin(); it != response_metadata.end(); ++it) { response_md.push_back({it->first.c_str(), @@ -109,9 +113,10 @@ int SecureServerCredentials::AddPortToServer(const grpc::string& addr, void SecureServerCredentials::SetAuthMetadataProcessor( const std::shared_ptr& processor) { - processor_.reset(new AuthMetadataProcessorAyncWrapper(processor)); + auto *wrapper = new AuthMetadataProcessorAyncWrapper(processor); grpc_server_credentials_set_auth_metadata_processor( - creds_, {AuthMetadataProcessorAyncWrapper::Process, processor_.get()}); + creds_, {AuthMetadataProcessorAyncWrapper::Process, + AuthMetadataProcessorAyncWrapper::Destroy, wrapper}); } std::shared_ptr SslServerCredentials( diff --git a/src/cpp/server/secure_server_credentials.h b/src/cpp/server/secure_server_credentials.h index d15b793b15..17be9e310d 100644 --- a/src/cpp/server/secure_server_credentials.h +++ b/src/cpp/server/secure_server_credentials.h @@ -46,6 +46,8 @@ namespace grpc { class AuthMetadataProcessorAyncWrapper GRPC_FINAL { public: + static void Destroy(void *wrapper); + static void Process(void* wrapper, grpc_auth_context* context, const grpc_metadata* md, size_t num_md, grpc_process_auth_metadata_done_cb cb, void* user_data); diff --git a/test/core/end2end/fixtures/chttp2_fake_security.c b/test/core/end2end/fixtures/chttp2_fake_security.c index b4a248fb52..3e64cc08e8 100644 --- a/test/core/end2end/fixtures/chttp2_fake_security.c +++ b/test/core/end2end/fixtures/chttp2_fake_security.c @@ -128,7 +128,7 @@ static void chttp2_init_server_fake_secure_fullstack( grpc_server_credentials *fake_ts_creds = grpc_fake_transport_security_server_credentials_create(); if (fail_server_auth_check(server_args)) { - grpc_auth_metadata_processor processor = {process_auth_failure, NULL}; + grpc_auth_metadata_processor processor = {process_auth_failure, NULL, NULL}; grpc_server_credentials_set_auth_metadata_processor(fake_ts_creds, processor); } diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c index 201d202dff..9193a09b17 100644 --- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c @@ -138,7 +138,7 @@ static void chttp2_init_server_simple_ssl_secure_fullstack( grpc_server_credentials *ssl_creds = grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL); if (fail_server_auth_check(server_args)) { - grpc_auth_metadata_processor processor = {process_auth_failure, NULL}; + grpc_auth_metadata_processor processor = {process_auth_failure, NULL, NULL}; grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor); } chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c index e7375f15e6..2c605d1471 100644 --- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c @@ -138,7 +138,7 @@ static void chttp2_init_server_simple_ssl_secure_fullstack( grpc_server_credentials *ssl_creds = grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL); if (fail_server_auth_check(server_args)) { - grpc_auth_metadata_processor processor = {process_auth_failure, NULL}; + grpc_auth_metadata_processor processor = {process_auth_failure, NULL, NULL}; grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor); } chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_proxy.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_proxy.c index be0dda25a6..8133a69a0c 100644 --- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_proxy.c +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_proxy.c @@ -167,7 +167,7 @@ static void chttp2_init_server_simple_ssl_secure_fullstack( grpc_server_credentials *ssl_creds = grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL); if (fail_server_auth_check(server_args)) { - grpc_auth_metadata_processor processor = {process_auth_failure, NULL}; + grpc_auth_metadata_processor processor = {process_auth_failure, NULL, NULL}; grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor); } chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c index 9a545b1e3d..e61e276fff 100644 --- a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c @@ -67,13 +67,21 @@ static const grpc_metadata *find_metadata(const grpc_metadata *md, return NULL; } +typedef struct { + size_t pseudo_refcount; +} test_processor_state; + static void process_oauth2_success(void *state, grpc_auth_context *ctx, const grpc_metadata *md, size_t md_count, grpc_process_auth_metadata_done_cb cb, void *user_data) { const grpc_metadata *oauth2 = find_metadata(md, md_count, "Authorization", oauth2_md); - GPR_ASSERT(state == NULL); + test_processor_state *s; + + GPR_ASSERT(state != NULL); + s = (test_processor_state *)state; + GPR_ASSERT(s->pseudo_refcount == 1); GPR_ASSERT(oauth2 != NULL); grpc_auth_context_add_cstring_property(ctx, client_identity_property_name, client_identity); @@ -88,7 +96,10 @@ static void process_oauth2_failure(void *state, grpc_auth_context *ctx, void *user_data) { const grpc_metadata *oauth2 = find_metadata(md, md_count, "Authorization", oauth2_md); - GPR_ASSERT(state == NULL); + test_processor_state *s; + GPR_ASSERT(state != NULL); + s = (test_processor_state *)state; + GPR_ASSERT(s->pseudo_refcount == 1); GPR_ASSERT(oauth2 != NULL); cb(user_data, oauth2, 1, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL); } @@ -171,20 +182,34 @@ static int fail_server_auth_check(grpc_channel_args *server_args) { return 0; } +static void processor_destroy(void *state) { + test_processor_state *s = (test_processor_state *)state; + GPR_ASSERT((s->pseudo_refcount--) == 1); + gpr_free(s); +} + +static grpc_auth_metadata_processor test_processor_create(int failing) { + test_processor_state *s = gpr_malloc(sizeof(*s)); + grpc_auth_metadata_processor result; + s->pseudo_refcount = 1; + result.state = s; + result.destroy = processor_destroy; + if (failing) { + result.process = process_oauth2_failure; + } else { + result.process = process_oauth2_success; + } + return result; +} + static void chttp2_init_server_simple_ssl_secure_fullstack( grpc_end2end_test_fixture *f, grpc_channel_args *server_args) { grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {test_server1_key, test_server1_cert}; grpc_server_credentials *ssl_creds = grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1, 0, NULL); - grpc_auth_metadata_processor processor; - processor.state = NULL; - if (fail_server_auth_check(server_args)) { - processor.process = process_oauth2_failure; - } else { - processor.process = process_oauth2_success; - } - grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor); + grpc_server_credentials_set_auth_metadata_processor( + ssl_creds, test_processor_create(fail_server_auth_check(server_args))); chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); } diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 9826837c60..72188e4da5 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -79,14 +80,23 @@ void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request, } } -void CheckServerAuthContext(const ServerContext* context) { +void CheckServerAuthContext(const ServerContext* context, + const grpc::string& expected_client_identity) { std::shared_ptr auth_ctx = context->auth_context(); std::vector ssl = auth_ctx->FindPropertyValues("transport_security_type"); EXPECT_EQ(1u, ssl.size()); EXPECT_EQ("ssl", ToString(ssl[0])); - EXPECT_TRUE(auth_ctx->GetPeerIdentityPropertyName().empty()); - EXPECT_TRUE(auth_ctx->GetPeerIdentity().empty()); + if (expected_client_identity.length() == 0) { + EXPECT_TRUE(auth_ctx->GetPeerIdentityPropertyName().empty()); + EXPECT_TRUE(auth_ctx->GetPeerIdentity().empty()); + EXPECT_FALSE(auth_ctx->IsPeerAuthenticated()); + } else { + auto identity = auth_ctx->GetPeerIdentity(); + EXPECT_TRUE(auth_ctx->IsPeerAuthenticated()); + EXPECT_EQ(1u, identity.size()); + EXPECT_EQ(expected_client_identity, identity[0]); + } } bool CheckIsLocalhost(const grpc::string& addr) { @@ -98,6 +108,54 @@ bool CheckIsLocalhost(const grpc::string& addr) { addr.substr(0, kIpv6.size()) == kIpv6; } +class TestAuthMetadataProcessor : public AuthMetadataProcessor { + public: + static const char kGoodGuy[]; + + TestAuthMetadataProcessor(bool is_blocking) : is_blocking_(is_blocking) {} + + std::shared_ptr GetCompatibleClientCreds() { + return AccessTokenCredentials(kGoodGuy); + } + std::shared_ptr GetIncompatibleClientCreds() { + return AccessTokenCredentials("Mr Hyde"); + } + + // Interface implementation + bool IsBlocking() const GRPC_OVERRIDE { return is_blocking_; } + + Status Process(const InputMetadata& auth_metadata, AuthContext* context, + OutputMetadata* consumed_auth_metadata, + OutputMetadata* response_metadata) GRPC_OVERRIDE { + EXPECT_TRUE(consumed_auth_metadata != nullptr); + EXPECT_TRUE(context != nullptr); + EXPECT_TRUE(response_metadata != nullptr); + auto auth_md = auth_metadata.find(GRPC_AUTHORIZATION_METADATA_KEY); + EXPECT_NE(auth_md, auth_metadata.end()); + string_ref auth_md_value = auth_md->second; + if (auth_md_value.ends_with("Dr Jekyll")) { + context->AddProperty(kIdentityPropName, kGoodGuy); + context->SetPeerIdentityPropertyName(kIdentityPropName); + consumed_auth_metadata->insert( + std::make_pair(string(auth_md->first.data(), auth_md->first.length()), + auth_md->second)); + return Status::OK; + } else { + return Status(StatusCode::UNAUTHENTICATED, + string("Invalid principal: ") + + string(auth_md_value.data(), auth_md_value.length())); + } + } + + protected: + static const char kIdentityPropName[]; + bool is_blocking_; +}; + +const char TestAuthMetadataProcessor::kGoodGuy[] = "Dr Jekyll"; +const char TestAuthMetadataProcessor::kIdentityPropName[] = "novel identity"; + + } // namespace class Proxy : public ::grpc::cpp::test::util::TestService::Service { @@ -162,8 +220,10 @@ class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service { ToString(iter->second)); } } - if (request->has_param() && request->param().check_auth_context()) { - CheckServerAuthContext(context); + if (request->has_param() && + (request->param().expected_client_identity().length() > 0 || + request->param().check_auth_context())) { + CheckServerAuthContext(context, request->param().expected_client_identity()); } if (request->has_param() && request->param().response_message_length() > 0) { @@ -259,9 +319,18 @@ class TestServiceImplDupPkg class End2endTest : public ::testing::TestWithParam { protected: End2endTest() - : kMaxMessageSize_(8192), special_service_("special") {} + : is_server_started_(false), + kMaxMessageSize_(8192), + special_service_("special") {} + + void TearDown() GRPC_OVERRIDE { + if (is_server_started_) { + server_->Shutdown(); + if (proxy_server_) proxy_server_->Shutdown(); + } + } - void SetUp() GRPC_OVERRIDE { + void StartServer(const std::shared_ptr& processor) { int port = grpc_pick_unused_port_or_die(); server_address_ << "127.0.0.1:" << port; // Setup server @@ -271,22 +340,23 @@ class End2endTest : public ::testing::TestWithParam { SslServerCredentialsOptions ssl_opts; ssl_opts.pem_root_certs = ""; ssl_opts.pem_key_cert_pairs.push_back(pkcp); - builder.AddListeningPort(server_address_.str(), - SslServerCredentials(ssl_opts)); + auto server_creds = SslServerCredentials(ssl_opts); + server_creds->SetAuthMetadataProcessor(processor); + builder.AddListeningPort(server_address_.str(), server_creds); builder.RegisterService(&service_); builder.RegisterService("foo.test.youtube.com", &special_service_); builder.SetMaxMessageSize( kMaxMessageSize_); // For testing max message size. builder.RegisterService(&dup_pkg_service_); server_ = builder.BuildAndStart(); - } - - void TearDown() GRPC_OVERRIDE { - server_->Shutdown(); - if (proxy_server_) proxy_server_->Shutdown(); + is_server_started_ = true; } void ResetChannel() { + if (!is_server_started_) { + StartServer(std::shared_ptr()); + } + EXPECT_TRUE(is_server_started_); SslCredentialsOptions ssl_opts = {test_root_cert, "", ""}; ChannelArguments args; args.SetSslTargetNameOverride("foo.test.google.fr"); @@ -314,6 +384,7 @@ class End2endTest : public ::testing::TestWithParam { stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel_)); } + bool is_server_started_; std::shared_ptr channel_; std::unique_ptr stub_; std::unique_ptr server_; @@ -806,6 +877,82 @@ TEST_F(End2endTest, OverridePerCallCredentials) { EXPECT_TRUE(s.ok()); } +TEST_F(End2endTest, NonBlockingAuthMetadataProcessorSuccess) { + auto* processor = new TestAuthMetadataProcessor(false); + StartServer(std::shared_ptr(processor)); + ResetStub(false); + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_credentials(processor->GetCompatibleClientCreds()); + request.set_message("Hello"); + request.mutable_param()->set_echo_metadata(true); + request.mutable_param()->set_expected_client_identity( + TestAuthMetadataProcessor::kGoodGuy); + + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(request.message(), response.message()); + EXPECT_TRUE(s.ok()); + + // Metadata should have been consumed by the processor. + EXPECT_FALSE(MetadataContains( + context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY, + grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy)); +} + +TEST_F(End2endTest, NonBlockingAuthMetadataProcessorFailure) { + auto* processor = new TestAuthMetadataProcessor(false); + StartServer(std::shared_ptr(processor)); + ResetStub(false); + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_credentials(processor->GetIncompatibleClientCreds()); + request.set_message("Hello"); + + Status s = stub_->Echo(&context, request, &response); + EXPECT_FALSE(s.ok()); + EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED); +} + +TEST_F(End2endTest, BlockingAuthMetadataProcessorSuccess) { + auto* processor = new TestAuthMetadataProcessor(true); + StartServer(std::shared_ptr(processor)); + ResetStub(false); + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_credentials(processor->GetCompatibleClientCreds()); + request.set_message("Hello"); + request.mutable_param()->set_echo_metadata(true); + request.mutable_param()->set_expected_client_identity( + TestAuthMetadataProcessor::kGoodGuy); + + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(request.message(), response.message()); + EXPECT_TRUE(s.ok()); + + // Metadata should have been consumed by the processor. + EXPECT_FALSE(MetadataContains( + context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY, + grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy)); +} + +TEST_F(End2endTest, BlockingAuthMetadataProcessorFailure) { + auto* processor = new TestAuthMetadataProcessor(true); + StartServer(std::shared_ptr(processor)); + ResetStub(false); + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_credentials(processor->GetIncompatibleClientCreds()); + request.set_message("Hello"); + + Status s = stub_->Echo(&context, request, &response); + EXPECT_FALSE(s.ok()); + EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED); +} + // Client sends 20 requests and the server returns CANCELLED status after // reading 10 requests. TEST_F(End2endTest, RequestStreamServerEarlyCancelTest) { diff --git a/test/cpp/util/messages.proto b/test/cpp/util/messages.proto index 359d1db74f..a022707be9 100644 --- a/test/cpp/util/messages.proto +++ b/test/cpp/util/messages.proto @@ -40,6 +40,7 @@ message RequestParams { bool check_auth_context = 5; int32 response_message_length = 6; bool echo_peer = 7; + string expected_client_identity = 8; // will force check_auth_context. } message EchoRequest { -- cgit v1.2.3 From 75d04da2e4d31753c9d8a8bb46a7260e3e44484b Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 28 Aug 2015 14:17:33 -0700 Subject: sync up with CreateChannel API change --- examples/cpp/helloworld/greeter_async_client.cc | 2 +- examples/cpp/helloworld/greeter_client.cc | 3 +-- examples/cpp/route_guide/route_guide_client.cc | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/cpp/helloworld/greeter_async_client.cc b/examples/cpp/helloworld/greeter_async_client.cc index d99f89b135..bc95c54e06 100644 --- a/examples/cpp/helloworld/greeter_async_client.cc +++ b/examples/cpp/helloworld/greeter_async_client.cc @@ -89,7 +89,7 @@ class GreeterClient { int main(int argc, char** argv) { GreeterClient greeter(grpc::CreateChannel( - "localhost:50051", grpc::InsecureCredentials(), ChannelArguments())); + "localhost:50051", grpc::InsecureCredentials())); std::string user("world"); std::string reply = greeter.SayHello(user); std::cout << "Greeter received: " << reply << std::endl; diff --git a/examples/cpp/helloworld/greeter_client.cc b/examples/cpp/helloworld/greeter_client.cc index dd0358ac95..2b542cd834 100644 --- a/examples/cpp/helloworld/greeter_client.cc +++ b/examples/cpp/helloworld/greeter_client.cc @@ -75,8 +75,7 @@ class GreeterClient { int main(int argc, char** argv) { GreeterClient greeter( - grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), - ChannelArguments())); + grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials())); std::string user("world"); std::string reply = greeter.SayHello(user); std::cout << "Greeter received: " << reply << std::endl; diff --git a/examples/cpp/route_guide/route_guide_client.cc b/examples/cpp/route_guide/route_guide_client.cc index 814def27f3..fe998079c4 100644 --- a/examples/cpp/route_guide/route_guide_client.cc +++ b/examples/cpp/route_guide/route_guide_client.cc @@ -235,8 +235,7 @@ int main(int argc, char** argv) { // Expect only arg: --db_path=path/to/route_guide_db.json. std::string db = examples::GetDbFileContent(argc, argv); RouteGuideClient guide( - grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), - ChannelArguments()), + grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials()), db); std::cout << "-------------- GetFeature --------------" << std::endl; -- cgit v1.2.3 From b00a3f689fef00f029589f52b3dda2272deb7914 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 28 Aug 2015 14:19:37 -0700 Subject: fix links in docs --- examples/cpp/README.md | 11 +++++------ examples/cpp/cpptutorial.md | 12 ++++++------ examples/cpp/helloworld/README.md | 12 ++++++------ 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/examples/cpp/README.md b/examples/cpp/README.md index 70418b4425..85c495099b 100644 --- a/examples/cpp/README.md +++ b/examples/cpp/README.md @@ -2,12 +2,11 @@ ## Installation -To install gRPC on your system, follow the instructions here: -[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). +To install gRPC on your system, follow the instructions [here](../../INSTALL). ## Hello C++ gRPC! -Here's how to build and run the C++ implementation of the [Hello World](examples/protos/helloworld.proto) example used in [Getting started](https://github.com/grpc/grpc/tree/master/examples). +Here's how to build and run the C++ implementation of the [Hello World](../protos/helloworld.proto) example used in [Getting started](..). The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the @@ -41,9 +40,9 @@ $ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto ### Client and server implementations -The client implementation is at [greeter_client.cc](examples/cpp/helloworld/greeter_client.cc). +The client implementation is at [greeter_client.cc](helloworld/greeter_client.cc). -The server implementation is at [greeter_server.cc](examples/cpp/helloworld/greeter_server.cc). +The server implementation is at [greeter_server.cc](helloworld/greeter_server.cc). ### Try it! Build client and server: @@ -62,4 +61,4 @@ If things go smoothly, you will see the "Greeter received: Hello world" in the c ## Tutorial -You can find a more detailed tutorial in [gRPC Basics: C++](examples/cpp/cpptutorial.md) +You can find a more detailed tutorial in [gRPC Basics: C++](cpptutorial.md) diff --git a/examples/cpp/cpptutorial.md b/examples/cpp/cpptutorial.md index 22be42d500..a23633d83c 100644 --- a/examples/cpp/cpptutorial.md +++ b/examples/cpp/cpptutorial.md @@ -6,7 +6,7 @@ This tutorial provides a basic C++ programmer's introduction to working with gRP - Generate server and client code using the protocol buffer compiler. - Use the C++ gRPC API to write a simple client and server for your service. -It assumes that you have read the [Getting started](https://github.com/grpc/grpc/tree/master/examples) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. +It assumes that you have read the [Getting started](..) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. This isn't a comprehensive guide to using gRPC in C++: more reference documentation is coming soon. @@ -18,7 +18,7 @@ With gRPC we can define our service once in a .proto file and implement clients ## Example code and setup -The example code for our tutorial is in [examples/cpp/route_guide](examples/cpp/route_guide). To download the example, clone this repository by running the following command: +The example code for our tutorial is in [examples/cpp/route_guide](route_guide). To download the example, clone this repository by running the following command: ```shell $ git clone https://github.com/grpc/grpc.git ``` @@ -33,7 +33,7 @@ You also should have the relevant tools installed to generate the server and cli ## Defining the service -Our first step (as you'll know from [Getting started](examples/) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`examples/protos/route_guide.proto`](examples/protos/route_guide.proto). +Our first step (as you'll know from [Getting started](..) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`examples/protos/route_guide.proto`](../protos/route_guide.proto). To define a service, you specify a named `service` in your .proto file: @@ -91,7 +91,7 @@ message Point { Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. -For simplicity, we've provided a [makefile](examples/cpp/route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first): +For simplicity, we've provided a [makefile](route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](../../INSTALL) first): ```shell $ make route_guide.grpc.pb.cc route_guide.pb.cc @@ -126,7 +126,7 @@ There are two parts to making our `RouteGuide` service do its job: - Implementing the service interface generated from our service definition: doing the actual "work" of our service. - Running a gRPC server to listen for requests from clients and return the service responses. -You can find our example `RouteGuide` server in [examples/cpp/route_guide/route_guide_server.cc](examples/cpp/route_guide/route_guide_server.cc). Let's take a closer look at how it works. +You can find our example `RouteGuide` server in [route_guide/route_guide_server.cc](route_guide/route_guide_server.cc). Let's take a closer look at how it works. ### Implementing RouteGuide @@ -236,7 +236,7 @@ As you can see, we build and start our server using a `ServerBuilder`. To do thi ## Creating the client -In this section, we'll look at creating a C++ client for our `RouteGuide` service. You can see our complete example client code in [examples/cpp/route_guide/route_guide_client.cc](examples/cpp/route_guide/route_guide_client.cc). +In this section, we'll look at creating a C++ client for our `RouteGuide` service. You can see our complete example client code in [route_guide/route_guide_client.cc](route_guide/route_guide_client.cc). ### Creating a stub diff --git a/examples/cpp/helloworld/README.md b/examples/cpp/helloworld/README.md index 641aadd52d..ac833e98eb 100644 --- a/examples/cpp/helloworld/README.md +++ b/examples/cpp/helloworld/README.md @@ -2,7 +2,7 @@ ### Install gRPC Make sure you have installed gRPC on your system. Follow the instructions here: -[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL). +[https://github.com/grpc/grpc/blob/master/INSTALL](../../../INSTALL). ### Get the tutorial source code @@ -34,7 +34,7 @@ types as protocol buffer message types. Both the client and the server use interface code generated from the service definition. Here's our example service definition, defined using protocol buffers IDL in -[helloworld.proto](examples/protos/helloworld.proto). The `Greeting` +[helloworld.proto](../../protos/helloworld.proto). The `Greeting` service has one method, `hello`, that lets the server receive a single `HelloRequest` message from the remote client containing the user's name, then send back @@ -124,7 +124,7 @@ $ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto } ``` -For a working example, refer to [greeter_client.cc](examples/cpp/helloworld/greeter_client.cc). +For a working example, refer to [greeter_client.cc](greeter_client.cc). ### Writing a server @@ -152,7 +152,7 @@ For a working example, refer to [greeter_client.cc](examples/cpp/helloworld/gree std::unique_ptr server(builder.BuildAndStart()); ``` -For a working example, refer to [greeter_server.cc](examples/cpp/helloworld/greeter_server.cc). +For a working example, refer to [greeter_server.cc](greeter_server.cc). ### Writing asynchronous client and server @@ -194,7 +194,7 @@ The channel and stub creation code is the same as the sync client. } ``` -For a working example, refer to [greeter_async_client.cc](examples/cpp/helloworld/greeter_async_client.cc). +For a working example, refer to [greeter_async_client.cc](greeter_async_client.cc). #### Async server @@ -253,7 +253,7 @@ maintain the state of each rpc and use the address of it as the unique tag. For simplicity the server only uses one completion queue for all events, and runs a main loop in `HandleRpcs` to query the queue. -For a working example, refer to [greeter_async_server.cc](examples/cpp/helloworld/greeter_async_server.cc). +For a working example, refer to [greeter_async_server.cc](greeter_async_server.cc). -- cgit v1.2.3 From 68ff03a952d1b5395ef1f4ee326f810cd0b55912 Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Fri, 28 Aug 2015 14:21:24 -0700 Subject: Fixing AuthContext tests. --- test/cpp/common/secure_auth_context_test.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/cpp/common/secure_auth_context_test.cc b/test/cpp/common/secure_auth_context_test.cc index 4ab7fcacdf..e1f2c5e968 100644 --- a/test/cpp/common/secure_auth_context_test.cc +++ b/test/cpp/common/secure_auth_context_test.cc @@ -50,7 +50,7 @@ class SecureAuthContextTest : public ::testing::Test {}; // Created with nullptr TEST_F(SecureAuthContextTest, EmptyContext) { - SecureAuthContext context(nullptr); + SecureAuthContext context(nullptr, true); EXPECT_TRUE(context.GetPeerIdentity().empty()); EXPECT_TRUE(context.GetPeerIdentityPropertyName().empty()); EXPECT_TRUE(context.FindPropertyValues("").empty()); @@ -60,7 +60,7 @@ TEST_F(SecureAuthContextTest, EmptyContext) { TEST_F(SecureAuthContextTest, Properties) { grpc_auth_context* ctx = grpc_auth_context_create(NULL); - SecureAuthContext context(ctx); + SecureAuthContext context(ctx, true); context.AddProperty("name", "chapi"); context.AddProperty("name", "chapo"); context.AddProperty("foo", "bar"); @@ -78,7 +78,7 @@ TEST_F(SecureAuthContextTest, Properties) { TEST_F(SecureAuthContextTest, Iterators) { grpc_auth_context* ctx = grpc_auth_context_create(NULL); - SecureAuthContext context(ctx); + SecureAuthContext context(ctx, true); context.AddProperty("name", "chapi"); context.AddProperty("name", "chapo"); context.AddProperty("foo", "bar"); -- cgit v1.2.3 From 92806a51ba419428c0e4a126e916860b0225c492 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 28 Aug 2015 14:24:44 -0700 Subject: remove ChannelArguments ref and update doc --- examples/cpp/cpptutorial.md | 4 ++-- examples/cpp/helloworld/README.md | 2 +- examples/cpp/helloworld/greeter_async_client.cc | 1 - examples/cpp/helloworld/greeter_client.cc | 1 - examples/cpp/route_guide/route_guide_client.cc | 1 - 5 files changed, 3 insertions(+), 6 deletions(-) diff --git a/examples/cpp/cpptutorial.md b/examples/cpp/cpptutorial.md index a23633d83c..c06233aa6b 100644 --- a/examples/cpp/cpptutorial.md +++ b/examples/cpp/cpptutorial.md @@ -242,10 +242,10 @@ In this section, we'll look at creating a C++ client for our `RouteGuide` servic To call service methods, we first need to create a *stub*. -First we need to create a gRPC *channel* for our stub, specifying the server address and port we want to connect to and any special channel arguments - in our case we'll use the default `ChannelArguments` and no SSL: +First we need to create a gRPC *channel* for our stub, specifying the server address and port we want to connect to without SSL: ```cpp -grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), ChannelArguments()); +grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials()); ``` Now we can use the channel to create our stub using the `NewStub` method provided in the `RouteGuide` class we generated from our .proto. diff --git a/examples/cpp/helloworld/README.md b/examples/cpp/helloworld/README.md index ac833e98eb..b16c084583 100644 --- a/examples/cpp/helloworld/README.md +++ b/examples/cpp/helloworld/README.md @@ -94,7 +94,7 @@ $ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto arguments as follows ``` - auto channel = CreateChannel("localhost:50051", InsecureCredentials(), ChannelArguments()); + auto channel = CreateChannel("localhost:50051", InsecureCredentials()); ``` - Create a stub. A stub implements the rpc methods of a service and in the diff --git a/examples/cpp/helloworld/greeter_async_client.cc b/examples/cpp/helloworld/greeter_async_client.cc index bc95c54e06..875599e161 100644 --- a/examples/cpp/helloworld/greeter_async_client.cc +++ b/examples/cpp/helloworld/greeter_async_client.cc @@ -45,7 +45,6 @@ #include "helloworld.grpc.pb.h" using grpc::Channel; -using grpc::ChannelArguments; using grpc::ClientAsyncResponseReader; using grpc::ClientContext; using grpc::CompletionQueue; diff --git a/examples/cpp/helloworld/greeter_client.cc b/examples/cpp/helloworld/greeter_client.cc index 2b542cd834..3d2fcba610 100644 --- a/examples/cpp/helloworld/greeter_client.cc +++ b/examples/cpp/helloworld/greeter_client.cc @@ -43,7 +43,6 @@ #include "helloworld.grpc.pb.h" using grpc::Channel; -using grpc::ChannelArguments; using grpc::ClientContext; using grpc::Status; using helloworld::HelloRequest; diff --git a/examples/cpp/route_guide/route_guide_client.cc b/examples/cpp/route_guide/route_guide_client.cc index fe998079c4..ec0a75e039 100644 --- a/examples/cpp/route_guide/route_guide_client.cc +++ b/examples/cpp/route_guide/route_guide_client.cc @@ -47,7 +47,6 @@ #include "route_guide.grpc.pb.h" using grpc::Channel; -using grpc::ChannelArguments; using grpc::ClientContext; using grpc::ClientReader; using grpc::ClientReaderWriter; -- cgit v1.2.3 From bcebb5d230611f530ae8daaeb172bc896d0ec39b Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 28 Aug 2015 14:29:53 -0700 Subject: fix link --- examples/cpp/cpptutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cpp/cpptutorial.md b/examples/cpp/cpptutorial.md index c06233aa6b..78de014f97 100644 --- a/examples/cpp/cpptutorial.md +++ b/examples/cpp/cpptutorial.md @@ -28,7 +28,7 @@ Then change your current directory to `examples/cpp/route_guide`: $ cd examples/cpp/route_guide ``` -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [the C++ quick start guide](examples/cpp). +You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [gRPC in 3 minutes](README.md). ## Defining the service -- cgit v1.2.3 From 3c99f09ef321e3b876ea843a3689dda33b89e104 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 28 Aug 2015 14:32:36 -0700 Subject: regenerate C# docs --- doc/ref/csharp/html/WebKI.xml | 16 +- doc/ref/csharp/html/WebTOC.xml | 270 ++++++++++----------- doc/ref/csharp/html/fti/FTI_100.json | 2 +- doc/ref/csharp/html/fti/FTI_102.json | 2 +- doc/ref/csharp/html/fti/FTI_103.json | 2 +- doc/ref/csharp/html/fti/FTI_104.json | 2 +- doc/ref/csharp/html/fti/FTI_105.json | 2 +- doc/ref/csharp/html/fti/FTI_109.json | 2 +- doc/ref/csharp/html/fti/FTI_111.json | 2 +- doc/ref/csharp/html/fti/FTI_112.json | 2 +- doc/ref/csharp/html/fti/FTI_113.json | 2 +- doc/ref/csharp/html/fti/FTI_114.json | 2 +- doc/ref/csharp/html/fti/FTI_115.json | 2 +- doc/ref/csharp/html/fti/FTI_116.json | 2 +- doc/ref/csharp/html/fti/FTI_118.json | 2 +- doc/ref/csharp/html/fti/FTI_97.json | 2 +- doc/ref/csharp/html/fti/FTI_99.json | 2 +- doc/ref/csharp/html/fti/FTI_Files.json | 2 +- .../html/F_Grpc_Core_ChannelOptions_Census.htm | 2 +- ...F_Grpc_Core_ChannelOptions_DefaultAuthority.htm | 2 +- ...e_ChannelOptions_Http2InitialSequenceNumber.htm | 2 +- ...pc_Core_ChannelOptions_MaxConcurrentStreams.htm | 2 +- ...F_Grpc_Core_ChannelOptions_MaxMessageLength.htm | 2 +- ..._Core_ChannelOptions_PrimaryUserAgentString.htm | 2 +- ...ore_ChannelOptions_SecondaryUserAgentString.htm | 2 +- ...c_Core_ChannelOptions_SslTargetNameOverride.htm | 2 +- ...Grpc_Core_ContextPropagationOptions_Default.htm | 2 +- .../F_Grpc_Core_Metadata_BinaryHeaderSuffix.htm | 2 +- .../html/html/F_Grpc_Core_Metadata_Empty.htm | 2 +- .../html/F_Grpc_Core_ServerPort_PickUnused.htm | 2 +- .../html/F_Grpc_Core_Status_DefaultCancelled.htm | 2 +- .../html/F_Grpc_Core_Status_DefaultSuccess.htm | 2 +- .../F_Grpc_Core_VersionInfo_CurrentVersion.htm | 6 +- .../html/html/F_Grpc_Core_WriteOptions_Default.htm | 2 +- .../html/html/Fields_T_Grpc_Core_VersionInfo.htm | 2 +- ..._Grpc_Auth_AuthInterceptors_FromAccessToken.htm | 2 +- ...M_Grpc_Auth_AuthInterceptors_FromCredential.htm | 2 +- ...rpc_Core_AsyncClientStreamingCall_2_Dispose.htm | 2 +- ..._Core_AsyncClientStreamingCall_2_GetAwaiter.htm | 2 +- ...c_Core_AsyncClientStreamingCall_2_GetStatus.htm | 2 +- ...Core_AsyncClientStreamingCall_2_GetTrailers.htm | 2 +- ...rpc_Core_AsyncDuplexStreamingCall_2_Dispose.htm | 2 +- ...c_Core_AsyncDuplexStreamingCall_2_GetStatus.htm | 2 +- ...Core_AsyncDuplexStreamingCall_2_GetTrailers.htm | 2 +- ...rpc_Core_AsyncServerStreamingCall_1_Dispose.htm | 2 +- ...c_Core_AsyncServerStreamingCall_1_GetStatus.htm | 2 +- ...Core_AsyncServerStreamingCall_1_GetTrailers.htm | 2 +- .../html/M_Grpc_Core_AsyncUnaryCall_1_Dispose.htm | 2 +- .../M_Grpc_Core_AsyncUnaryCall_1_GetAwaiter.htm | 2 +- .../M_Grpc_Core_AsyncUnaryCall_1_GetStatus.htm | 2 +- .../M_Grpc_Core_AsyncUnaryCall_1_GetTrailers.htm | 2 +- ...pc_Core_CallInvocationDetails_2_WithOptions.htm | 2 +- .../M_Grpc_Core_CallInvocationDetails_2__ctor.htm | 2 +- ...M_Grpc_Core_CallInvocationDetails_2__ctor_1.htm | 2 +- ...M_Grpc_Core_CallInvocationDetails_2__ctor_2.htm | 6 +- ...Grpc_Core_CallOptions_WithCancellationToken.htm | 2 +- .../html/M_Grpc_Core_CallOptions_WithDeadline.htm | 2 +- .../html/M_Grpc_Core_CallOptions_WithHeaders.htm | 2 +- .../html/html/M_Grpc_Core_CallOptions__ctor.htm | 2 +- ...Grpc_Core_Calls_AsyncClientStreamingCall__2.htm | 2 +- ...Grpc_Core_Calls_AsyncDuplexStreamingCall__2.htm | 2 +- ...Grpc_Core_Calls_AsyncServerStreamingCall__2.htm | 2 +- .../html/M_Grpc_Core_Calls_AsyncUnaryCall__2.htm | 2 +- .../M_Grpc_Core_Calls_BlockingUnaryCall__2.htm | 2 +- .../html/html/M_Grpc_Core_ChannelOption__ctor.htm | 2 +- .../html/M_Grpc_Core_ChannelOption__ctor_1.htm | 2 +- .../html/html/M_Grpc_Core_Channel_ConnectAsync.htm | 2 +- .../html/M_Grpc_Core_Channel_ShutdownAsync.htm | 2 +- ..._Grpc_Core_Channel_WaitForStateChangedAsync.htm | 2 +- .../csharp/html/html/M_Grpc_Core_Channel__ctor.htm | 2 +- .../html/html/M_Grpc_Core_Channel__ctor_1.htm | 2 +- .../html/M_Grpc_Core_ClientBase_CreateCall__2.htm | 2 +- .../html/html/M_Grpc_Core_ClientBase__ctor.htm | 2 +- ...M_Grpc_Core_ContextPropagationOptions__ctor.htm | 2 +- .../html/html/M_Grpc_Core_Credentials__ctor.htm | 2 +- .../html/M_Grpc_Core_GrpcEnvironment_SetLogger.htm | 2 +- ...M_Grpc_Core_IAsyncStreamWriter_1_WriteAsync.htm | 2 +- ...pc_Core_IClientStreamWriter_1_CompleteAsync.htm | 2 +- .../html/M_Grpc_Core_KeyCertificatePair__ctor.htm | 2 +- .../M_Grpc_Core_Logging_ConsoleLogger_Debug.htm | 2 +- .../M_Grpc_Core_Logging_ConsoleLogger_Error.htm | 2 +- .../M_Grpc_Core_Logging_ConsoleLogger_Error_1.htm | 2 +- ..._Grpc_Core_Logging_ConsoleLogger_ForType__1.htm | 2 +- .../M_Grpc_Core_Logging_ConsoleLogger_Info.htm | 2 +- .../M_Grpc_Core_Logging_ConsoleLogger_Warning.htm | 2 +- ...M_Grpc_Core_Logging_ConsoleLogger_Warning_1.htm | 2 +- .../M_Grpc_Core_Logging_ConsoleLogger__ctor.htm | 2 +- .../html/M_Grpc_Core_Logging_ILogger_Debug.htm | 2 +- .../html/M_Grpc_Core_Logging_ILogger_Error.htm | 2 +- .../html/M_Grpc_Core_Logging_ILogger_Error_1.htm | 2 +- .../M_Grpc_Core_Logging_ILogger_ForType__1.htm | 2 +- .../html/html/M_Grpc_Core_Logging_ILogger_Info.htm | 2 +- .../html/M_Grpc_Core_Logging_ILogger_Warning.htm | 2 +- .../html/M_Grpc_Core_Logging_ILogger_Warning_1.htm | 2 +- .../html/html/M_Grpc_Core_Marshaller_1__ctor.htm | 6 +- .../html/M_Grpc_Core_Marshallers_Create__1.htm | 4 +- .../csharp/html/html/M_Grpc_Core_Metadata_Add.htm | 2 +- .../html/html/M_Grpc_Core_Metadata_Add_1.htm | 2 +- .../html/html/M_Grpc_Core_Metadata_Add_2.htm | 2 +- .../html/html/M_Grpc_Core_Metadata_Clear.htm | 2 +- .../html/html/M_Grpc_Core_Metadata_Contains.htm | 2 +- .../html/html/M_Grpc_Core_Metadata_CopyTo.htm | 2 +- .../html/M_Grpc_Core_Metadata_Entry_ToString.htm | 2 +- .../html/html/M_Grpc_Core_Metadata_Entry__ctor.htm | 2 +- .../html/M_Grpc_Core_Metadata_Entry__ctor_1.htm | 2 +- .../html/M_Grpc_Core_Metadata_GetEnumerator.htm | 2 +- .../html/html/M_Grpc_Core_Metadata_IndexOf.htm | 2 +- .../html/html/M_Grpc_Core_Metadata_Insert.htm | 2 +- .../html/html/M_Grpc_Core_Metadata_Remove.htm | 2 +- .../html/html/M_Grpc_Core_Metadata_RemoveAt.htm | 2 +- .../html/html/M_Grpc_Core_Metadata__ctor.htm | 2 +- .../html/html/M_Grpc_Core_Method_2__ctor.htm | 6 +- .../html/html/M_Grpc_Core_RpcException__ctor.htm | 2 +- .../html/html/M_Grpc_Core_RpcException__ctor_1.htm | 2 +- ...re_ServerCallContext_CreatePropagationToken.htm | 2 +- ...ServerCallContext_WriteResponseHeadersAsync.htm | 2 +- .../html/M_Grpc_Core_ServerCredentials__ctor.htm | 2 +- .../html/html/M_Grpc_Core_ServerPort__ctor.htm | 2 +- ...erverServiceDefinition_Builder_AddMethod__2.htm | 2 +- ...verServiceDefinition_Builder_AddMethod__2_1.htm | 2 +- ...verServiceDefinition_Builder_AddMethod__2_2.htm | 2 +- ...verServiceDefinition_Builder_AddMethod__2_3.htm | 2 +- ..._Core_ServerServiceDefinition_Builder_Build.htm | 2 +- ..._Core_ServerServiceDefinition_Builder__ctor.htm | 2 +- ..._Core_ServerServiceDefinition_CreateBuilder.htm | 2 +- .../html/html/M_Grpc_Core_Server_KillAsync.htm | 2 +- ...M_Grpc_Core_Server_ServerPortCollection_Add.htm | 2 +- ...Grpc_Core_Server_ServerPortCollection_Add_1.htm | 2 +- ...e_Server_ServerPortCollection_GetEnumerator.htm | 2 +- ...Core_Server_ServiceDefinitionCollection_Add.htm | 2 +- ...r_ServiceDefinitionCollection_GetEnumerator.htm | 2 +- .../html/html/M_Grpc_Core_Server_ShutdownAsync.htm | 2 +- .../csharp/html/html/M_Grpc_Core_Server_Start.htm | 2 +- .../csharp/html/html/M_Grpc_Core_Server__ctor.htm | 2 +- .../html/html/M_Grpc_Core_SslCredentials__ctor.htm | 2 +- .../html/M_Grpc_Core_SslCredentials__ctor_1.htm | 2 +- .../html/M_Grpc_Core_SslCredentials__ctor_2.htm | 2 +- .../M_Grpc_Core_SslServerCredentials__ctor.htm | 2 +- .../M_Grpc_Core_SslServerCredentials__ctor_1.htm | 2 +- .../html/html/M_Grpc_Core_Status_ToString.htm | 2 +- .../csharp/html/html/M_Grpc_Core_Status__ctor.htm | 2 +- ...Utils_AsyncStreamExtensions_ForEachAsync__1.htm | 2 +- ..._Utils_AsyncStreamExtensions_ToListAsync__1.htm | 2 +- ...tils_AsyncStreamExtensions_WriteAllAsync__1.htm | 2 +- ...ls_AsyncStreamExtensions_WriteAllAsync__1_1.htm | 2 +- ..._Grpc_Core_Utils_BenchmarkUtil_RunBenchmark.htm | 2 +- ...Grpc_Core_Utils_Preconditions_CheckArgument.htm | 2 +- ...pc_Core_Utils_Preconditions_CheckArgument_1.htm | 2 +- ...pc_Core_Utils_Preconditions_CheckNotNull__1.htm | 2 +- ..._Core_Utils_Preconditions_CheckNotNull__1_1.htm | 2 +- .../M_Grpc_Core_Utils_Preconditions_CheckState.htm | 2 +- ..._Grpc_Core_Utils_Preconditions_CheckState_1.htm | 2 +- .../html/html/M_Grpc_Core_WriteOptions__ctor.htm | 2 +- .../html/html/Methods_T_Grpc_Core_Marshaller_1.htm | 4 +- doc/ref/csharp/html/html/N_Grpc_Core.htm | 16 +- ...re_AsyncClientStreamingCall_2_RequestStream.htm | 2 +- ...re_AsyncClientStreamingCall_2_ResponseAsync.htm | 2 +- ...cClientStreamingCall_2_ResponseHeadersAsync.htm | 2 +- ...re_AsyncDuplexStreamingCall_2_RequestStream.htm | 2 +- ...cDuplexStreamingCall_2_ResponseHeadersAsync.htm | 2 +- ...e_AsyncDuplexStreamingCall_2_ResponseStream.htm | 2 +- ...cServerStreamingCall_1_ResponseHeadersAsync.htm | 2 +- ...e_AsyncServerStreamingCall_1_ResponseStream.htm | 2 +- .../P_Grpc_Core_AsyncUnaryCall_1_ResponseAsync.htm | 2 +- ..._Core_AsyncUnaryCall_1_ResponseHeadersAsync.htm | 2 +- ...P_Grpc_Core_CallInvocationDetails_2_Channel.htm | 2 +- .../P_Grpc_Core_CallInvocationDetails_2_Host.htm | 2 +- .../P_Grpc_Core_CallInvocationDetails_2_Method.htm | 2 +- ...P_Grpc_Core_CallInvocationDetails_2_Options.htm | 2 +- ...e_CallInvocationDetails_2_RequestMarshaller.htm | 6 +- ..._CallInvocationDetails_2_ResponseMarshaller.htm | 6 +- .../P_Grpc_Core_CallOptions_CancellationToken.htm | 2 +- .../html/html/P_Grpc_Core_CallOptions_Deadline.htm | 2 +- .../html/html/P_Grpc_Core_CallOptions_Headers.htm | 2 +- .../P_Grpc_Core_CallOptions_PropagationToken.htm | 2 +- .../html/P_Grpc_Core_CallOptions_WriteOptions.htm | 2 +- .../html/P_Grpc_Core_ChannelOption_IntValue.htm | 2 +- .../html/html/P_Grpc_Core_ChannelOption_Name.htm | 2 +- .../html/P_Grpc_Core_ChannelOption_StringValue.htm | 2 +- .../html/html/P_Grpc_Core_ChannelOption_Type.htm | 2 +- .../html/P_Grpc_Core_Channel_ResolvedTarget.htm | 2 +- .../csharp/html/html/P_Grpc_Core_Channel_State.htm | 2 +- .../html/html/P_Grpc_Core_Channel_Target.htm | 2 +- .../html/html/P_Grpc_Core_ClientBase_Channel.htm | 2 +- .../P_Grpc_Core_ClientBase_HeaderInterceptor.htm | 2 +- .../html/html/P_Grpc_Core_ClientBase_Host.htm | 2 +- ...tPropagationOptions_IsPropagateCancellation.htm | 2 +- ...ntextPropagationOptions_IsPropagateDeadline.htm | 2 +- .../html/html/P_Grpc_Core_Credentials_Insecure.htm | 2 +- .../html/P_Grpc_Core_GrpcEnvironment_Logger.htm | 2 +- ...Grpc_Core_IAsyncStreamWriter_1_WriteOptions.htm | 2 +- .../P_Grpc_Core_IHasWriteOptions_WriteOptions.htm | 2 +- .../html/html/P_Grpc_Core_IMethod_FullName.htm | 2 +- .../csharp/html/html/P_Grpc_Core_IMethod_Name.htm | 2 +- .../html/html/P_Grpc_Core_IMethod_ServiceName.htm | 2 +- .../csharp/html/html/P_Grpc_Core_IMethod_Type.htm | 2 +- ...pc_Core_KeyCertificatePair_CertificateChain.htm | 2 +- .../P_Grpc_Core_KeyCertificatePair_PrivateKey.htm | 2 +- .../html/P_Grpc_Core_Marshaller_1_Deserializer.htm | 6 +- .../html/P_Grpc_Core_Marshaller_1_Serializer.htm | 6 +- .../P_Grpc_Core_Marshallers_StringMarshaller.htm | 6 +- .../html/html/P_Grpc_Core_Metadata_Count.htm | 2 +- .../html/P_Grpc_Core_Metadata_Entry_IsBinary.htm | 2 +- .../html/html/P_Grpc_Core_Metadata_Entry_Key.htm | 2 +- .../html/html/P_Grpc_Core_Metadata_Entry_Value.htm | 2 +- .../html/P_Grpc_Core_Metadata_Entry_ValueBytes.htm | 2 +- .../html/html/P_Grpc_Core_Metadata_IsReadOnly.htm | 2 +- .../csharp/html/html/P_Grpc_Core_Metadata_Item.htm | 2 +- .../html/html/P_Grpc_Core_Method_2_FullName.htm | 2 +- .../csharp/html/html/P_Grpc_Core_Method_2_Name.htm | 2 +- .../P_Grpc_Core_Method_2_RequestMarshaller.htm | 6 +- .../P_Grpc_Core_Method_2_ResponseMarshaller.htm | 6 +- .../html/html/P_Grpc_Core_Method_2_ServiceName.htm | 2 +- .../csharp/html/html/P_Grpc_Core_Method_2_Type.htm | 2 +- .../html/html/P_Grpc_Core_RpcException_Status.htm | 2 +- ...pc_Core_ServerCallContext_CancellationToken.htm | 2 +- .../P_Grpc_Core_ServerCallContext_Deadline.htm | 2 +- .../html/P_Grpc_Core_ServerCallContext_Host.htm | 2 +- .../html/P_Grpc_Core_ServerCallContext_Method.htm | 2 +- .../html/P_Grpc_Core_ServerCallContext_Peer.htm | 2 +- ..._Grpc_Core_ServerCallContext_RequestHeaders.htm | 2 +- ...rpc_Core_ServerCallContext_ResponseTrailers.htm | 2 +- .../html/P_Grpc_Core_ServerCallContext_Status.htm | 2 +- .../P_Grpc_Core_ServerCallContext_WriteOptions.htm | 2 +- .../P_Grpc_Core_ServerCredentials_Insecure.htm | 2 +- .../html/html/P_Grpc_Core_ServerPort_BoundPort.htm | 2 +- .../html/P_Grpc_Core_ServerPort_Credentials.htm | 2 +- .../html/html/P_Grpc_Core_ServerPort_Host.htm | 2 +- .../html/html/P_Grpc_Core_ServerPort_Port.htm | 2 +- .../csharp/html/html/P_Grpc_Core_Server_Ports.htm | 2 +- .../html/html/P_Grpc_Core_Server_Services.htm | 2 +- .../html/html/P_Grpc_Core_Server_ShutdownTask.htm | 2 +- ...Grpc_Core_SslCredentials_KeyCertificatePair.htm | 2 +- ...P_Grpc_Core_SslCredentials_RootCertificates.htm | 2 +- ...ServerCredentials_ForceClientAuthentication.htm | 2 +- ...re_SslServerCredentials_KeyCertificatePairs.htm | 2 +- ..._Core_SslServerCredentials_RootCertificates.htm | 2 +- .../csharp/html/html/P_Grpc_Core_Status_Detail.htm | 2 +- .../html/html/P_Grpc_Core_Status_StatusCode.htm | 2 +- .../html/html/P_Grpc_Core_WriteOptions_Flags.htm | 2 +- .../html/Properties_T_Grpc_Core_Marshaller_1.htm | 4 +- .../html/html/T_Grpc_Auth_AuthInterceptors.htm | 2 +- .../T_Grpc_Core_AsyncClientStreamingCall_2.htm | 2 +- .../T_Grpc_Core_AsyncDuplexStreamingCall_2.htm | 2 +- .../T_Grpc_Core_AsyncServerStreamingCall_1.htm | 2 +- .../html/html/T_Grpc_Core_AsyncUnaryCall_1.htm | 2 +- .../html/T_Grpc_Core_CallInvocationDetails_2.htm | 2 +- .../csharp/html/html/T_Grpc_Core_CallOptions.htm | 2 +- doc/ref/csharp/html/html/T_Grpc_Core_Calls.htm | 2 +- doc/ref/csharp/html/html/T_Grpc_Core_Channel.htm | 2 +- .../csharp/html/html/T_Grpc_Core_ChannelOption.htm | 2 +- .../html/T_Grpc_Core_ChannelOption_OptionType.htm | 4 +- .../html/html/T_Grpc_Core_ChannelOptions.htm | 2 +- .../csharp/html/html/T_Grpc_Core_ChannelState.htm | 4 +- .../csharp/html/html/T_Grpc_Core_ClientBase.htm | 2 +- .../T_Grpc_Core_ClientStreamingServerMethod_2.htm | 4 +- .../html/html/T_Grpc_Core_CompressionLevel.htm | 4 +- .../html/T_Grpc_Core_ContextPropagationOptions.htm | 2 +- .../html/T_Grpc_Core_ContextPropagationToken.htm | 2 +- .../csharp/html/html/T_Grpc_Core_Credentials.htm | 2 +- .../T_Grpc_Core_DuplexStreamingServerMethod_2.htm | 4 +- .../html/html/T_Grpc_Core_GrpcEnvironment.htm | 2 +- .../html/html/T_Grpc_Core_HeaderInterceptor.htm | 4 +- .../html/html/T_Grpc_Core_IAsyncStreamReader_1.htm | 2 +- .../html/html/T_Grpc_Core_IAsyncStreamWriter_1.htm | 2 +- .../html/T_Grpc_Core_IClientStreamWriter_1.htm | 2 +- .../html/html/T_Grpc_Core_IHasWriteOptions.htm | 2 +- doc/ref/csharp/html/html/T_Grpc_Core_IMethod.htm | 2 +- .../html/T_Grpc_Core_IServerStreamWriter_1.htm | 2 +- .../html/html/T_Grpc_Core_KeyCertificatePair.htm | 2 +- .../html/T_Grpc_Core_Logging_ConsoleLogger.htm | 2 +- .../html/html/T_Grpc_Core_Logging_ILogger.htm | 2 +- .../csharp/html/html/T_Grpc_Core_Marshaller_1.htm | 17 +- .../csharp/html/html/T_Grpc_Core_Marshallers.htm | 2 +- doc/ref/csharp/html/html/T_Grpc_Core_Metadata.htm | 2 +- .../html/html/T_Grpc_Core_Metadata_Entry.htm | 2 +- .../csharp/html/html/T_Grpc_Core_MethodType.htm | 4 +- doc/ref/csharp/html/html/T_Grpc_Core_Method_2.htm | 2 +- .../csharp/html/html/T_Grpc_Core_RpcException.htm | 2 +- doc/ref/csharp/html/html/T_Grpc_Core_Server.htm | 2 +- .../html/html/T_Grpc_Core_ServerCallContext.htm | 2 +- .../html/html/T_Grpc_Core_ServerCredentials.htm | 2 +- .../csharp/html/html/T_Grpc_Core_ServerPort.htm | 2 +- .../html/T_Grpc_Core_ServerServiceDefinition.htm | 2 +- ...T_Grpc_Core_ServerServiceDefinition_Builder.htm | 2 +- .../T_Grpc_Core_ServerStreamingServerMethod_2.htm | 4 +- .../T_Grpc_Core_Server_ServerPortCollection.htm | 2 +- ...rpc_Core_Server_ServiceDefinitionCollection.htm | 2 +- .../html/html/T_Grpc_Core_SslCredentials.htm | 2 +- .../html/html/T_Grpc_Core_SslServerCredentials.htm | 2 +- doc/ref/csharp/html/html/T_Grpc_Core_Status.htm | 2 +- .../csharp/html/html/T_Grpc_Core_StatusCode.htm | 4 +- .../html/html/T_Grpc_Core_UnaryServerMethod_2.htm | 4 +- .../T_Grpc_Core_Utils_AsyncStreamExtensions.htm | 2 +- .../html/html/T_Grpc_Core_Utils_BenchmarkUtil.htm | 2 +- .../html/html/T_Grpc_Core_Utils_Preconditions.htm | 2 +- .../csharp/html/html/T_Grpc_Core_VersionInfo.htm | 4 +- .../csharp/html/html/T_Grpc_Core_WriteFlags.htm | 4 +- .../csharp/html/html/T_Grpc_Core_WriteOptions.htm | 2 +- doc/ref/csharp/html/toc/N_Grpc_Core.xml | 2 +- .../csharp/html/toc/T_Grpc_Core_Marshaller_1.xml | 2 +- 301 files changed, 493 insertions(+), 494 deletions(-) diff --git a/doc/ref/csharp/html/WebKI.xml b/doc/ref/csharp/html/WebKI.xml index 1318ed5f17..595105b5a6 100644 --- a/doc/ref/csharp/html/WebKI.xml +++ b/doc/ref/csharp/html/WebKI.xml @@ -454,8 +454,8 @@ - - + + @@ -621,9 +621,9 @@ - - - + + + @@ -631,9 +631,9 @@ - - - + + + diff --git a/doc/ref/csharp/html/WebTOC.xml b/doc/ref/csharp/html/WebTOC.xml index 63da550f44..85c1b8a266 100644 --- a/doc/ref/csharp/html/WebTOC.xml +++ b/doc/ref/csharp/html/WebTOC.xml @@ -1,71 +1,71 @@  - - - - + + + + - - - + + + - + - - + + - + - - + + - + - - + + - + - - + + - + @@ -73,27 +73,27 @@ - + - + - + - + - - + + @@ -101,28 +101,28 @@ - - + + - + - + - - + + - + @@ -131,8 +131,8 @@ - - + + @@ -144,118 +144,118 @@ - + - + - + - + - + - + - + - + - + - - + + - + - + - - + + - + - + - + - - + + - - + + - + - + - + - + - + - - + + - + - + - + - - + + @@ -269,29 +269,29 @@ - + - - + + - + - + - + - + @@ -302,47 +302,47 @@ - - + + - + - + - + - + - - - + + + - - + + - - + + @@ -353,40 +353,40 @@ - + - + - + - + - + - + - - + + - + - - + + @@ -396,123 +396,123 @@ - - + + - + - - + + - + - + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - - - + + + - + - - + + - - - + + + - + - + diff --git a/doc/ref/csharp/html/fti/FTI_100.json b/doc/ref/csharp/html/fti/FTI_100.json index e9e948d71c..9d216914b0 100644 --- a/doc/ref/csharp/html/fti/FTI_100.json +++ b/doc/ref/csharp/html/fti/FTI_100.json @@ -1 +1 @@ -{"default":[1,196609,262146,458754,589826,720897,1179654,1441793,1507329,1638406,1769473,1835009,1900545,1966081,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3276801,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4456449,5701633,6750209,12648449,14221314,14548993,14614529,14811137,17825794,18153473,19267586,21561345,21626881,21692417,21757953,22020098,22085633,22151169,22347779,22544387,22609921,22675457,22806529,23003137,23068673,23265281,23330817,23396353,23658497,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707074,25231363],"description":[131073,196609,262145,327681,393217,458753,524289,589825,1703937,1769473,1835009,1900545,1966081,2031617,2097153,2162689,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2686978,2752513,2818050,2883586,2949121,3014657,3080193,3145729,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4259841,4325377,4390913,4456449,12255233,12320774,12386306,12451841,12517377,12582913,12648449,12713985,12779521,12845057,12910593,12976129,13041665,13107201,13172737,13238273,13303809,13369345,13434881,13500417,13565953,13631489,13697025,13762561,13828097,13893633,13959169,14024705,14090241,14155777,14221313,14286849,14352385,14417921,14483457,14548993,14614529,14680065,14745601,14811137,14876673,14942209,15007745,15073281,15138817,15204353,15269889,15335425,15400961,15466497,15532033,15597569,15663105,15728641,15794177,21430273,21495809,21561346,21626882,21692418,21757954,21823491,21889027,21954561,22020099,22085635,22151169,22216705,22282241,22347779,22478849,22544388,22609921,22675459,22806530,22937603,23003138,23068675,23134209,23199745,23265283,23330819,23396354,23461889,23527426,23592963,23658500,23724035,23789569,23855108,23920644,23986179,24051714,24117251,24182788,24248321,24313858,24444929,24510465,24576003,24641539,24707076,24772609,24903681,24969217,25034753,25100289,25165825,25231364],"data":[131073,15269889,23920642,24772609],"defaultauthority":[196609,720901,22151169],"defaultcancelled":[458753,1441797,24707073],"details":[458754,1441793,1507329,6881281,12320769,21823489,24707074],"defaultsuccess":[458753,1507333,24707073],"dll":[655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572865,1638401,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6094849,6160385,6225921,6291457,6356993,6422529,6488065,6553601,6619137,6684673,6750209,6815745,6881281,6946817,7012353,7077889,7143425,7208961,7274497,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7864321,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388609,8454145,8519681,8585217,8650753,8716289,8781825,8847361,8912897,8978433,9043969,9109505,9175041,9240577,9306113,9371649,9437185,9502721,9568257,9633793,9699329,9764865,9830401,9895937,9961473,10027009,10092545,10158081,10223617,10289153,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11337729,11403265,11468801,11534337,11599873,11665409,11730945,11796481,11862017,11927553,11993089,12058625,12124161,12189697,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18153473,18219009,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19267585,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020097,22085633,22151169,22216705,22282241,22347777,22413313,22478849,22544385,22609921,22675457,22740993,22806529,22872065,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23789569,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24379393,24444929,24510465,24576001,24641537,24707073,24772609,24838145,24903681,24969217,25034753,25100289,25165825,25231361],"dispose":[1769473,1835009,1900545,1966081,2686977,4653063,4915207,5111815,5308423,21561345,21626881,21692417,21757953,22937601],"determines":[1769473,1835009,1900545,1966081,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3276801,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4456449,21561345,21626881,21692417,21757953,22020097,22085633,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23658497,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,25231361],"directly":[1769473,1966081,4718593,5373953,21561345,21757953],"deadline":[2097153,2228226,5898247,6029321,6553610,6684681,7012353,12320769,14024706,14286849,15400962,16973830,17956865,19857414,21889027,22020098,22544385,22609921,24051714,24772610],"duplex":[2162690,6160386,21954562],"different":[2228225,6684673,22020097],"defined":[2686979,2818049,2883585,15269889,22937603,23068673,23265281,23920641],"debug":[3014658,3080194,7405578,7929864,23396354,23461890],"deserializer":[3145729,8388615,8454149,15007746,18743302,23527425,23592962],"derived":[3473410,23920642],"definitions":[3866628,9961473,10027009,10092545,10158081,12320769,13172740,24313860,24510465],"duplexstreamingservermethod":[3866625,10027014,12320769,13172737,22740997,24313857],"definition":[3997697,6160385,10682369,12320770,15335426,20709377,20774913,21954561,23986178,24248321,24510465],"documentation":[5570561,6684674,7143425,7405570,7471107,7536642,7602177,7667714,7733251,7798786,7929858,7995395,8060930,8126465,8192002,8257539,8323074,8388611,8519682,8585219,8650755,8716289,8781826,8847363,9109505,9175042,9240579,9306114,9371650,9699329,10485761,10682369,11075585,11468803,11534338,11599876,11665411,11730947,11927553,11993089,18874369,19202049,19267585,20447233,20512769,20578305,20643841,23265281,23592961],"datetime":[5898245,6029317,6553605,6684679,16973830,19857414],"defaults":[6029313,6553601,6684673,6750209,6815745,7012353,9699329,10944513,11599873,12189697],"defaultarg":[6029317,6553601,6684673,6750209,6815745,7012354,9699329,10944513,11599873,12189697],"defintion":[6094849,6225921,6291457,6356993],"deserialize":[8454145],"disk":[11010050,13303810,24576002],"detail":[11403270,12320769,15728642,21233670,24707075],"defines":[12320769,22151169],"deserializing":[12320769,23592961],"delegates":[12320769],"delegate":[12320769,22413317,22740997,22872069,24379397,24838149],"destination":[12386305,21430273],"deserialized":[13959169,16842753,21823489],"dispatched":[14745601,15204353,18284545,19333121,23199745,23855105],"describes":[15269889,23920641],"duplexstreaming":[23789569],"differs":[24772609],"deadlineexceeded":[24772609],"delayed":[24772609],"directory":[24772612],"deleted":[24772609],"dataloss":[24772609],"disabled":[25165825]} \ No newline at end of file +{"default":[1,196609,262146,458754,589826,720897,1179654,1441793,1507329,1638406,1769473,1835009,1900545,1966081,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4456449,5701633,6750209,12648449,14221314,14548993,14614529,14811137,17825794,18153473,19267586,21561345,21626881,21692417,21757953,22020098,22085633,22151169,22347779,22544387,22609921,22675457,22806529,23003137,23068673,23265281,23330817,23396353,23592961,23658497,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707074,25231363],"description":[131073,196609,262145,327681,393217,458753,524289,589825,1703937,1769473,1835009,1900545,1966081,2031617,2097153,2162689,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2686978,2752513,2818050,2883586,2949121,3014657,3080193,3145729,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4259841,4325377,4390913,4456449,12255233,12320774,12386306,12451841,12517377,12582913,12648449,12713985,12779521,12845057,12910593,12976129,13041665,13107201,13172737,13238273,13303809,13369345,13434881,13500417,13565953,13631489,13697025,13762561,13828097,13893633,13959169,14024705,14090241,14155777,14221313,14286849,14352385,14417921,14483457,14548993,14614529,14680065,14745601,14811137,14876673,14942209,15007745,15073281,15138817,15204353,15269889,15335425,15400961,15466497,15532033,15597569,15663105,15728641,15794177,21430273,21495809,21561346,21626882,21692418,21757954,21823491,21889027,21954561,22020099,22085635,22151169,22216705,22282241,22347779,22478849,22544388,22609921,22675459,22806530,22937603,23003138,23068675,23134209,23199745,23265283,23330819,23396354,23461889,23527426,23592963,23658500,23724035,23789569,23855108,23920644,23986179,24051714,24117251,24182788,24248321,24313858,24444929,24510465,24576003,24641539,24707076,24772609,24903681,24969217,25034753,25100289,25165825,25231364],"data":[131073,15269889,23920642,24772609],"defaultauthority":[196609,720901,22151169],"defaultcancelled":[458753,1441797,24707073],"details":[458754,1441793,1507329,6881281,12320769,21823489,24707074],"defaultsuccess":[458753,1507333,24707073],"dll":[655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572865,1638401,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6094849,6160385,6225921,6291457,6356993,6422529,6488065,6553601,6619137,6684673,6750209,6815745,6881281,6946817,7012353,7077889,7143425,7208961,7274497,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7864321,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388609,8454145,8519681,8585217,8650753,8716289,8781825,8847361,8912897,8978433,9043969,9109505,9175041,9240577,9306113,9371649,9437185,9502721,9568257,9633793,9699329,9764865,9830401,9895937,9961473,10027009,10092545,10158081,10223617,10289153,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11337729,11403265,11468801,11534337,11599873,11665409,11730945,11796481,11862017,11927553,11993089,12058625,12124161,12189697,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18153473,18219009,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19267585,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020097,22085633,22151169,22216705,22282241,22347777,22413313,22478849,22544385,22609921,22675457,22740993,22806529,22872065,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23789569,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24379393,24444929,24510465,24576001,24641537,24707073,24772609,24838145,24903681,24969217,25034753,25100289,25165825,25231361],"dispose":[1769473,1835009,1900545,1966081,2686977,4653063,4915207,5111815,5308423,21561345,21626881,21692417,21757953,22937601],"determines":[1769473,1835009,1900545,1966081,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4456449,21561345,21626881,21692417,21757953,22020097,22085633,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23592961,23658497,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,25231361],"directly":[1769473,1966081,4718593,5373953,21561345,21757953],"deadline":[2097153,2228226,5898247,6029321,6553610,6684681,7012353,12320769,14024706,14286849,15400962,16973830,17956865,19857414,21889027,22020098,22544385,22609921,24051714,24772610],"duplex":[2162690,6160386,21954562],"different":[2228225,6684673,22020097],"defined":[2686979,2818049,2883585,15269889,22937603,23068673,23265281,23920641],"debug":[3014658,3080194,7405578,7929864,23396354,23461890],"deserializer":[3145729,8388615,8454149,15007746,18743302,23527425,23592962],"derived":[3473410,23920642],"definitions":[3866628,9961473,10027009,10092545,10158081,12320769,13172740,24313860,24510465],"duplexstreamingservermethod":[3866625,10027014,12320769,13172737,22740997,24313857],"definition":[3997697,6160385,10682369,12320770,15335426,20709377,20774913,21954561,23986178,24248321,24510465],"documentation":[5570561,6684674,7143425,7405570,7471107,7536642,7602177,7667714,7733251,7798786,7929858,7995395,8060930,8126465,8192002,8257539,8323074,8388611,8519682,8585219,8650755,8716289,8781826,8847363,9109505,9175042,9240579,9306114,9371650,9699329,10485761,10682369,11075585,11468803,11534338,11599876,11665411,11730947,11927553,11993089,18874369,19202049,19267585,20447233,20512769,20578305,20643841,23265281,23592961],"datetime":[5898245,6029317,6553605,6684679,16973830,19857414],"defaults":[6029313,6553601,6684673,6750209,6815745,7012353,9699329,10944513,11599873,12189697],"defaultarg":[6029317,6553601,6684673,6750209,6815745,7012354,9699329,10944513,11599873,12189697],"defintion":[6094849,6225921,6291457,6356993],"deserialize":[8454145],"disk":[11010050,13303810,24576002],"detail":[11403270,12320769,15728642,21233670,24707075],"defines":[12320769,22151169],"deserializing":[12320769,23592961],"delegates":[12320769],"delegate":[12320769,22413317,22740997,22872069,24379397,24838149],"destination":[12386305,21430273],"deserialized":[13959169,16842753,21823489],"dispatched":[14745601,15204353,18284545,19333121,23199745,23855105],"describes":[15269889,23920641],"duplexstreaming":[23789569],"differs":[24772609],"deadlineexceeded":[24772609],"delayed":[24772609],"directory":[24772612],"deleted":[24772609],"dataloss":[24772609],"disabled":[25165825]} \ No newline at end of file diff --git a/doc/ref/csharp/html/fti/FTI_102.json b/doc/ref/csharp/html/fti/FTI_102.json index a1d03f68e2..b2fe94168d 100644 --- a/doc/ref/csharp/html/fti/FTI_102.json +++ b/doc/ref/csharp/html/fti/FTI_102.json @@ -1 +1 @@ -{"follow":[1,2818049,7274497,23068673],"following":[131073,196609,262145,327681,393217,458753,524289,589825,1703937,1769473,1835009,1900545,1966081,2031617,2097153,2162689,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2686977,2752513,2818049,2883585,2949121,3014657,3080193,3145729,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4259841,4325377,4456449,13697025,13762561,13828097,13893633,13959169,14024705,14090241,14155777,14221313,14286849,14352385,14417921,14483457,14548993,14614529,14680065,14745601,14811137,14876673,14942209,15007745,15073281,15138817,15204353,15269889,15335425,15400962,15466497,15532033,15597569,15663105,15728641,15794177,20316161,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020097,22085633,22151169,22347777,22544385,22609921,22675457,22806529,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23855105,23920641,23986177,24051714,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707073,24903681,24969217,25100289,25231361],"fields":[196610,262146,327682,393218,458754,524290,589826,2031617,2097155,5570561,5832705,5898241,5963777,21823489,21889027,22151169,22544385,23658497,24182785,24707073,25100289,25231361],"field":[655362,720898,786434,851970,917506,983042,1048578,1114114,1179650,1245186,1310722,1376258,1441794,1507330,1572866,1638402],"fromaccesstoken":[1703937,4521989,21495809],"fromcredential":[1703937,4587525,21495809],"finished":[1769475,1835011,1900547,1966083,4653057,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5439489,5505025,9764865,21561347,21626883,21692419,21757955],"function":[1769473,1835009,1900545,1966081,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3276801,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4456449,4521985,4587521,4718593,4784129,4849665,4980737,5046273,5177345,5242881,5373953,5439489,5505025,5570561,5832705,5898241,5963777,6094849,6160385,6225921,6291457,6356993,6553601,6619137,6684673,6881281,7208961,7274497,7602177,8126465,8388609,8454146,8781825,8912897,9109505,9175041,9306113,9699329,9764865,9961473,10027009,10092545,10158081,10223617,10354689,10420225,10485761,10551297,10616833,10747905,10813441,11337729,11468801,11534337,11599873,11665409,11927553,11993089,15007746,18743297,18808833,21561345,21626881,21692417,21757953,22020097,22085633,22347777,22413313,22544385,22609921,22675457,22740993,22806529,23330817,23396353,23592962,23658497,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24379393,24444929,24510465,24576001,24641537,24838145,25231361],"fully":[1835009,1900545,2031617,2097153,3211265,4915201,5111809,14745601,15204353,18284545,19333121,21626881,21692417,21823489,21889025,23199745,23592961,23855105],"fashion":[2162689,6356993,21954561],"fatalfailure":[2228225,6553601,22020097,22282241],"finalize":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"free":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25165825,25231361],"freeing":[2686977,22937601],"foreachasync":[2686977,4259841,11468808,22937601,24903681],"false":[2818049,4259841,4390916,11599873,11796481,11862017,12058625,12124161,13434881,13500418,13631490,23068673,24903681,25034756],"fortype":[3014657,3080193,7602184,8126470,23396353,23461889],"finishes":[3538946,10420225,10813441,15400962,20185089,20250625,23986178,24051714],"first":[3604481,9764865,11468801,11534337,11599873,11665409,24051713],"finish":[6029313],"formatargs":[7405575,7471111,7536647,7667719,7733255,7798791,7929862,7995398,8060934,8192006,8257542,8323078],"func":[8388624,8454154,11468808,18743302,18808838],"file":[11010049,13303809,15269889,23920641,24576001,24772613],"fails":[11010049,12320769,13303809,23920641,24576001],"forceclientauth":[11272197],"flags":[12189704,12320769,15794178,21364742,25165825,25231362],"factory":[12255233,12320769,21495809,24248321],"functionality":[12320769,12386305,21430274],"files":[12320769,21954561],"format":[14090241,15400961,17498113,20054017,22020097,24051713],"fullname":[14745601,15204353,18284549,19333127,23199745,23855105],"frames":[15269889,23920641],"forceclientauthentication":[15663105,21037061,24641537],"failure":[22282242],"failed_precondition":[24772609],"failedprecondition":[24772609],"failures":[24772609],"flagsattribute":[25165828],"force":[25165825]} \ No newline at end of file +{"follow":[1,2818049,7274497,23068673],"following":[131073,196609,262145,327681,393217,458753,524289,589825,1703937,1769473,1835009,1900545,1966081,2031617,2097153,2162689,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2686977,2752513,2818049,2883585,2949121,3014657,3080193,3145729,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4259841,4325377,4456449,13697025,13762561,13828097,13893633,13959169,14024705,14090241,14155777,14221313,14286849,14352385,14417921,14483457,14548993,14614529,14680065,14745601,14811137,14876673,14942209,15007745,15073281,15138817,15204353,15269889,15335425,15400962,15466497,15532033,15597569,15663105,15728641,15794177,20316161,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020097,22085633,22151169,22347777,22544385,22609921,22675457,22806529,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23855105,23920641,23986177,24051714,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707073,24903681,24969217,25100289,25231361],"fields":[196610,262146,327682,393218,458754,524290,589826,2031617,2097155,5570561,5832705,5898241,5963777,21823489,21889027,22151169,22544385,23658497,24182785,24707073,25100289,25231361],"field":[655362,720898,786434,851970,917506,983042,1048578,1114114,1179650,1245186,1310722,1376258,1441794,1507330,1572866,1638402],"fromaccesstoken":[1703937,4521989,21495809],"fromcredential":[1703937,4587525,21495809],"finished":[1769475,1835011,1900547,1966083,4653057,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5439489,5505025,9764865,21561347,21626883,21692419,21757955],"function":[1769473,1835009,1900545,1966081,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4456449,4521985,4587521,4718593,4784129,4849665,4980737,5046273,5177345,5242881,5373953,5439489,5505025,5570561,5832705,5898241,5963777,6094849,6160385,6225921,6291457,6356993,6553601,6619137,6684673,6881281,7208961,7274497,7602177,8126465,8388609,8454146,8781825,8912897,9109505,9175041,9306113,9699329,9764865,9961473,10027009,10092545,10158081,10223617,10354689,10420225,10485761,10551297,10616833,10747905,10813441,11337729,11468801,11534337,11599873,11665409,11927553,11993089,15007746,18743297,18808833,21561345,21626881,21692417,21757953,22020097,22085633,22347777,22413313,22544385,22609921,22675457,22740993,22806529,23330817,23396353,23592963,23658497,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24379393,24444929,24510465,24576001,24641537,24838145,25231361],"fully":[1835009,1900545,2031617,2097153,4915201,5111809,14745601,15204353,18284545,19333121,21626881,21692417,21823489,21889025,23199745,23855105],"fashion":[2162689,6356993,21954561],"fatalfailure":[2228225,6553601,22020097,22282241],"finalize":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3211265,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23592961,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"free":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3211265,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23592961,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25165825,25231361],"freeing":[2686977,22937601],"foreachasync":[2686977,4259841,11468808,22937601,24903681],"false":[2818049,4259841,4390916,11599873,11796481,11862017,12058625,12124161,13434881,13500418,13631490,23068673,24903681,25034756],"fortype":[3014657,3080193,7602184,8126470,23396353,23461889],"finishes":[3538946,10420225,10813441,15400962,20185089,20250625,23986178,24051714],"first":[3604481,9764865,11468801,11534337,11599873,11665409,24051713],"finish":[6029313],"formatargs":[7405575,7471111,7536647,7667719,7733255,7798791,7929862,7995398,8060934,8192006,8257542,8323078],"func":[8388624,8454154,11468808,18743302,18808838],"file":[11010049,13303809,15269889,23920641,24576001,24772613],"fails":[11010049,12320769,13303809,23920641,24576001],"forceclientauth":[11272197],"flags":[12189704,12320769,15794178,21364742,25165825,25231362],"factory":[12255233,12320769,21495809,24248321],"functionality":[12320769,12386305,21430274],"files":[12320769,21954561],"format":[14090241,15400961,17498113,20054017,22020097,24051713],"fullname":[14745601,15204353,18284549,19333127,23199745,23855105],"frames":[15269889,23920641],"forceclientauthentication":[15663105,21037061,24641537],"failure":[22282242],"failed_precondition":[24772609],"failedprecondition":[24772609],"failures":[24772609],"flagsattribute":[25165828],"force":[25165825]} \ No newline at end of file diff --git a/doc/ref/csharp/html/fti/FTI_103.json b/doc/ref/csharp/html/fti/FTI_103.json index 398e827a53..530a1de8af 100644 --- a/doc/ref/csharp/html/fti/FTI_103.json +++ b/doc/ref/csharp/html/fti/FTI_103.json @@ -1 +1 @@ -{"grpc":[65537,131074,196610,262146,327682,393218,458754,524291,589826,655365,720901,786437,851973,917509,983045,1048581,1114117,1179653,1245189,1310725,1376261,1441797,1507333,1572870,1638405,1703938,1769474,1835010,1900546,1966082,2031618,2097154,2162690,2228226,2293762,2359298,2424834,2490370,2555906,2621443,2686978,2752514,2818050,2883586,2949122,3014658,3080194,3145730,3211266,3276802,3342338,3407874,3473410,3538946,3604482,3670018,3735554,3801090,3866626,3932162,3997698,4063234,4128770,4194306,4259842,4325378,4390914,4456450,4521989,4587525,4653061,4718597,4784133,4849669,4915205,4980741,5046277,5111813,5177349,5242885,5308421,5373957,5439493,5505029,5570568,5636104,5701640,5767177,5832709,5898245,5963782,6029320,6094854,6160390,6225926,6291462,6356998,6422533,6488069,6553605,6619141,6684682,6750214,6815750,6881287,6946822,7012357,7077893,7143433,7208965,7274501,7340037,7405575,7471112,7536647,7602182,7667719,7733256,7798791,7864325,7929863,7995400,8060935,8126470,8192007,8257544,8323079,8388616,8454149,8519690,8585224,8650760,8716294,8781834,8847372,8912901,8978437,9043973,9109510,9175050,9240588,9306122,9371655,9437189,9502728,9568262,9633798,9699336,9764870,9830405,9895942,9961479,10027015,10092551,10158087,10223621,10289157,10354693,10420229,10485768,10551302,10616837,10682376,10747909,10813445,10878981,10944517,11010053,11075590,11141126,11206661,11272197,11337733,11403270,11468812,11534346,11599886,11665420,11730952,11796485,11862021,11927558,11993094,12058629,12124165,12189702,12255237,12320787,12386307,12451844,12517378,12582914,12648450,12713986,12779522,12845058,12910594,12976130,13041666,13107202,13172738,13238274,13303810,13369346,13434882,13500418,13565954,13631490,13697026,13762562,13828098,13893634,13959170,14024706,14090242,14155778,14221315,14286850,14352386,14417923,14483458,14548994,14614530,14680066,14745602,14811138,14876674,14942210,15007746,15073282,15138818,15204354,15269890,15335426,15400962,15466498,15532034,15597570,15663106,15728643,15794178,15859717,15925253,15990789,16056325,16121861,16187397,16252933,16318469,16384005,16449541,16515077,16580613,16646149,16711685,16777221,16842757,16908293,16973829,17039365,17104901,17170437,17235973,17301509,17367045,17432581,17498117,17563653,17629189,17694725,17760261,17825798,17891333,17956869,18022405,18087942,18153477,18219013,18284549,18350085,18415621,18481157,18546693,18612229,18677765,18743301,18808837,18874374,18939909,19005445,19070981,19136517,19202054,19267590,19333125,19398661,19464197,19529733,19595269,19660805,19726341,19791877,19857413,19922949,19988485,20054021,20119557,20185093,20250629,20316165,20381701,20447238,20512774,20578310,20643846,20709381,20774917,20840453,20905989,20971525,21037061,21102597,21168133,21233669,21299206,21364741,21430283,21495815,21561350,21626886,21692422,21757958,21823493,21889029,21954566,22020103,22085640,22151174,22216709,22282247,22347783,22413319,22478854,22544390,22609927,22675463,22741000,22806537,22872071,22937605,23003141,23068677,23134213,23199749,23265286,23330822,23396358,23461893,23527430,23592966,23658503,23724037,23789574,23855110,23920646,23986183,24051718,24117255,24182790,24248326,24313862,24379399,24444934,24510470,24576007,24641543,24707078,24772614,24838150,24903687,24969222,25034758,25100296,25165830,25231366],"goes":[196610,983041,1048577,22151170],"given":[1703937,2228225,2359297,2818049,2883585,4259842,4390914,4521985,6684673,6881281,9568257,9633793,11599873,11665409,11862017,12124161,13107202,13434882,13500417,13631489,21495809,22020097,22347777,23068673,23265281,23920642,24903682,25034754],"googlecredential":[1703937,4587521,21495809],"generic":[1769473,1835009,1900545,1966081,2031617,2686977,2752513,2818049,2883585,3211265,3407873,6094849,6160385,6225921,6291457,6356993,6750209,6815745,6881281,7602177,8126465,8388609,9961473,10027009,10092545,10158081,10944513,11206657,11272193,11468801,11534337,11599878,11665413,11927553,11993089,12320769,13697025,13762561,13828097,13893633,13959169,14483457,14548993,14614529,14811137,15007745,15204353,21561345,21626881,21692417,21757953,21823489,22413313,22740993,22937601,23003137,23068673,23199745,23265281,23592961,23855105,24379393,24838145],"getawaiter":[1769473,1966081,4718597,5373957,21561345,21757953],"gethashcode":[1769473,1835009,1900545,1966081,2031617,2097153,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4456449,21561345,21626881,21692417,21757953,21823489,21889025,22020097,22085633,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23592961,23658497,23724033,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707073,25231361],"getstatus":[1769473,1835009,1900545,1966081,4784133,4980741,5177349,5439493,21561345,21626881,21692417,21757953],"gets":[1769475,1835011,1900547,1966083,2031617,2097153,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932162,3997698,4063233,4128769,4194305,4456449,4784129,4849665,4980737,5046273,5177345,5242881,5439489,5505025,10616833,10747905,11010049,13303809,13959172,14090241,14155780,14417921,14680065,14745604,15007746,15138819,15204358,15269896,15728642,15794177,16646145,16711681,16777217,16842753,17235969,17301505,17367041,17432577,17563649,18087937,18219009,18284545,18350081,18415617,18481153,18743297,18808833,19005441,19070977,19136513,19333121,19398657,19464193,19529729,19595265,19660801,21233665,21299201,21364737,21561347,21626883,21692419,21757955,21823493,21889025,22020098,22085637,22347777,22544385,22609921,22675457,22806530,23134209,23199748,23330817,23396353,23592963,23658497,23724036,23855111,23920649,23986177,24051713,24117249,24182785,24248321,24313857,24444930,24510466,24576002,24641537,24707075,25231362],"gettrailers":[1769473,1835009,1900545,1966081,4849669,5046277,5242885,5505029,21561345,21626881,21692417,21757953],"gettype":[1769473,1835009,1900545,1966081,2031617,2097153,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4456449,21561345,21626881,21692417,21757953,21823489,21889025,22020097,22085633,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23592961,23658497,23724033,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707073,25231361],"garbage":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"grpcenvironment":[2621443,7143427,12320769,14417923,18087938,22806535],"getenumerator":[3276801,3932161,3997697,9109512,10616839,10747911,23658497,24444929,24510465],"getbaseexception":[3473409,23920641],"getobjectdata":[3473409,23920641],"grpc_default_ssl_roots_file_path":[11010049,13303809,24576001],"guide":[11468801,11534337,11599873,11665409],"google":[12255233,21430273],"generated":[12320770,21954562],"general":[12320769,22020097],"grpc_channel_args":[12320769,22085633],"grpc_connectivity_state":[12320769,22282241],"grpc_compression_level":[12320769,22478849],"grpc_status_code":[12320769,24772609]} \ No newline at end of file +{"grpc":[65537,131074,196610,262146,327682,393218,458754,524291,589826,655365,720901,786437,851973,917509,983045,1048581,1114117,1179653,1245189,1310725,1376261,1441797,1507333,1572870,1638405,1703938,1769474,1835010,1900546,1966082,2031618,2097154,2162690,2228226,2293762,2359298,2424834,2490370,2555906,2621443,2686978,2752514,2818050,2883586,2949122,3014658,3080194,3145730,3211266,3276802,3342338,3407874,3473410,3538946,3604482,3670018,3735554,3801090,3866626,3932162,3997698,4063234,4128770,4194306,4259842,4325378,4390914,4456450,4521989,4587525,4653061,4718597,4784133,4849669,4915205,4980741,5046277,5111813,5177349,5242885,5308421,5373957,5439493,5505029,5570568,5636104,5701640,5767177,5832709,5898245,5963782,6029320,6094854,6160390,6225926,6291462,6356998,6422533,6488069,6553605,6619141,6684682,6750214,6815750,6881287,6946822,7012357,7077893,7143433,7208965,7274501,7340037,7405575,7471112,7536647,7602182,7667719,7733256,7798791,7864325,7929863,7995400,8060935,8126470,8192007,8257544,8323079,8388616,8454149,8519690,8585224,8650760,8716294,8781834,8847372,8912901,8978437,9043973,9109510,9175050,9240588,9306122,9371655,9437189,9502728,9568262,9633798,9699336,9764870,9830405,9895942,9961479,10027015,10092551,10158087,10223621,10289157,10354693,10420229,10485768,10551302,10616837,10682376,10747909,10813445,10878981,10944517,11010053,11075590,11141126,11206661,11272197,11337733,11403270,11468812,11534346,11599886,11665420,11730952,11796485,11862021,11927558,11993094,12058629,12124165,12189702,12255237,12320787,12386307,12451844,12517378,12582914,12648450,12713986,12779522,12845058,12910594,12976130,13041666,13107202,13172738,13238274,13303810,13369346,13434882,13500418,13565954,13631490,13697026,13762562,13828098,13893634,13959170,14024706,14090242,14155778,14221315,14286850,14352386,14417923,14483458,14548994,14614530,14680066,14745602,14811138,14876674,14942210,15007746,15073282,15138818,15204354,15269890,15335426,15400962,15466498,15532034,15597570,15663106,15728643,15794178,15859717,15925253,15990789,16056325,16121861,16187397,16252933,16318469,16384005,16449541,16515077,16580613,16646149,16711685,16777221,16842757,16908293,16973829,17039365,17104901,17170437,17235973,17301509,17367045,17432581,17498117,17563653,17629189,17694725,17760261,17825798,17891333,17956869,18022405,18087942,18153477,18219013,18284549,18350085,18415621,18481157,18546693,18612229,18677765,18743301,18808837,18874374,18939909,19005445,19070981,19136517,19202054,19267590,19333125,19398661,19464197,19529733,19595269,19660805,19726341,19791877,19857413,19922949,19988485,20054021,20119557,20185093,20250629,20316165,20381701,20447238,20512774,20578310,20643846,20709381,20774917,20840453,20905989,20971525,21037061,21102597,21168133,21233669,21299206,21364741,21430283,21495815,21561350,21626886,21692422,21757958,21823493,21889029,21954566,22020103,22085640,22151174,22216709,22282247,22347783,22413319,22478854,22544390,22609927,22675463,22741000,22806537,22872071,22937605,23003141,23068677,23134213,23199749,23265286,23330822,23396358,23461893,23527430,23592967,23658503,23724037,23789574,23855110,23920646,23986183,24051718,24117255,24182790,24248326,24313862,24379399,24444934,24510470,24576007,24641543,24707078,24772614,24838150,24903687,24969222,25034758,25100296,25165830,25231366],"goes":[196610,983041,1048577,22151170],"given":[1703937,2228225,2359297,2818049,2883585,4259842,4390914,4521985,6684673,6881281,9568257,9633793,11599873,11665409,11862017,12124161,13107202,13434882,13500417,13631489,21495809,22020097,22347777,23068673,23265281,23920642,24903682,25034754],"googlecredential":[1703937,4587521,21495809],"generic":[1769473,1835009,1900545,1966081,2031617,2686977,2752513,2818049,2883585,3211265,3407873,6094849,6160385,6225921,6291457,6356993,6750209,6815745,6881281,7602177,8126465,8388609,9961473,10027009,10092545,10158081,10944513,11206657,11272193,11468801,11534337,11599878,11665413,11927553,11993089,12320769,13697025,13762561,13828097,13893633,13959169,14483457,14548993,14614529,14811137,15007745,15204353,21561345,21626881,21692417,21757953,21823489,22413313,22740993,22937601,23003137,23068673,23199745,23265281,23592961,23855105,24379393,24838145],"getawaiter":[1769473,1966081,4718597,5373957,21561345,21757953],"gethashcode":[1769473,1835009,1900545,1966081,2031617,2097153,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4456449,21561345,21626881,21692417,21757953,21823489,21889025,22020097,22085633,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23592961,23658497,23724033,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707073,25231361],"getstatus":[1769473,1835009,1900545,1966081,4784133,4980741,5177349,5439493,21561345,21626881,21692417,21757953],"gets":[1769475,1835011,1900547,1966083,2031617,2097153,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932162,3997698,4063233,4128769,4194305,4456449,4784129,4849665,4980737,5046273,5177345,5242881,5439489,5505025,10616833,10747905,11010049,13303809,13959172,14090241,14155780,14417921,14680065,14745604,15007746,15138819,15204358,15269896,15728642,15794177,16646145,16711681,16777217,16842753,17235969,17301505,17367041,17432577,17563649,18087937,18219009,18284545,18350081,18415617,18481153,18743297,18808833,19005441,19070977,19136513,19333121,19398657,19464193,19529729,19595265,19660801,21233665,21299201,21364737,21561347,21626883,21692419,21757955,21823493,21889025,22020098,22085637,22347777,22544385,22609921,22675457,22806530,23134209,23199748,23330817,23396353,23592963,23658497,23724036,23855111,23920649,23986177,24051713,24117249,24182785,24248321,24313857,24444930,24510466,24576002,24641537,24707075,25231362],"gettrailers":[1769473,1835009,1900545,1966081,4849669,5046277,5242885,5505029,21561345,21626881,21692417,21757953],"gettype":[1769473,1835009,1900545,1966081,2031617,2097153,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4456449,21561345,21626881,21692417,21757953,21823489,21889025,22020097,22085633,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23592961,23658497,23724033,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707073,25231361],"garbage":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3211265,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23592961,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"grpcenvironment":[2621443,7143427,12320769,14417923,18087938,22806535],"getenumerator":[3276801,3932161,3997697,9109512,10616839,10747911,23658497,24444929,24510465],"getbaseexception":[3473409,23920641],"getobjectdata":[3473409,23920641],"grpc_default_ssl_roots_file_path":[11010049,13303809,24576001],"guide":[11468801,11534337,11599873,11665409],"google":[12255233,21430273],"generated":[12320770,21954562],"general":[12320769,22020097],"grpc_channel_args":[12320769,22085633],"grpc_connectivity_state":[12320769,22282241],"grpc_compression_level":[12320769,22478849],"grpc_status_code":[12320769,24772609]} \ No newline at end of file diff --git a/doc/ref/csharp/html/fti/FTI_104.json b/doc/ref/csharp/html/fti/FTI_104.json index 4c30282ae7..4013bb0433 100644 --- a/doc/ref/csharp/html/fti/FTI_104.json +++ b/doc/ref/csharp/html/fti/FTI_104.json @@ -1 +1 @@ -{"http2initialsequencenumber":[196609,786437,22151169],"http2":[196610,786433,851969,22151170],"headers":[327681,1245185,2097153,3604482,5963783,6029320,9764868,12320771,13697025,13762561,13828097,13893633,14024706,15990785,16121857,16252929,16449537,17039366,21561345,21626881,21692417,21757953,21889027,22872065,23658499,24051714],"hash":[1769473,1835009,1900545,1966081,2031617,2097153,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4456449,21561345,21626881,21692417,21757953,21823489,21889025,22020097,22085633,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23592961,23658497,23724033,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707073,25231361],"handlers":[3997697,10682369,12320771,22609921,23265281,24248321,24510465],"headerinterceptor":[4521989,4587525,12320769,14221313,17760268,22347777,22872069],"header":[4521985,4587521,14221313,17760257,22347777],"host":[5701639,5767174,6750209,6815751,9895942,10551302,12648450,13959170,14221315,15400962,15532033,16580614,17825799,19922950,20578311,21823490,22020098,22347779,24051714,24182785],"holding":[9043969,13041665,23724033],"handler":[9961478,10027014,10092550,10158086,12320773,22413313,22740993,23658497,24379393,24838145],"helper":[12320769,21954561],"hosts":[14221313,17825793,22347777],"helplink":[15269889,23920641],"help":[15269889,23920641],"hresult":[15269890,23920642],"hierarchy":[21495809,21561345,21626881,21692417,21757953,21954561,22020097,22085633,22151169,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23527425,23658497,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24903681,24969217,25034753,25100289,25231361],"high":[22478850],"hint":[25165825]} \ No newline at end of file +{"http2initialsequencenumber":[196609,786437,22151169],"http2":[196610,786433,851969,22151170],"headers":[327681,1245185,2097153,3604482,5963783,6029320,9764868,12320771,13697025,13762561,13828097,13893633,14024706,15990785,16121857,16252929,16449537,17039366,21561345,21626881,21692417,21757953,21889027,22872065,23658499,24051714],"hash":[1769473,1835009,1900545,1966081,2031617,2097153,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4456449,21561345,21626881,21692417,21757953,21823489,21889025,22020097,22085633,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23592961,23658497,23724033,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707073,25231361],"handlers":[3997697,10682369,12320771,22609921,23265281,24248321,24510465],"headerinterceptor":[4521989,4587525,12320769,14221313,17760268,22347777,22872069],"header":[4521985,4587521,14221313,17760257,22347777],"host":[5701639,5767174,6750209,6815751,9895942,10551302,12648450,13959170,14221315,15400962,15532033,16580614,17825799,19922950,20578311,21823490,22020098,22347779,24051714,24182785],"holding":[9043969,13041665,23724033],"handler":[9961478,10027014,10092550,10158086,12320773,22413313,22740993,23658497,24379393,24838145],"helper":[12320769,21954561],"hosts":[14221313,17825793,22347777],"helplink":[15269889,23920641],"help":[15269889,23920641],"hresult":[15269890,23920642],"hierarchy":[21495809,21561345,21626881,21692417,21757953,21954561,22020097,22085633,22151169,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23527425,23592961,23658497,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24903681,24969217,25034753,25100289,25231361],"high":[22478850],"hint":[25165825]} \ No newline at end of file diff --git a/doc/ref/csharp/html/fti/FTI_105.json b/doc/ref/csharp/html/fti/FTI_105.json index d521afa4a0..a31687940f 100644 --- a/doc/ref/csharp/html/fti/FTI_105.json +++ b/doc/ref/csharp/html/fti/FTI_105.json @@ -1 +1 @@ -{"inherited":[131073,1769476,1835012,1900548,1966084,2031620,2097156,2228230,2293764,2359302,2424838,2490374,2555910,2621446,2686978,2818049,2883585,2949124,3014662,3211268,3276804,3342339,3407878,3473416,3538950,3604486,3670022,3735558,3801094,3866630,3932166,3997702,4063236,4128774,4194307,4456454,14483457,14614529,14811137,15269896,21561348,21626884,21692420,21757956,21823492,21889028,22020102,22085636,22347782,22544390,22609926,22675462,22806534,22937603,23068674,23265282,23330820,23396358,23592964,23658500,23724035,23855110,23920657,23986182,24051718,24117254,24182790,24248326,24313862,24444934,24510470,24576004,24641542,24707075,25231366],"initial":[196609,786433,15400961,20119553,22151169,24051713],"incoming":[196609,851969,22151169],"instance":[327681,1310721,1769473,1835009,1900545,1966081,2031621,2097159,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211268,3276801,3342339,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194307,4456449,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6946817,7077889,8978433,9043969,9437185,9502721,9830401,9961473,10027009,10092545,10158081,10289153,11403265,11468802,11534338,11599874,11665410,12189697,12517379,13041666,14352385,15269889,15466497,18022401,20381697,21561345,21626881,21692417,21757953,21823496,21889032,22020097,22085633,22347778,22544385,22609921,22675459,22806529,23330817,23396353,23592964,23658499,23724037,23855106,23920642,23986177,24051713,24117251,24182785,24248321,24313858,24444929,24510465,24576001,24641537,24707076,25231362],"initonly":[1179649,1310721,1441793,1507329,1638401],"int":[1376259,6422531,6815747,8847364,9175044,9240580,9371652,9895939,10485763,10551302,11730950,17235972,18874373,19267588,20447236,20643844],"integer":[1376257,6422531,6815745,8847361,9175041,9240577,9371649,9895937,10485761,10551298,11730946,12582913,14155777,17235970,18874369,19267585,20447233,20643841,22085634,22216706],"int32":[1376257,3932161,6422530,6815746,8847365,9175041,9240581,9371652,9895937,10485762,10551300,11730952,12582913,12648449,13238273,17235969,18874369,19267587,20447233,20643841,22020097,22085633,24444929],"interceptor":[1703938,4521986,4587522,12320769,14221314,17760258,21495810,22347778,22872065],"implements":[1703937,4587521,4653057,4915201,5111809,5308417,7405569,7471105,7536641,7602177,7667713,7733249,7798785,8519681,8716289,8781825,8847361,9109505,9175041,9240577,9306113,9371649,10616833,10747905,18874369,19202049,19267585,19333121,19398657,19595265,19660801,21495809,21561345,21626881,21692417,21757953,23396353,23658497,23855105,24444929,24510465],"itokenaccess":[1703937,4587526,21495809],"invalidoperationexception":[1769474,1835010,1900546,1966082,4390914,4784129,4849665,4980737,5046273,5177345,5242881,5439489,5505025,12058625,12124161,13631490,21561346,21626882,21692418,21757954,25034754],"indicates":[2031617,2097153,3211265,3342337,4194305,6553601,15728641,21299201,21823489,21889025,23592961,23724033,24707074,24772609],"invokes":[2162693,6094849,6160385,6225921,6291457,6356993,21954565],"independent":[2162689,6160385,21954561],"implicitly":[2228225,3604481,6553601,9764865,22020097,24051713],"iasyncstreamreader":[2686979,11468809,11534344,12320769,14483459,16187398,16318470,22413317,22740997,22937606],"idisposable":[2686977,4653057,4915201,5111809,5308417,21561348,21626884,21692420,21757956,22937605],"iasyncenumerator":[2686977,14483457,22937606],"interface":[2686977,2752513,2818049,2883585,3080193,7208961,7274497,7929857,7995393,8060929,8126465,8192001,8257537,8323073,12320769,12386305,12845057,12910593,14483457,14548993,14614529,14680065,14745601,14811137,18153473,18219009,18284545,18350081,18415617,18481153,21561345,21626881,21692417,21757953,22937607,23003141,23068678,23134213,23199749,23265286,23396353,23461893,23658500,23855105,24444930,24510466],"iasyncstreamwriter":[2752515,2818049,2883585,7208962,12320769,14548995,14614529,14811137,18153474,23003142,23068678,23265286],"iclientstreamwriter":[2818051,4259841,7274498,11599883,12320769,13434881,14614531,15859718,16056326,23068678,24903681],"iserverstreamwriter":[2883587,4259841,11665418,12320769,13434881,14811139,15400961,20316161,22740997,23265287,24051713,24379397,24903681],"info":[3014658,3080194,7667722,8192008,12320769,23396354,23461890,25100289],"ilogger":[3080195,7143430,7405569,7471105,7536641,7602183,7667713,7733249,7798785,7929860,7995397,8060932,8126472,8192004,8257541,8323076,12386305,12845058,12910594,18087942,23396356,23461894],"indexof":[3276801,9175049,23658497],"insert":[3276801,9240586,23658497],"information":[3473409,11468801,11534337,11599873,11665409,15269889,23920642,24772609],"invoked":[3604482,9764866,12320769,14221313,17760257,21823489,22347777,24051714],"immutable":[3866625,10223617,24313857],"ienumerable":[4259842,6750214,6815750,9109505,10616833,10747905,10944517,11206662,11272198,11599882,11665417,12648450,13369346,13434882,22020098,23658504,24444936,24510472,24641538,24903682],"initializes":[5636097,5701633,5767169,6946817,7077889,8454145,8978433,9043969,9437185,9502721,9830401,12189697,12517379,13041666,21823491,22347777,22675457,23592961,23658497,23724034,23855105,24117249,25231361],"intvalue":[6422533,14155777,17235973,22085633],"invoke":[6881281],"invocation":[6881281,6946817],"item":[8519687,8781831,9175047,9240583,9306119,15073281,19267590,23658497],"icollection":[8519681,8716289,8781825,8847361,9306113,18874369,19202049,23658500],"indicating":[8978433,9043969],"ienumerator":[9109510,10616838,10747910],"ilist":[9175041,9240577,9371649,19267585,21102598,23658500],"index":[9240583,9371655,19267590],"interceptors":[12255234,21495810],"inherit":[12255233,21495809,23920641,24576001,24641537],"indirectly":[12320769,21954561],"invoking":[12320769,22020097],"initialization":[12320769,22806529],"interfaces":[12320769,12386305],"ihaswriteoptions":[12320769,14680067,18219010,23134214],"imethod":[12320769,14745603,18284546,18350082,18415618,18481154,19333121,19398657,19595265,19660801,22872069,23199750,23855108],"ispropagatecancellation":[14286849,17891333,22544385],"ispropagatedeadline":[14286849,17956869,22544385],"insecure":[14352385,15466497,18022405,20381701,22675457,24117249],"isreadonly":[15073281,19202056,23658497],"isbinary":[15138817,18939909,23724033],"innerexception":[15269889,23920641],"immediate":[15269889,23920641],"indicate":[15728641,21299201,24707073],"inheritance":[21495809,21561345,21626881,21692417,21757953,21954561,22020097,22085633,22151169,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23527425,23658497,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24903681,24969217,25034753,25100289,25231361],"idle":[22282242],"inherits":[22937601,23068673,23265281,23920641,24576001,24641537],"invalidargument":[24772609],"invalid":[24772609],"invalid_argument":[24772609],"instead":[24772610],"identified":[24772609],"issue":[24772609],"implemented":[24772609],"internal":[24772610],"invariants":[24772609],"immediately":[25165825]} \ No newline at end of file +{"inherited":[131073,1769476,1835012,1900548,1966084,2031620,2097156,2228230,2293764,2359302,2424838,2490374,2555910,2621446,2686978,2818049,2883585,2949124,3014662,3211270,3276804,3342339,3407878,3473416,3538950,3604486,3670022,3735558,3801094,3866630,3932166,3997702,4063236,4128774,4194307,4456454,14483457,14614529,14811137,15269896,21561348,21626884,21692420,21757956,21823492,21889028,22020102,22085636,22347782,22544390,22609926,22675462,22806534,22937603,23068674,23265282,23330820,23396358,23592966,23658500,23724035,23855110,23920657,23986182,24051718,24117254,24182790,24248326,24313862,24444934,24510470,24576004,24641542,24707075,25231366],"initial":[196609,786433,15400961,20119553,22151169,24051713],"incoming":[196609,851969,22151169],"instance":[327681,1310721,1769473,1835009,1900545,1966081,2031621,2097159,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3342339,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194307,4456449,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6946817,7077889,8978433,9043969,9437185,9502721,9830401,9961473,10027009,10092545,10158081,10289153,11403265,11468802,11534338,11599874,11665410,12189697,12517379,13041666,14352385,15269889,15466497,18022401,20381697,21561345,21626881,21692417,21757953,21823496,21889032,22020097,22085633,22347778,22544385,22609921,22675459,22806529,23330817,23396353,23592961,23658499,23724037,23855106,23920642,23986177,24051713,24117251,24182785,24248321,24313858,24444929,24510465,24576001,24641537,24707076,25231362],"initonly":[1179649,1310721,1441793,1507329,1638401],"int":[1376259,6422531,6815747,8847364,9175044,9240580,9371652,9895939,10485763,10551302,11730950,17235972,18874373,19267588,20447236,20643844],"integer":[1376257,6422531,6815745,8847361,9175041,9240577,9371649,9895937,10485761,10551298,11730946,12582913,14155777,17235970,18874369,19267585,20447233,20643841,22085634,22216706],"int32":[1376257,3932161,6422530,6815746,8847365,9175041,9240581,9371652,9895937,10485762,10551300,11730952,12582913,12648449,13238273,17235969,18874369,19267587,20447233,20643841,22020097,22085633,24444929],"interceptor":[1703938,4521986,4587522,12320769,14221314,17760258,21495810,22347778,22872065],"implements":[1703937,4587521,4653057,4915201,5111809,5308417,7405569,7471105,7536641,7602177,7667713,7733249,7798785,8519681,8716289,8781825,8847361,9109505,9175041,9240577,9306113,9371649,10616833,10747905,18874369,19202049,19267585,19333121,19398657,19595265,19660801,21495809,21561345,21626881,21692417,21757953,23396353,23658497,23855105,24444929,24510465],"itokenaccess":[1703937,4587526,21495809],"invalidoperationexception":[1769474,1835010,1900546,1966082,4390914,4784129,4849665,4980737,5046273,5177345,5242881,5439489,5505025,12058625,12124161,13631490,21561346,21626882,21692418,21757954,25034754],"indicates":[2031617,2097153,3342337,4194305,6553601,15728641,21299201,21823489,21889025,23724033,24707074,24772609],"invokes":[2162693,6094849,6160385,6225921,6291457,6356993,21954565],"independent":[2162689,6160385,21954561],"implicitly":[2228225,3604481,6553601,9764865,22020097,24051713],"iasyncstreamreader":[2686979,11468809,11534344,12320769,14483459,16187398,16318470,22413317,22740997,22937606],"idisposable":[2686977,4653057,4915201,5111809,5308417,21561348,21626884,21692420,21757956,22937605],"iasyncenumerator":[2686977,14483457,22937606],"interface":[2686977,2752513,2818049,2883585,3080193,7208961,7274497,7929857,7995393,8060929,8126465,8192001,8257537,8323073,12320769,12386305,12845057,12910593,14483457,14548993,14614529,14680065,14745601,14811137,18153473,18219009,18284545,18350081,18415617,18481153,21561345,21626881,21692417,21757953,22937607,23003141,23068678,23134213,23199749,23265286,23396353,23461893,23658500,23855105,24444930,24510466],"iasyncstreamwriter":[2752515,2818049,2883585,7208962,12320769,14548995,14614529,14811137,18153474,23003142,23068678,23265286],"iclientstreamwriter":[2818051,4259841,7274498,11599883,12320769,13434881,14614531,15859718,16056326,23068678,24903681],"iserverstreamwriter":[2883587,4259841,11665418,12320769,13434881,14811139,15400961,20316161,22740997,23265287,24051713,24379397,24903681],"info":[3014658,3080194,7667722,8192008,12320769,23396354,23461890,25100289],"ilogger":[3080195,7143430,7405569,7471105,7536641,7602183,7667713,7733249,7798785,7929860,7995397,8060932,8126472,8192004,8257541,8323076,12386305,12845058,12910594,18087942,23396356,23461894],"indexof":[3276801,9175049,23658497],"insert":[3276801,9240586,23658497],"information":[3473409,11468801,11534337,11599873,11665409,15269889,23920642,24772609],"invoked":[3604482,9764866,12320769,14221313,17760257,21823489,22347777,24051714],"immutable":[3866625,10223617,24313857],"ienumerable":[4259842,6750214,6815750,9109505,10616833,10747905,10944517,11206662,11272198,11599882,11665417,12648450,13369346,13434882,22020098,23658504,24444936,24510472,24641538,24903682],"initializes":[5636097,5701633,5767169,6946817,7077889,8454145,8978433,9043969,9437185,9502721,9830401,12189697,12517379,13041666,21823491,22347777,22675457,23592961,23658497,23724034,23855105,24117249,25231361],"intvalue":[6422533,14155777,17235973,22085633],"invoke":[6881281],"invocation":[6881281,6946817],"item":[8519687,8781831,9175047,9240583,9306119,15073281,19267590,23658497],"icollection":[8519681,8716289,8781825,8847361,9306113,18874369,19202049,23658500],"indicating":[8978433,9043969],"ienumerator":[9109510,10616838,10747910],"ilist":[9175041,9240577,9371649,19267585,21102598,23658500],"index":[9240583,9371655,19267590],"interceptors":[12255234,21495810],"inherit":[12255233,21495809,23920641,24576001,24641537],"indirectly":[12320769,21954561],"invoking":[12320769,22020097],"initialization":[12320769,22806529],"interfaces":[12320769,12386305],"ihaswriteoptions":[12320769,14680067,18219010,23134214],"imethod":[12320769,14745603,18284546,18350082,18415618,18481154,19333121,19398657,19595265,19660801,22872069,23199750,23855108],"ispropagatecancellation":[14286849,17891333,22544385],"ispropagatedeadline":[14286849,17956869,22544385],"insecure":[14352385,15466497,18022405,20381701,22675457,24117249],"isreadonly":[15073281,19202056,23658497],"isbinary":[15138817,18939909,23724033],"innerexception":[15269889,23920641],"immediate":[15269889,23920641],"indicate":[15728641,21299201,24707073],"inheritance":[21495809,21561345,21626881,21692417,21757953,21954561,22020097,22085633,22151169,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23527425,23592961,23658497,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24903681,24969217,25034753,25100289,25231361],"idle":[22282242],"inherits":[22937601,23068673,23265281,23920641,24576001,24641537],"invalidargument":[24772609],"invalid":[24772609],"invalid_argument":[24772609],"instead":[24772610],"identified":[24772609],"issue":[24772609],"implemented":[24772609],"internal":[24772610],"invariants":[24772609],"immediately":[25165825]} \ No newline at end of file diff --git a/doc/ref/csharp/html/fti/FTI_109.json b/doc/ref/csharp/html/fti/FTI_109.json index 6c114c9ab6..7071213861 100644 --- a/doc/ref/csharp/html/fti/FTI_109.json +++ b/doc/ref/csharp/html/fti/FTI_109.json @@ -1 +1 @@ -{"members":[131073,196609,262145,327681,393217,458753,524289,589825,1703937,1769473,1835009,1900545,1966081,2031617,2097153,2162689,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2686977,2752513,2818049,2883585,2949121,3014657,3080193,3145729,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4259841,4325377,4456449,13697025,13762561,13828097,13893633,13959169,14024705,14090241,14155777,14221313,14286849,14352385,14417921,14483457,14548993,14614529,14680065,14745601,14811137,14876673,14942209,15007745,15073281,15138817,15204353,15269889,15335425,15400961,15466497,15532033,15597569,15663105,15728641,15794177,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020097,22085633,22151169,22216705,22282241,22347777,22478849,22544385,22609921,22675457,22806529,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23789569,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707073,24772609,24903681,24969217,25100289,25165825,25231361],"maxconcurrentstreams":[196609,851973,22151169],"maximum":[196610,851969,917505,22151170],"maxmessagelength":[196609,917509,22151169],"message":[196609,458754,917505,1441793,1507329,3014662,3080198,3604481,4390914,6094849,6225922,6291459,6356995,6881282,7208966,7405576,7471112,7536648,7667720,7733256,7798792,7929863,7995399,8060935,8192007,8257543,8323079,9633799,9764865,9961474,10027010,10092546,10158082,11862018,12124162,12713986,12779522,12845058,12910594,13107201,13500417,13631489,15269890,21561346,21626882,21692417,21757953,21823490,22151169,22413314,22740994,22937601,23003137,23068673,23396358,23461894,23855106,23920643,24051713,24379394,24707074,24838146,25034754,25165825],"metadata":[196610,327684,983041,1048577,1245186,1310728,1769473,1835009,1900545,1966081,3276804,3342339,4849670,5046278,5242886,5505030,5963781,6029317,8519693,8585221,8650757,8716291,8781836,8847374,8912899,8978438,9043974,9109513,9175052,9240590,9306124,9371652,9437190,9764869,12320773,12976131,13041669,14221313,15073283,15138821,15400961,15990790,16121862,16252934,16449542,17039366,17760257,18874371,18939906,19005443,19070979,19136515,19202051,19267595,20119559,20185094,21561345,21626881,21692417,21757953,22151170,22347777,22872074,23658521,23724043,24051713],"mutable":[655361,720897,786433,851969,917505,983041,1048577,1114113,1245185,1376257,1572865],"methods":[1703938,1769474,1835010,1900546,1966082,2031618,2097154,2162690,2228226,2293762,2359298,2424834,2490370,2555906,2621442,2686979,2752514,2818051,2883587,2949122,3014658,3080194,3145730,3211266,3276802,3342338,3407874,3473410,3538946,3604482,3670018,3735554,3801090,3866626,3932162,3997698,4063234,4128770,4194306,4259842,4325378,4390914,4456450,11468802,11534338,11599874,11665410,12255233,12320769,12451843,14745601,15204353,18284545,19333121,21495810,21561345,21626881,21692417,21757953,21823489,21889025,21954562,22020097,22085633,22347777,22544385,22609921,22675457,22806529,22937602,23003137,23068674,23199745,23265282,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23855106,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707073,24903682,24969218,25034754,25231361],"means":[1769473,1835009,1900545,1966081,4653057,4915201,5111809,5308417,6029313,21561345,21626881,21692417,21757953,24772609],"messages":[2162689,3604481,6094849,6160387,6225921,8454146,9502722,9764865,12320775,12386305,15204354,19464193,19529729,21954561,22937601,23003137,23068673,23265281,23461889,23592961,23658498,23855106,24051713],"memberwiseclone":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"method":[2359297,3407875,3604481,3866632,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,5570561,5636108,5701645,5767175,5832705,5898241,5963777,6094849,6160385,6225921,6291457,6356993,6553601,6619137,6684673,6881293,7143425,7208961,7274497,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388609,8519681,8585217,8650753,8716289,8781825,8847361,8912897,9109505,9175041,9240577,9306113,9371649,9502729,9699329,9764866,9961487,10027023,10092559,10158095,10223617,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,11337729,11468805,11534341,11599877,11665413,11730945,11796481,11862017,11927553,11993089,12058625,12124161,12320774,12517378,12713985,12779521,12845057,12910593,12976129,13172745,13238273,13434881,13500417,13565953,13631489,13959170,14745604,15204359,15269889,15400962,16646150,18284545,18350081,18415617,18481153,19333123,19398659,19464194,19529730,19595267,19660803,19988486,21823492,22347777,22413314,22740994,22872069,23199749,23789569,23855120,23920641,24051715,24248322,24313864,24379394,24838146],"movenext":[2686977,22937601],"marshallers":[3145731,8388613,12320770,14942211,18677762,23527432],"marshaller":[3145729,3211267,5767182,8388614,8454150,9502732,12320769,12517378,13959170,14942209,15007747,15204354,16777223,16842759,18677767,18743298,18808834,19464199,19529735,21823492,23527426,23592969,23855106],"member":[4521985,4587521,4718593,4784129,4849665,4980737,5046273,5177345,5242881,5373953,5439489,5505025,5570561,5832705,5898241,5963777,6094849,6160385,6225921,6291457,6356993,6553601,6619137,6684673,6881281,7143425,8388609,8585217,8650753,9699329,9764865,9961473,10027009,10092545,10158081,10223617,10354689,10420225,10485761,10551297,10682369,10813441,10878977,11468801,11534337,11599873,11665409,11730945,11796481,11862017,11927553,11993089,12058625,12124161,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18546689,18612225,18677761,18743297,18808833,18939905,19005441,19070977,19136513,19464193,19529729,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,22216705,22282241,22478849,23789569,24772609,25165825],"missing":[5570561,6684674,7143425,7405570,7471107,7536642,7602177,7667714,7733251,7798786,7929858,7995395,8060930,8126465,8192002,8257539,8323074,8388611,8519682,8585219,8650755,8716289,8781826,8847363,9109505,9175042,9240579,9306114,9371650,9699329,10485761,10682369,11075585,11468803,11534338,11599876,11665411,11730947,11927553,11993089,18874369,19202049,19267585,20447233,20512769,20578305,20643841,23265281,23592961],"methodtype":[9502725,12320769,18481158,19660807,23789573],"main":[12320769,21430273],"make":[12320769,21954561],"making":[12320770,21954561,22609921],"makes":[12320769,22609921],"mapping":[12320769,24248321],"microbenchmarks":[12451841,24969217],"multiple":[14221313,17825793,22347777],"meaning":[14221313,17825793,22347777],"maintains":[14548993,14614529,14811137,18153473,23003137,23068673,23265281],"mustinherit":[22347777,22675457,24117249],"medium":[22478850],"malformed":[24772609]} \ No newline at end of file +{"members":[131073,196609,262145,327681,393217,458753,524289,589825,1703937,1769473,1835009,1900545,1966081,2031617,2097153,2162689,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2686977,2752513,2818049,2883585,2949121,3014657,3080193,3145729,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4259841,4325377,4456449,13697025,13762561,13828097,13893633,13959169,14024705,14090241,14155777,14221313,14286849,14352385,14417921,14483457,14548993,14614529,14680065,14745601,14811137,14876673,14942209,15007745,15073281,15138817,15204353,15269889,15335425,15400961,15466497,15532033,15597569,15663105,15728641,15794177,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020097,22085633,22151169,22216705,22282241,22347777,22478849,22544385,22609921,22675457,22806529,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23789569,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707073,24772609,24903681,24969217,25100289,25165825,25231361],"maxconcurrentstreams":[196609,851973,22151169],"maximum":[196610,851969,917505,22151170],"maxmessagelength":[196609,917509,22151169],"message":[196609,458754,917505,1441793,1507329,3014662,3080198,3604481,4390914,6094849,6225922,6291459,6356995,6881282,7208966,7405576,7471112,7536648,7667720,7733256,7798792,7929863,7995399,8060935,8192007,8257543,8323079,9633799,9764865,9961474,10027010,10092546,10158082,11862018,12124162,12713986,12779522,12845058,12910594,13107201,13500417,13631489,15269890,21561346,21626882,21692417,21757953,21823490,22151169,22413314,22740994,22937601,23003137,23068673,23396358,23461894,23855106,23920643,24051713,24379394,24707074,24838146,25034754,25165825],"metadata":[196610,327684,983041,1048577,1245186,1310728,1769473,1835009,1900545,1966081,3276804,3342339,4849670,5046278,5242886,5505030,5963781,6029317,8519693,8585221,8650757,8716291,8781836,8847374,8912899,8978438,9043974,9109513,9175052,9240590,9306124,9371652,9437190,9764869,12320773,12976131,13041669,14221313,15073283,15138821,15400961,15990790,16121862,16252934,16449542,17039366,17760257,18874371,18939906,19005443,19070979,19136515,19202051,19267595,20119559,20185094,21561345,21626881,21692417,21757953,22151170,22347777,22872074,23658521,23724043,24051713],"mutable":[655361,720897,786433,851969,917505,983041,1048577,1114113,1245185,1376257,1572865],"methods":[1703938,1769474,1835010,1900546,1966082,2031618,2097154,2162690,2228226,2293762,2359298,2424834,2490370,2555906,2621442,2686979,2752514,2818051,2883587,2949122,3014658,3080194,3145730,3211266,3276802,3342338,3407874,3473410,3538946,3604482,3670018,3735554,3801090,3866626,3932162,3997698,4063234,4128770,4194306,4259842,4325378,4390914,4456450,11468802,11534338,11599874,11665410,12255233,12320769,12451843,14745601,15204353,18284545,19333121,21495810,21561345,21626881,21692417,21757953,21823489,21889025,21954562,22020097,22085633,22347777,22544385,22609921,22675457,22806529,22937602,23003137,23068674,23199745,23265282,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23855106,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707073,24903682,24969218,25034754,25231361],"means":[1769473,1835009,1900545,1966081,4653057,4915201,5111809,5308417,6029313,21561345,21626881,21692417,21757953,24772609],"messages":[2162689,3604481,6094849,6160387,6225921,8454146,9502722,9764865,12320775,12386305,15204354,19464193,19529729,21954561,22937601,23003137,23068673,23265281,23461889,23592961,23658498,23855106,24051713],"memberwiseclone":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3211265,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23592961,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"method":[2359297,3407875,3604481,3866632,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,5570561,5636108,5701645,5767175,5832705,5898241,5963777,6094849,6160385,6225921,6291457,6356993,6553601,6619137,6684673,6881293,7143425,7208961,7274497,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388609,8519681,8585217,8650753,8716289,8781825,8847361,8912897,9109505,9175041,9240577,9306113,9371649,9502729,9699329,9764866,9961487,10027023,10092559,10158095,10223617,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,11337729,11468805,11534341,11599877,11665413,11730945,11796481,11862017,11927553,11993089,12058625,12124161,12320774,12517378,12713985,12779521,12845057,12910593,12976129,13172745,13238273,13434881,13500417,13565953,13631489,13959170,14745604,15204359,15269889,15400962,16646150,18284545,18350081,18415617,18481153,19333123,19398659,19464194,19529730,19595267,19660803,19988486,21823492,22347777,22413314,22740994,22872069,23199749,23789569,23855120,23920641,24051715,24248322,24313864,24379394,24838146],"movenext":[2686977,22937601],"marshallers":[3145731,8388613,12320770,14942211,18677762,23527432],"marshaller":[3145729,3211267,5767182,8388614,8454150,9502732,12320769,12517378,13959170,14942209,15007747,15204354,16777223,16842759,18677767,18743298,18808834,19464199,19529735,21823492,23527426,23592970,23855106],"member":[4521985,4587521,4718593,4784129,4849665,4980737,5046273,5177345,5242881,5373953,5439489,5505025,5570561,5832705,5898241,5963777,6094849,6160385,6225921,6291457,6356993,6553601,6619137,6684673,6881281,7143425,8388609,8585217,8650753,9699329,9764865,9961473,10027009,10092545,10158081,10223617,10354689,10420225,10485761,10551297,10682369,10813441,10878977,11468801,11534337,11599873,11665409,11730945,11796481,11862017,11927553,11993089,12058625,12124161,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18546689,18612225,18677761,18743297,18808833,18939905,19005441,19070977,19136513,19464193,19529729,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,22216705,22282241,22478849,23789569,24772609,25165825],"missing":[5570561,6684674,7143425,7405570,7471107,7536642,7602177,7667714,7733251,7798786,7929858,7995395,8060930,8126465,8192002,8257539,8323074,8388611,8519682,8585219,8650755,8716289,8781826,8847363,9109505,9175042,9240579,9306114,9371650,9699329,10485761,10682369,11075585,11468803,11534338,11599876,11665411,11730947,11927553,11993089,18874369,19202049,19267585,20447233,20512769,20578305,20643841,23265281,23592961],"methodtype":[9502725,12320769,18481158,19660807,23789573],"main":[12320769,21430273],"make":[12320769,21954561],"making":[12320770,21954561,22609921],"makes":[12320769,22609921],"mapping":[12320769,24248321],"microbenchmarks":[12451841,24969217],"multiple":[14221313,17825793,22347777],"meaning":[14221313,17825793,22347777],"maintains":[14548993,14614529,14811137,18153473,23003137,23068673,23265281],"mustinherit":[22347777,22675457,24117249],"medium":[22478850],"malformed":[24772609]} \ No newline at end of file diff --git a/doc/ref/csharp/html/fti/FTI_111.json b/doc/ref/csharp/html/fti/FTI_111.json index d6598433cd..7777fcea47 100644 --- a/doc/ref/csharp/html/fti/FTI_111.json +++ b/doc/ref/csharp/html/fti/FTI_111.json @@ -1 +1 @@ -{"occurs":[131073,2228225,6684673,22020097,23920641],"object":[131073,1769480,1835015,1900551,1966088,2031618,2097154,2228235,2293767,2359307,2424843,2490379,2555915,2621451,2949127,3014671,3080196,3211266,3276807,3342338,3407883,3473416,3538955,3604491,3670027,3735563,3801100,3866635,3932171,3997707,4063239,4128779,4194306,4456459,4718593,5373953,6094849,6160385,6225921,6291457,7405577,7471115,7536650,7667721,7733259,7798794,7929863,7995401,8060936,8192007,8257545,8323080,10223617,10354690,11468801,11534337,11599873,11665409,12320769,12713986,12779522,12845058,12910594,15269889,21495809,21561353,21626888,21692424,21757961,21823490,21889026,21954562,22020108,22085640,22151169,22347788,22544396,22609932,22675468,22806540,23330824,23396368,23461892,23527425,23592962,23658504,23724034,23855116,23920651,23986188,24051724,24117260,24182796,24248333,24313868,24444940,24510476,24576008,24641548,24707074,24903681,24969217,25034753,25100289,25231372],"override":[196609,1114113,4653057,4915201,5111809,5308417,7405569,7471105,7536641,7602177,7667713,7733249,7798785,8519681,8716289,8781825,8847361,8912899,9109505,9175041,9240577,9306113,9371649,10616833,10747905,11337731,18874369,19202049,19267585,19333121,19398657,19595265,19660801,22151169],"options":[262145,589825,1179649,1638401,2031617,5570567,5636102,5701638,5767174,6029313,6750216,6815752,6881286,7012353,9699336,10944520,12320773,13959170,14024705,14548994,14614530,14680065,14811138,15400961,16711686,17170433,18153474,18219009,20316161,21823491,21889026,22151169,22544387,23003138,23068674,23134210,23265282,24051713,25231362],"oauth2":[1703937,4521986,12255233,21430273,21495809],"obtain":[1703937,4587522,21495809],"operations":[1769473,1835009,1900545,1966081,2228225,2359297,2424833,2490369,2555905,2621441,3014657,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,4653057,4915201,5111809,5308417,12320770,21561345,21626881,21692417,21757953,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,24772609,25165825,25231362],"one":[2752513,2818049,2883585,3473409,7208961,12320769,23003137,23068673,23265281,23920641,23986177,24772609],"overrides":[3342337,4194305,8912897,11337729,23724033,24707073],"overridden":[3473410,23920642],"overload":[5636097,5701633,5767169,6422529,6488065,6750209,6815745,7471105,7536641,7733249,7798785,7995393,8060929,8257537,8323073,8519681,8585217,8650753,8978433,9043969,9568257,9633793,9961473,10027009,10092545,10158081,10485761,10551297,11010049,11075585,11141121,11206657,11272193,11599873,11665409,11796481,11862017,11927553,11993089,12058625,12124161,12517377,12582913,12648449,12713985,12779521,12845057,12910593,12976129,13041665,13107201,13172737,13238273,13303809,13369345,13434881,13500417,13565953,13631489],"optional":[6029322,6553602,6684674,6750210,6815746,7012356,9699330,10944514,11599874,12189698,12320769,24707073],"obtained":[6029313],"option":[6422529,6488065,12320769,12582914,22085635,22216706],"omit":[11468801,11534337,11599873,11665409],"objects":[12320771,22020097,23134209,24248321],"operation":[12320769,22020097,24772618],"optiontype":[12320769,17432582,22216709],"original":[14090241,17629185,22020097],"operatio":[24772609],"outofrange":[24772609]} \ No newline at end of file +{"occurs":[131073,2228225,6684673,22020097,23920641],"object":[131073,1769480,1835015,1900551,1966088,2031618,2097154,2228235,2293767,2359307,2424843,2490379,2555915,2621451,2949127,3014671,3080196,3211275,3276807,3342338,3407883,3473416,3538955,3604491,3670027,3735563,3801100,3866635,3932171,3997707,4063239,4128779,4194306,4456459,4718593,5373953,6094849,6160385,6225921,6291457,7405577,7471115,7536650,7667721,7733259,7798794,7929863,7995401,8060936,8192007,8257545,8323080,10223617,10354690,11468801,11534337,11599873,11665409,12320769,12713986,12779522,12845058,12910594,15269889,21495809,21561353,21626888,21692424,21757961,21823490,21889026,21954562,22020108,22085640,22151169,22347788,22544396,22609932,22675468,22806540,23330824,23396368,23461892,23527425,23592972,23658504,23724034,23855116,23920651,23986188,24051724,24117260,24182796,24248333,24313868,24444940,24510476,24576008,24641548,24707074,24903681,24969217,25034753,25100289,25231372],"override":[196609,1114113,4653057,4915201,5111809,5308417,7405569,7471105,7536641,7602177,7667713,7733249,7798785,8519681,8716289,8781825,8847361,8912899,9109505,9175041,9240577,9306113,9371649,10616833,10747905,11337731,18874369,19202049,19267585,19333121,19398657,19595265,19660801,22151169],"options":[262145,589825,1179649,1638401,2031617,5570567,5636102,5701638,5767174,6029313,6750216,6815752,6881286,7012353,9699336,10944520,12320773,13959170,14024705,14548994,14614530,14680065,14811138,15400961,16711686,17170433,18153474,18219009,20316161,21823491,21889026,22151169,22544387,23003138,23068674,23134210,23265282,24051713,25231362],"oauth2":[1703937,4521986,12255233,21430273,21495809],"obtain":[1703937,4587522,21495809],"operations":[1769473,1835009,1900545,1966081,2228225,2359297,2424833,2490369,2555905,2621441,3014657,3211265,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,4653057,4915201,5111809,5308417,12320770,21561345,21626881,21692417,21757953,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23592961,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,24772609,25165825,25231362],"one":[2752513,2818049,2883585,3473409,7208961,12320769,23003137,23068673,23265281,23920641,23986177,24772609],"overrides":[3342337,4194305,8912897,11337729,23724033,24707073],"overridden":[3473410,23920642],"overload":[5636097,5701633,5767169,6422529,6488065,6750209,6815745,7471105,7536641,7733249,7798785,7995393,8060929,8257537,8323073,8519681,8585217,8650753,8978433,9043969,9568257,9633793,9961473,10027009,10092545,10158081,10485761,10551297,11010049,11075585,11141121,11206657,11272193,11599873,11665409,11796481,11862017,11927553,11993089,12058625,12124161,12517377,12582913,12648449,12713985,12779521,12845057,12910593,12976129,13041665,13107201,13172737,13238273,13303809,13369345,13434881,13500417,13565953,13631489],"optional":[6029322,6553602,6684674,6750210,6815746,7012356,9699330,10944514,11599874,12189698,12320769,24707073],"obtained":[6029313],"option":[6422529,6488065,12320769,12582914,22085635,22216706],"omit":[11468801,11534337,11599873,11665409],"objects":[12320771,22020097,23134209,24248321],"operation":[12320769,22020097,24772618],"optiontype":[12320769,17432582,22216709],"original":[14090241,17629185,22020097],"operatio":[24772609],"outofrange":[24772609]} \ No newline at end of file diff --git a/doc/ref/csharp/html/fti/FTI_112.json b/doc/ref/csharp/html/fti/FTI_112.json index f8b685b9ef..fef4b54db7 100644 --- a/doc/ref/csharp/html/fti/FTI_112.json +++ b/doc/ref/csharp/html/fti/FTI_112.json @@ -1 +1 @@ -{"primaryuseragentstring":[196609,983045,22151169],"primary":[196609,983041,22151169],"propagation":[262145,1179649,3604481,6029313,7012353,9699329,22544386,24051713],"pickunused":[393217,1376261,20447233,24182785],"pass":[393217,1376257,24182785],"port":[393219,1376259,3932164,6750209,6815751,9895946,10485762,10551306,12320769,12648450,13238276,15335425,15466497,15532033,20381697,20447234,20643847,20709377,22020098,23986177,24117249,24182790,24444932],"ports":[393217,1376257,12320770,15335426,20709382,23986179,24182785,24444929],"property":[393217,1376257,14221313,14548993,14614529,14811137,15400961,15859716,15925252,15990788,16056324,16121860,16187396,16252932,16318468,16384004,16449540,16515076,16580612,16646148,16711684,16777220,16842756,16908292,16973828,17039364,17104900,17170436,17235972,17301508,17367044,17432580,17498116,17563652,17629188,17694724,17760260,17825797,17891332,17956868,18022404,18087940,18153477,18219012,18284548,18350084,18415620,18481156,18546692,18612228,18677764,18743300,18808836,18874372,18939908,19005444,19070980,19136516,19202052,19267588,19333124,19398660,19464196,19529732,19595268,19660804,19726340,19791876,19857412,19922948,19988484,20054020,20119556,20185092,20250628,20316165,20381700,20447236,20512772,20578308,20643844,20709380,20774916,20840452,20905988,20971524,21037060,21102596,21168132,21233668,21299204,21364740,22347777,23003137,23068673,23265281,24051713,24182785],"public":[655363,720899,786435,851971,917507,983043,1048579,1114115,1179651,1245187,1310723,1376259,1441795,1507331,1572867,1638403,4521987,4587523,4653059,4718595,4784131,4849667,4915203,4980739,5046275,5111811,5177347,5242883,5308419,5373955,5439491,5505027,5570563,5636099,5701635,5767171,5832707,5898243,5963779,6029315,6094851,6160387,6225923,6291459,6356995,6422531,6488067,6553603,6619139,6684675,6750211,6815747,6946819,7012355,7143427,7340035,7405571,7471107,7536643,7602179,7667715,7733251,7798787,7864323,8388611,8454147,8519683,8585219,8650755,8716291,8781827,8847363,8912899,8978435,9043971,9109507,9175043,9240579,9306115,9371651,9437187,9502723,9568259,9633795,9699331,9764867,9895939,9961475,10027011,10092547,10158083,10223619,10289155,10354691,10420227,10485763,10551299,10616835,10682371,10747907,10813443,10878979,10944515,11010051,11075587,11141123,11206659,11272195,11337731,11403267,11468803,11534339,11599875,11665411,11730947,11796483,11862019,11927555,11993091,12058627,12124163,12189699,15859715,15925251,15990787,16056323,16121859,16187395,16252931,16318467,16384003,16449539,16515075,16580611,16646147,16711683,16777219,16842755,16908291,16973827,17039363,17104899,17170435,17235971,17301507,17367043,17432579,17498115,17563651,17629187,17694723,17760259,17825795,17891331,17956867,18022403,18087939,18546691,18612227,18677763,18743299,18808835,18874371,18939907,19005443,19070979,19136515,19202051,19267587,19333123,19398659,19464195,19529731,19595267,19660803,19726339,19791875,19857411,19922947,19988483,20054019,20119555,20185091,20250627,20316163,20381699,20447235,20512771,20578307,20643843,20709379,20774915,20840451,20905987,20971523,21037059,21102595,21168131,21233667,21299203,21364739,21495811,21561347,21626883,21692419,21757955,21823491,21889027,21954563,22020099,22085635,22151171,22216707,22282243,22347779,22413315,22478851,22544387,22609923,22675459,22740995,22806531,22872067,22937603,23003139,23068675,23134211,23199747,23265283,23330819,23396355,23461891,23527427,23592963,23658499,23724035,23789571,23855107,23920644,23986179,24051715,24117251,24182787,24248323,24313859,24379395,24444931,24510467,24576004,24641540,24707075,24772611,24838147,24903683,24969219,25034755,25100291,25165827,25231363],"provides":[1769473,1835009,1900545,1966081,4653057,4915201,5111809,5308417,12255233,12320770,12386305,14352385,15466497,18022401,20381697,21430274,21561345,21626881,21692417,21757953,22609921,22675457,24117249,25100289],"pending":[1769473,1835009,1900545,1966081,2752513,2818050,2883585,4653057,4915201,5111809,5308417,7208961,7274497,21561345,21626881,21692417,21757953,23003137,23068674,23265281],"provided":[2031617,2097155,5570561,5832705,5898241,5963777,21823489,21889027],"preserved":[2031617,2097155,5570561,5832705,5898241,5963777,21823489,21889027],"perform":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"performs":[2686977,22937601],"progress":[3538945,10420225,23986177],"procedure":[3538946,10420225,10813441,12320770,23920641,23986178,24772609],"propagate":[3604481,9699329,12320769,22609921,24051713],"preceded":[4325377,11730945,24969217],"phase":[4325377,11730945,24969217],"preconditions":[4390914,11796482,11862018,11927555,11993091,12058626,12124162,12451842,13500418,13565954,13631490,25034759],"parameters":[4521985,4587521,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6094850,6160386,6225922,6291458,6356994,6422529,6488065,6553601,6684673,6750209,6815745,6881282,6946817,7012353,7143425,7208961,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388610,8454145,8519681,8585217,8650753,8781825,8847361,8978433,9043969,9175041,9240577,9306113,9371649,9502721,9568257,9633793,9699329,9764865,9895937,9961474,10027010,10092546,10158082,10289153,10354689,10485761,10551297,10682369,10944513,11075585,11141121,11206657,11272193,11403265,11468802,11534338,11599874,11665410,11730945,11796481,11862017,11927554,11993090,12058625,12124161,12189697,19267585,21561345,21626881,21692417,21757953,21823489,22413314,22740994,22872065,22937601,23003137,23068673,23265281,23592961,23855105,24379394,24838146],"param":[5570561,6684674,7143425,7405570,7471107,7536642,7667714,7733251,7798786,7929858,7995395,8060930,8192002,8257539,8323074,8388610,8519681,8585218,8650754,8781825,8847362,9175041,9240578,9306113,9371649,9699329,10485761,10682369,11075585,11468802,11534337,11599875,11665410,11730947],"propagationtoken":[6029319,14024705,17104901,21889025],"providing":[6094849,6160385,6225921,6291457],"protected":[6881283,7077891,9830403],"propagatedeadline":[7012359],"propagatecancellation":[7012359],"parent":[7012354,14024705,14286850,17104897,17891329,17956865,21889025,22544386],"propagated":[7012354,14286850,17891329,17956865,22544386],"private":[7340034,14876673,18612225,23330818],"pair":[7340033,11141121,12320769,15597570,20905986,23330818,24576002],"privatekey":[7340037,14876673,18612229,23330817],"pem":[7340034,11075585,11141121,11272193,12320769,13303809,14876674,15597569,15663105,18546689,18612225,20971521,21168129,23330819,24576002,24641537],"params":[7405569,7471105,7536641,7667713,7733249,7798785,7929857,7995393,8060929,8192001,8257537,8323073],"paramarray":[7405569,7471105,7536641,7667713,7733249,7798785,7929857,7995393,8060929,8192001,8257537,8323073],"pointed":[11010049,13303809,24576001],"place":[11010049,13303809,24576001],"proves":[11272193],"parameter":[11468801,11534337,11599873,11665409,11993089],"programming":[11468801,11534337,11599873,11665409],"paramname":[11993093],"protocol":[12320770,21954561,24248321],"possible":[12320769,22020097],"propagating":[12320770,14024705,17104897,21889025,22609922],"properties":[12320769,13697026,13762562,13828098,13893634,13959170,14024706,14090242,14155778,14221314,14286850,14352386,14417922,14483458,14548994,14614530,14680066,14745602,14811138,14876674,14942210,15007746,15073282,15138818,15204354,15269890,15335426,15400963,15466498,15532034,15597570,15663106,15728642,15794178,20316161,21561345,21626881,21692417,21757953,21823489,21889025,22020097,22085633,22347777,22544385,22609921,22675457,22806529,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23527425,23592961,23658497,23724033,23855105,23920641,23986177,24051714,24117249,24182785,24576001,24641537,24707073,25231361],"part":[12320769,24248321],"pairs":[15269889,15663105,21102593,23920641,24641537],"provide":[15269889,23920641],"peer":[15400961,20054021,24051713],"pick":[20447233],"problematic":[24772609],"permissiondenied":[24772609],"permission":[24772609],"permission_denied":[24772610],"past":[24772610],"particular":[25165825]} \ No newline at end of file +{"primaryuseragentstring":[196609,983045,22151169],"primary":[196609,983041,22151169],"propagation":[262145,1179649,3604481,6029313,7012353,9699329,22544386,24051713],"pickunused":[393217,1376261,20447233,24182785],"pass":[393217,1376257,24182785],"port":[393219,1376259,3932164,6750209,6815751,9895946,10485762,10551306,12320769,12648450,13238276,15335425,15466497,15532033,20381697,20447234,20643847,20709377,22020098,23986177,24117249,24182790,24444932],"ports":[393217,1376257,12320770,15335426,20709382,23986179,24182785,24444929],"property":[393217,1376257,14221313,14548993,14614529,14811137,15400961,15859716,15925252,15990788,16056324,16121860,16187396,16252932,16318468,16384004,16449540,16515076,16580612,16646148,16711684,16777220,16842756,16908292,16973828,17039364,17104900,17170436,17235972,17301508,17367044,17432580,17498116,17563652,17629188,17694724,17760260,17825797,17891332,17956868,18022404,18087940,18153477,18219012,18284548,18350084,18415620,18481156,18546692,18612228,18677764,18743300,18808836,18874372,18939908,19005444,19070980,19136516,19202052,19267588,19333124,19398660,19464196,19529732,19595268,19660804,19726340,19791876,19857412,19922948,19988484,20054020,20119556,20185092,20250628,20316165,20381700,20447236,20512772,20578308,20643844,20709380,20774916,20840452,20905988,20971524,21037060,21102596,21168132,21233668,21299204,21364740,22347777,23003137,23068673,23265281,24051713,24182785],"public":[655363,720899,786435,851971,917507,983043,1048579,1114115,1179651,1245187,1310723,1376259,1441795,1507331,1572867,1638403,4521987,4587523,4653059,4718595,4784131,4849667,4915203,4980739,5046275,5111811,5177347,5242883,5308419,5373955,5439491,5505027,5570563,5636099,5701635,5767171,5832707,5898243,5963779,6029315,6094851,6160387,6225923,6291459,6356995,6422531,6488067,6553603,6619139,6684675,6750211,6815747,6946819,7012355,7143427,7340035,7405571,7471107,7536643,7602179,7667715,7733251,7798787,7864323,8388611,8454147,8519683,8585219,8650755,8716291,8781827,8847363,8912899,8978435,9043971,9109507,9175043,9240579,9306115,9371651,9437187,9502723,9568259,9633795,9699331,9764867,9895939,9961475,10027011,10092547,10158083,10223619,10289155,10354691,10420227,10485763,10551299,10616835,10682371,10747907,10813443,10878979,10944515,11010051,11075587,11141123,11206659,11272195,11337731,11403267,11468803,11534339,11599875,11665411,11730947,11796483,11862019,11927555,11993091,12058627,12124163,12189699,15859715,15925251,15990787,16056323,16121859,16187395,16252931,16318467,16384003,16449539,16515075,16580611,16646147,16711683,16777219,16842755,16908291,16973827,17039363,17104899,17170435,17235971,17301507,17367043,17432579,17498115,17563651,17629187,17694723,17760259,17825795,17891331,17956867,18022403,18087939,18546691,18612227,18677763,18743299,18808835,18874371,18939907,19005443,19070979,19136515,19202051,19267587,19333123,19398659,19464195,19529731,19595267,19660803,19726339,19791875,19857411,19922947,19988483,20054019,20119555,20185091,20250627,20316163,20381699,20447235,20512771,20578307,20643843,20709379,20774915,20840451,20905987,20971523,21037059,21102595,21168131,21233667,21299203,21364739,21495811,21561347,21626883,21692419,21757955,21823491,21889027,21954563,22020099,22085635,22151171,22216707,22282243,22347779,22413315,22478851,22544387,22609923,22675459,22740995,22806531,22872067,22937603,23003139,23068675,23134211,23199747,23265283,23330819,23396355,23461891,23527427,23592963,23658499,23724035,23789571,23855107,23920644,23986179,24051715,24117251,24182787,24248323,24313859,24379395,24444931,24510467,24576004,24641540,24707075,24772611,24838147,24903683,24969219,25034755,25100291,25165827,25231363],"provides":[1769473,1835009,1900545,1966081,4653057,4915201,5111809,5308417,12255233,12320770,12386305,14352385,15466497,18022401,20381697,21430274,21561345,21626881,21692417,21757953,22609921,22675457,24117249,25100289],"pending":[1769473,1835009,1900545,1966081,2752513,2818050,2883585,4653057,4915201,5111809,5308417,7208961,7274497,21561345,21626881,21692417,21757953,23003137,23068674,23265281],"provided":[2031617,2097155,5570561,5832705,5898241,5963777,21823489,21889027],"preserved":[2031617,2097155,5570561,5832705,5898241,5963777,21823489,21889027],"perform":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3211265,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23592961,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"performs":[2686977,22937601],"progress":[3538945,10420225,23986177],"procedure":[3538946,10420225,10813441,12320770,23920641,23986178,24772609],"propagate":[3604481,9699329,12320769,22609921,24051713],"preceded":[4325377,11730945,24969217],"phase":[4325377,11730945,24969217],"preconditions":[4390914,11796482,11862018,11927555,11993091,12058626,12124162,12451842,13500418,13565954,13631490,25034759],"parameters":[4521985,4587521,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6094850,6160386,6225922,6291458,6356994,6422529,6488065,6553601,6684673,6750209,6815745,6881282,6946817,7012353,7143425,7208961,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388610,8454145,8519681,8585217,8650753,8781825,8847361,8978433,9043969,9175041,9240577,9306113,9371649,9502721,9568257,9633793,9699329,9764865,9895937,9961474,10027010,10092546,10158082,10289153,10354689,10485761,10551297,10682369,10944513,11075585,11141121,11206657,11272193,11403265,11468802,11534338,11599874,11665410,11730945,11796481,11862017,11927554,11993090,12058625,12124161,12189697,19267585,21561345,21626881,21692417,21757953,21823489,22413314,22740994,22872065,22937601,23003137,23068673,23265281,23592961,23855105,24379394,24838146],"param":[5570561,6684674,7143425,7405570,7471107,7536642,7667714,7733251,7798786,7929858,7995395,8060930,8192002,8257539,8323074,8388610,8519681,8585218,8650754,8781825,8847362,9175041,9240578,9306113,9371649,9699329,10485761,10682369,11075585,11468802,11534337,11599875,11665410,11730947],"propagationtoken":[6029319,14024705,17104901,21889025],"providing":[6094849,6160385,6225921,6291457],"protected":[6881283,7077891,9830403],"propagatedeadline":[7012359],"propagatecancellation":[7012359],"parent":[7012354,14024705,14286850,17104897,17891329,17956865,21889025,22544386],"propagated":[7012354,14286850,17891329,17956865,22544386],"private":[7340034,14876673,18612225,23330818],"pair":[7340033,11141121,12320769,15597570,20905986,23330818,24576002],"privatekey":[7340037,14876673,18612229,23330817],"pem":[7340034,11075585,11141121,11272193,12320769,13303809,14876674,15597569,15663105,18546689,18612225,20971521,21168129,23330819,24576002,24641537],"params":[7405569,7471105,7536641,7667713,7733249,7798785,7929857,7995393,8060929,8192001,8257537,8323073],"paramarray":[7405569,7471105,7536641,7667713,7733249,7798785,7929857,7995393,8060929,8192001,8257537,8323073],"pointed":[11010049,13303809,24576001],"place":[11010049,13303809,24576001],"proves":[11272193],"parameter":[11468801,11534337,11599873,11665409,11993089],"programming":[11468801,11534337,11599873,11665409],"paramname":[11993093],"protocol":[12320770,21954561,24248321],"possible":[12320769,22020097],"propagating":[12320770,14024705,17104897,21889025,22609922],"properties":[12320769,13697026,13762562,13828098,13893634,13959170,14024706,14090242,14155778,14221314,14286850,14352386,14417922,14483458,14548994,14614530,14680066,14745602,14811138,14876674,14942210,15007746,15073282,15138818,15204354,15269890,15335426,15400963,15466498,15532034,15597570,15663106,15728642,15794178,20316161,21561345,21626881,21692417,21757953,21823489,21889025,22020097,22085633,22347777,22544385,22609921,22675457,22806529,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23527425,23592961,23658497,23724033,23855105,23920641,23986177,24051714,24117249,24182785,24576001,24641537,24707073,25231361],"part":[12320769,24248321],"pairs":[15269889,15663105,21102593,23920641,24641537],"provide":[15269889,23920641],"peer":[15400961,20054021,24051713],"pick":[20447233],"problematic":[24772609],"permissiondenied":[24772609],"permission":[24772609],"permission_denied":[24772610],"past":[24772610],"particular":[25165825]} \ No newline at end of file diff --git a/doc/ref/csharp/html/fti/FTI_113.json b/doc/ref/csharp/html/fti/FTI_113.json index 50cc318bdf..0a336d9f2d 100644 --- a/doc/ref/csharp/html/fti/FTI_113.json +++ b/doc/ref/csharp/html/fti/FTI_113.json @@ -1 +1 @@ -{"qualified":[2031617,2097153,3211265,5767169,14745601,15204353,18284545,19333121,21823489,21889025,23199745,23592961,23855105],"quota":[24772609]} \ No newline at end of file +{"qualified":[2031617,2097153,5767169,14745601,15204353,18284545,19333121,21823489,21889025,23199745,23855105],"quota":[24772609]} \ No newline at end of file diff --git a/doc/ref/csharp/html/fti/FTI_114.json b/doc/ref/csharp/html/fti/FTI_114.json index eb0e8484e8..b2f9e361e1 100644 --- a/doc/ref/csharp/html/fti/FTI_114.json +++ b/doc/ref/csharp/html/fti/FTI_114.json @@ -1 +1 @@ -{"redirected":[1],"rpcexception":[131075,3473411,9568263,9633799,12320770,13107206,15269891,19726338,23920652],"reference":[131073,196609,262145,327681,393217,458753,524289,589825,655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572865,1638401,1703937,1769473,1835009,1900545,1966081,2031617,2097153,2162689,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2686977,2752513,2818049,2883585,2949121,3014657,3080193,3145729,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4259841,4325377,4390915,4456449,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6094849,6160385,6225921,6291457,6356993,6422529,6488065,6553601,6619137,6684673,6750209,6815745,6881281,6946817,7012353,7077889,7143425,7208961,7274497,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7864321,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388609,8454145,8519681,8585217,8650753,8716289,8781825,8847361,8912897,8978433,9043969,9109505,9175041,9240577,9306113,9371649,9437185,9502721,9568257,9633793,9699329,9764865,9830401,9895937,9961473,10027009,10092545,10158081,10223617,10289153,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11337729,11403265,11468801,11534337,11599873,11665409,11730945,11796481,11862017,11927560,11993096,12058625,12124161,12189697,12320769,12517377,12582913,12648449,12713985,12779521,12845057,12910593,12976129,13041665,13107201,13172737,13238273,13303809,13369345,13434881,13500417,13565955,13631489,13697025,13762561,13828097,13893633,13959169,14024705,14090241,14155777,14221313,14286849,14352385,14417921,14483457,14548993,14614529,14680065,14745601,14811137,14876673,14942209,15007745,15073281,15138817,15204353,15269889,15335425,15400961,15466497,15532033,15597569,15663105,15728641,15794177,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18153473,18219009,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19267585,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020097,22085633,22151169,22216705,22282241,22347777,22413313,22478849,22544385,22609921,22675457,22740993,22806529,22872065,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23789569,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24379393,24444929,24510465,24576001,24641537,24707073,24772609,24838145,24903681,24969217,25034755,25100289,25165825,25231361],"receive":[196609,917505,22151169],"read":[327681,1310721,1835009,1900545,2686977,4259841,4915201,5111809,11534337,12320769,13762561,13828097,16187393,16318465,21626882,21692418,22937602,23658497,24903681],"result":[458754,1441793,1507329,1769474,1835009,1900545,1966082,4653058,4915201,5111809,5308418,12320770,13697025,13893633,14352385,15466497,15925249,16384001,18022401,20381697,21561347,21626881,21692417,21757955,22675457,24117249,24707075,24772609],"rpc":[458754,1441793,1507329,2228226,6553602,12320770,15400965,19857409,19922945,19988481,20185089,20250625,21954561,22020098,24051717,24707075],"readonly":[1179650,1310722,1441794,1507330,1638402,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17891329,17956865,18022401,18087937,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737],"request":[1769473,1835009,1966081,2162689,2228225,3866625,4653057,4915201,5308417,5767169,6029313,6094849,6160386,6225923,6291458,6356994,6553601,6881281,9502721,9961473,10027009,10092545,10158082,12320771,13172737,14221313,15204353,17760257,19464193,21561346,21626882,21757954,21823489,21954561,22020097,22347777,22413313,22740993,23658498,23789571,23855106,24313857,24379398,24772609,24838150],"received":[1769473,1966081,4653057,5308417,21561345,21757953,23789571,24772609],"requests":[1769473,1835009,1900545,1966081,2162690,3538946,4653057,4915201,5111809,5308417,6094849,6160385,10420225,10813441,13697025,13762561,13959169,15859713,16056321,16777217,21561346,21626882,21692417,21757953,21823489,21954562,23789569,23986178],"resources":[1769473,1835009,1900545,1966081,2228226,2359297,2424833,2490369,2555905,2621441,2686977,3014657,3407873,3473409,3538946,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,4653057,4915201,5111809,5308417,6619137,10813441,21561345,21626881,21692417,21757953,22020098,22347777,22544385,22609921,22675457,22806529,22937601,23396353,23855105,23920641,23986178,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"released":[1769473,1835009,1900545,1966081,4653057,4915201,5111809,5308417,21561345,21626881,21692417,21757953],"returns":[1769473,1835009,1900545,1966081,2031619,2097157,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014658,3080193,3211266,3276801,3342338,3407873,3473410,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194306,4456449,5570561,5832705,5898241,5963777,7602177,8126465,8912897,11337729,14352385,14942209,15138817,15466497,18022401,18677761,18939905,20381697,21561345,21626881,21692417,21757953,21823491,21889029,22020097,22085633,22347777,22544385,22609921,22675458,22806529,23330817,23396354,23461889,23527425,23592962,23658497,23724035,23855105,23920642,23986177,24051713,24117250,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707074,25231361],"represents":[1769473,1835009,1900545,1966081,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3276801,3342337,3407873,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4456449,8912897,11337729,12320770,21561345,21626881,21692417,21757953,22020098,22085633,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23658497,23724033,23855105,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707074,25231361],"response":[1835009,1900545,2162690,3604484,3866625,4915201,5111809,5767169,6094851,6160386,6225922,6291458,6356994,6881281,9502721,9764870,9961473,10027009,10092545,10158082,12320772,13172737,13697025,13762561,13828097,13893633,15204353,15400961,15990785,16121857,16252929,16449537,19529729,20316161,21561346,21626883,21692419,21757955,21823489,21954562,22413313,22740993,23658499,23789570,23855106,24051717,24313857,24379393,24772609,24838145],"responds":[2162691,6094849,6160385,6225921,21954563],"responses":[2162690,6160385,6225921,13762561,13828097,13959169,16187393,16318465,16842753,21626881,21692417,21823489,21954562,23789570],"remote":[2162690,6291457,6356993,6946817,12320777,14090241,15400961,17498113,20054017,21954562,22020099,23199745,23658499,23855105,23920641,24051713,24772609],"requesting":[2228225,6553601,22020097],"returned":[2228227,3538946,6553601,6684674,10420225,10813441,22020099,23986178,24772611],"ready":[2228225,6553601,22020097,22282242],"reached":[2228226,6553601,6684673,22020098],"requires":[2228225,6553601,22020097],"reclaimed":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"releasing":[2686977,22937601],"resetting":[2686977,22937601],"reads":[2686978,4259842,11468801,11534337,22937602,24903682],"remove":[3276801,9306121,23658497],"removeat":[3276801,9371657,23658497],"root":[3473409,11075585,11141121,11206657,11272193,13303809,13369345,15597569,15663105,20971521,21168129,23920641,24576002,24641538],"runtime":[3473409,23920641],"representation":[3473409,12320769,15269889,23199745,23920642],"return":[3932162,4521985,4587521,4718593,4784129,4849665,4980737,5046273,5177345,5242881,5373953,5439489,5505025,5570561,5832705,5898241,5963777,6094849,6160385,6225921,6291457,6356993,6553601,6619137,6684673,6881281,7208961,7274497,7602177,8126465,8388609,8781825,8912897,9109505,9175041,9306113,9699329,9764865,9895937,9961473,10027009,10092545,10158081,10223617,10354689,10420225,10485762,10551298,10616833,10747905,10813441,11337729,11468801,11534337,11599873,11665409,11927553,11993089,12320772,13238274,21561345,21626881,21692417,21757953,22413313,22740993,24379393,24444930,24772609,24838145],"register":[3997697,10682369,14221313,15335426,17760257,20709377,20774913,22347777,23986178,24510465],"runbenchmark":[4325377,11730952,24969217],"runs":[4325377,11730945,24969217],"requestmarshaller":[5767173,9502725,13959169,15204353,16777221,19464197,21823489,23855105],"responsemarshaller":[5767173,9502725,13959169,15204353,16842757,19529733,21823489,23855105],"ref":[6094850,6160386,6225922,6291458,6356994,6881282,9961474,10027010,10092546,10158082,11468801,11534337,11599873,11665409,21495809,21561345,21626881,21692417,21757953,21954561,22020097,22085633,22151169,22347777,22413314,22544385,22609921,22675457,22740994,22806529,23330817,23396353,23527425,23658497,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24379394,24444929,24510465,24576001,24641537,24838146,24903681,24969217,25034753,25100289,25231361],"reponse":[6160385],"req":[6225925,6291461,6356997],"resulting":[9568257,9633793,12320770,15269889,19726337,23658497,23920642],"responseheaders":[9764869],"roots":[11010049,13303809,24576001],"rootcertificates":[11075590,11141125,11272198,15597569,15663105,20971525,21168133,24576001,24641537],"rejected":[11272193,24772609],"registered":[12255233,21495809],"representing":[12320769,21430273],"reuse":[12320770,22020098],"redirect":[12386305,21430273],"requeststream":[13697025,13762561,15859717,16056325,21561345,21626881,22413317,22740997],"responseasync":[13697025,13893633,15925253,16384005,21561345,21757953],"responseheadersasync":[13697025,13762561,13828097,13893633,15990789,16121861,16252933,16449541,21561345,21626881,21692417,21757953],"responsestream":[13762561,13828097,16187397,16318469,21626881,21692417,22740997,24379397],"resolvedtarget":[14090241,17498117,22020097],"resolved":[14090241,17498113,22020097],"requestheaders":[15400961,20119557,24051713],"responsetrailers":[15400961,20185093,24051713],"recover":[22282242],"raised":[24772609],"regardless":[24772609],"requested":[24772609],"rejections":[24772609],"resource":[24772610],"resource_exhausted":[24772609],"resourceexhausted":[24772609],"required":[24772609],"rmdir":[24772609],"range":[24772609],"reading":[24772609],"retrying":[24772609]} \ No newline at end of file +{"redirected":[1],"rpcexception":[131075,3473411,9568263,9633799,12320770,13107206,15269891,19726338,23920652],"reference":[131073,196609,262145,327681,393217,458753,524289,589825,655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572865,1638401,1703937,1769473,1835009,1900545,1966081,2031617,2097153,2162689,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2686977,2752513,2818049,2883585,2949121,3014657,3080193,3145729,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4259841,4325377,4390915,4456449,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6094849,6160385,6225921,6291457,6356993,6422529,6488065,6553601,6619137,6684673,6750209,6815745,6881281,6946817,7012353,7077889,7143425,7208961,7274497,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7864321,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388609,8454145,8519681,8585217,8650753,8716289,8781825,8847361,8912897,8978433,9043969,9109505,9175041,9240577,9306113,9371649,9437185,9502721,9568257,9633793,9699329,9764865,9830401,9895937,9961473,10027009,10092545,10158081,10223617,10289153,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11337729,11403265,11468801,11534337,11599873,11665409,11730945,11796481,11862017,11927560,11993096,12058625,12124161,12189697,12320769,12517377,12582913,12648449,12713985,12779521,12845057,12910593,12976129,13041665,13107201,13172737,13238273,13303809,13369345,13434881,13500417,13565955,13631489,13697025,13762561,13828097,13893633,13959169,14024705,14090241,14155777,14221313,14286849,14352385,14417921,14483457,14548993,14614529,14680065,14745601,14811137,14876673,14942209,15007745,15073281,15138817,15204353,15269889,15335425,15400961,15466497,15532033,15597569,15663105,15728641,15794177,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18153473,18219009,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19267585,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020097,22085633,22151169,22216705,22282241,22347777,22413313,22478849,22544385,22609921,22675457,22740993,22806529,22872065,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23789569,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24379393,24444929,24510465,24576001,24641537,24707073,24772609,24838145,24903681,24969217,25034755,25100289,25165825,25231361],"receive":[196609,917505,22151169],"read":[327681,1310721,1835009,1900545,2686977,4259841,4915201,5111809,11534337,12320769,13762561,13828097,16187393,16318465,21626882,21692418,22937602,23658497,24903681],"result":[458754,1441793,1507329,1769474,1835009,1900545,1966082,4653058,4915201,5111809,5308418,12320770,13697025,13893633,14352385,15466497,15925249,16384001,18022401,20381697,21561347,21626881,21692417,21757955,22675457,24117249,24707075,24772609],"rpc":[458754,1441793,1507329,2228226,6553602,12320770,15400965,19857409,19922945,19988481,20185089,20250625,21954561,22020098,24051717,24707075],"readonly":[1179650,1310722,1441794,1507330,1638402,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17891329,17956865,18022401,18087937,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737],"request":[1769473,1835009,1966081,2162689,2228225,3866625,4653057,4915201,5308417,5767169,6029313,6094849,6160386,6225923,6291458,6356994,6553601,6881281,9502721,9961473,10027009,10092545,10158082,12320771,13172737,14221313,15204353,17760257,19464193,21561346,21626882,21757954,21823489,21954561,22020097,22347777,22413313,22740993,23658498,23789571,23855106,24313857,24379398,24772609,24838150],"received":[1769473,1966081,4653057,5308417,21561345,21757953,23789571,24772609],"requests":[1769473,1835009,1900545,1966081,2162690,3538946,4653057,4915201,5111809,5308417,6094849,6160385,10420225,10813441,13697025,13762561,13959169,15859713,16056321,16777217,21561346,21626882,21692417,21757953,21823489,21954562,23789569,23986178],"resources":[1769473,1835009,1900545,1966081,2228226,2359297,2424833,2490369,2555905,2621441,2686977,3014657,3211265,3407873,3473409,3538946,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,4653057,4915201,5111809,5308417,6619137,10813441,21561345,21626881,21692417,21757953,22020098,22347777,22544385,22609921,22675457,22806529,22937601,23396353,23592961,23855105,23920641,23986178,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"released":[1769473,1835009,1900545,1966081,4653057,4915201,5111809,5308417,21561345,21626881,21692417,21757953],"returns":[1769473,1835009,1900545,1966081,2031619,2097157,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014658,3080193,3211265,3276801,3342338,3407873,3473410,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194306,4456449,5570561,5832705,5898241,5963777,7602177,8126465,8912897,11337729,14352385,14942209,15138817,15466497,18022401,18677761,18939905,20381697,21561345,21626881,21692417,21757953,21823491,21889029,22020097,22085633,22347777,22544385,22609921,22675458,22806529,23330817,23396354,23461889,23527425,23592961,23658497,23724035,23855105,23920642,23986177,24051713,24117250,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707074,25231361],"represents":[1769473,1835009,1900545,1966081,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3342337,3407873,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4456449,8912897,11337729,12320770,21561345,21626881,21692417,21757953,22020098,22085633,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23592961,23658497,23724033,23855105,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707074,25231361],"response":[1835009,1900545,2162690,3604484,3866625,4915201,5111809,5767169,6094851,6160386,6225922,6291458,6356994,6881281,9502721,9764870,9961473,10027009,10092545,10158082,12320772,13172737,13697025,13762561,13828097,13893633,15204353,15400961,15990785,16121857,16252929,16449537,19529729,20316161,21561346,21626883,21692419,21757955,21823489,21954562,22413313,22740993,23658499,23789570,23855106,24051717,24313857,24379393,24772609,24838145],"responds":[2162691,6094849,6160385,6225921,21954563],"responses":[2162690,6160385,6225921,13762561,13828097,13959169,16187393,16318465,16842753,21626881,21692417,21823489,21954562,23789570],"remote":[2162690,6291457,6356993,6946817,12320777,14090241,15400961,17498113,20054017,21954562,22020099,23199745,23658499,23855105,23920641,24051713,24772609],"requesting":[2228225,6553601,22020097],"returned":[2228227,3538946,6553601,6684674,10420225,10813441,22020099,23986178,24772611],"ready":[2228225,6553601,22020097,22282242],"reached":[2228226,6553601,6684673,22020098],"requires":[2228225,6553601,22020097],"reclaimed":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3211265,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23592961,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"releasing":[2686977,22937601],"resetting":[2686977,22937601],"reads":[2686978,4259842,11468801,11534337,22937602,24903682],"remove":[3276801,9306121,23658497],"removeat":[3276801,9371657,23658497],"root":[3473409,11075585,11141121,11206657,11272193,13303809,13369345,15597569,15663105,20971521,21168129,23920641,24576002,24641538],"runtime":[3473409,23920641],"representation":[3473409,12320769,15269889,23199745,23920642],"return":[3932162,4521985,4587521,4718593,4784129,4849665,4980737,5046273,5177345,5242881,5373953,5439489,5505025,5570561,5832705,5898241,5963777,6094849,6160385,6225921,6291457,6356993,6553601,6619137,6684673,6881281,7208961,7274497,7602177,8126465,8388609,8781825,8912897,9109505,9175041,9306113,9699329,9764865,9895937,9961473,10027009,10092545,10158081,10223617,10354689,10420225,10485762,10551298,10616833,10747905,10813441,11337729,11468801,11534337,11599873,11665409,11927553,11993089,12320772,13238274,21561345,21626881,21692417,21757953,22413313,22740993,24379393,24444930,24772609,24838145],"register":[3997697,10682369,14221313,15335426,17760257,20709377,20774913,22347777,23986178,24510465],"runbenchmark":[4325377,11730952,24969217],"runs":[4325377,11730945,24969217],"requestmarshaller":[5767173,9502725,13959169,15204353,16777221,19464197,21823489,23855105],"responsemarshaller":[5767173,9502725,13959169,15204353,16842757,19529733,21823489,23855105],"ref":[6094850,6160386,6225922,6291458,6356994,6881282,9961474,10027010,10092546,10158082,11468801,11534337,11599873,11665409,21495809,21561345,21626881,21692417,21757953,21954561,22020097,22085633,22151169,22347777,22413314,22544385,22609921,22675457,22740994,22806529,23330817,23396353,23527425,23592961,23658497,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24379394,24444929,24510465,24576001,24641537,24838146,24903681,24969217,25034753,25100289,25231361],"reponse":[6160385],"req":[6225925,6291461,6356997],"resulting":[9568257,9633793,12320770,15269889,19726337,23658497,23920642],"responseheaders":[9764869],"roots":[11010049,13303809,24576001],"rootcertificates":[11075590,11141125,11272198,15597569,15663105,20971525,21168133,24576001,24641537],"rejected":[11272193,24772609],"registered":[12255233,21495809],"representing":[12320769,21430273],"reuse":[12320770,22020098],"redirect":[12386305,21430273],"requeststream":[13697025,13762561,15859717,16056325,21561345,21626881,22413317,22740997],"responseasync":[13697025,13893633,15925253,16384005,21561345,21757953],"responseheadersasync":[13697025,13762561,13828097,13893633,15990789,16121861,16252933,16449541,21561345,21626881,21692417,21757953],"responsestream":[13762561,13828097,16187397,16318469,21626881,21692417,22740997,24379397],"resolvedtarget":[14090241,17498117,22020097],"resolved":[14090241,17498113,22020097],"requestheaders":[15400961,20119557,24051713],"responsetrailers":[15400961,20185093,24051713],"recover":[22282242],"raised":[24772609],"regardless":[24772609],"requested":[24772609],"rejections":[24772609],"resource":[24772610],"resource_exhausted":[24772609],"resourceexhausted":[24772609],"required":[24772609],"rmdir":[24772609],"range":[24772609],"reading":[24772609],"retrying":[24772609]} \ No newline at end of file diff --git a/doc/ref/csharp/html/fti/FTI_115.json b/doc/ref/csharp/html/fti/FTI_115.json index 37245fd262..f812ee6d1c 100644 --- a/doc/ref/csharp/html/fti/FTI_115.json +++ b/doc/ref/csharp/html/fti/FTI_115.json @@ -1 +1 @@ -{"search":[65537],"sort":[65537],"serializeobjectstate":[131073,23920641],"serialized":[131074,23920642],"state":[131073,2228227,6553602,6684673,12320769,14090242,17563654,22020101,22282241,23920641,24772611],"stats":[196609,655361,22151169],"sequence":[196609,786433,22151169],"streams":[196609,851969,6160385,22151169],"start":[196609,983041,3538945,3932161,3997697,10485761,10682369,10878981,13238273,22151169,23986177,24444929,24510465],"secondaryuseragentstring":[196609,1048581,22151169],"secondary":[196609,1048577,22151169],"ssltargetnameoverride":[196609,1114117,22151169],"ssl":[196609,1114113,11010049,11075585,11141121,11206657,11272193,12320770,13303811,13369346,22151169,24576004,24641539],"suffix":[327681,1245185,8978433,9043969,23658497],"serverport":[393219,1376258,3735555,3932161,9895941,10485773,10616838,12320769,13238273,15532035,20447235,20512771,20578307,20643843,24182792,24444933],"server":[393218,1376258,2162693,3538950,3866625,3932166,3997700,6094849,6160385,6225923,9895938,10092545,10420227,10485765,10551300,10616834,10682373,10747906,10813443,10878979,10944518,11141121,11206657,11272193,12320793,13172737,13238277,13369346,14221313,14745601,15204353,15335432,15466497,15597569,17825793,18284545,19333121,20381697,20447234,20512769,20709386,20774922,20840451,20971521,21430273,21692417,21954565,22347777,22413313,22609922,22740993,23199745,23265281,23658498,23789572,23855105,23986196,24051713,24117250,24182788,24248321,24313857,24379394,24444936,24510469,24576001,24641539,24772609,24838145],"status":[458755,1441799,1507335,1769473,1835009,1900545,1966081,4194308,4784134,4980742,5177350,5439494,9568269,9633805,11337731,11403271,12320772,13107204,15269890,15400962,15728644,19726348,20250637,21233666,21299203,21561345,21626881,21692417,21757953,23658497,23920647,24051714,24707082,24772610],"statuscode":[458754,1441793,1507329,11403274,12320770,15728641,21299211,24707076,24772613],"successful":[458753,1507329,24707073,24772609],"structure":[458753,1441793,1507329,2031617,2097153,3211265,3342337,4194305,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,8454145,8912897,8978433,9043969,11337729,11403265,12320769,12517377,13041665,13959169,14024705,15007745,15138817,15728641,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,18743297,18808833,18939905,19005441,19070977,19136513,21233665,21299201,21823490,21889026,23592962,23724034,24707074],"syntax":[655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572865,1638401,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6094849,6160385,6225921,6291457,6356993,6422529,6488065,6553601,6619137,6684673,6750209,6815745,6881281,6946817,7012353,7077889,7143425,7208961,7274497,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7864321,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388609,8454145,8519681,8585217,8650753,8716289,8781825,8847361,8912897,8978433,9043969,9109505,9175041,9240577,9306113,9371649,9437185,9502721,9568257,9633793,9699329,9764865,9830401,9895937,9961473,10027009,10092545,10158081,10223617,10289153,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11337729,11403265,11468802,11534338,11599874,11665410,11730945,11796481,11862017,11927553,11993089,12058625,12124161,12189697,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18153473,18219009,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19267585,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020097,22085633,22151169,22216705,22282241,22347777,22413313,22478849,22544385,22609921,22675457,22740993,22806529,22872065,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23789569,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24379393,24444929,24510465,24576001,24641537,24707073,24772609,24838145,24903681,24969217,25034753,25100289,25165825,25231361],"string":[655365,720901,786437,851973,917509,983045,1048581,1114117,1245189,1572869,1769473,1835009,1900545,1966081,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014661,3080196,3276804,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932162,3997697,4063233,4128769,4194305,4390915,4456449,4521989,5701638,5767180,6422534,6488078,6750214,6815750,7340042,7405577,7471115,7536650,7667721,7733259,7798794,7929863,7995401,8060936,8192007,8257545,8323080,8585225,8650770,8912903,8978438,9043981,9502730,9633798,9895941,10289157,10354693,10551302,11075592,11141127,11272198,11337735,11403269,11862022,11993095,12124166,12320769,12517379,12582916,12648450,12713986,12779522,12845058,12910594,12976131,13041667,13107201,13238273,13303811,13369345,13500417,13565953,13631489,14155777,14942209,15138817,15269889,16580614,16646150,17301510,17367047,17498118,17629190,17825799,18284550,18350086,18415622,18546694,18612230,18677767,19005446,19070983,19333127,19398663,19595271,19922950,19988486,20054022,20578310,20971526,21168134,21233670,21561345,21626881,21692417,21757953,21823491,22020099,22085638,22216706,22347777,22544385,22609921,22675457,22806529,22872069,23330817,23396357,23461892,23527425,23658500,23724037,23855105,23920643,23986177,24051713,24117249,24182785,24248321,24313857,24444930,24510465,24576004,24641538,24707074,25034755,25231361],"static":[655361,720897,786433,851969,917505,983041,1048577,1114113,1179651,1245185,1310723,1376257,1441795,1507331,1572865,1638403,4521987,4587523,6094851,6160387,6225923,6291459,6356995,7143427,8388611,10354691,11468803,11534339,11599875,11665411,11730947,11796483,11862019,11927555,11993091,12058627,12124163,18022403,18087939,18677763,20381699,21495809,21954561,22151169,23527425,24903681,24969217,25034753,25100289],"shared":[1179649,1310721,1441793,1507329,1638401,4521985,4587521,6094849,6160385,6225921,6291457,6356993,7143425,8388609,10354689,11468801,11534337,11599873,11665409,11730945,11796481,11862017,11927553,11993089,12058625,12124161,18022401,18087937,18677761,20381697],"stream":[1769473,1835010,1900545,1966081,2162693,2686978,2818051,2883585,4259845,4653057,4915202,5111809,5308417,6094849,6160387,6225922,7274497,11468801,11534337,11599874,11665409,12320772,13434883,13697025,13762562,13828097,15859713,16056321,16187393,16318465,21561346,21626884,21692418,21757953,21954565,22937603,23003137,23068676,23265282,23789571,24903685,25165825],"specified":[1769473,1835009,1900545,1966081,2031617,2097153,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014658,3080193,3145729,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4456449,7602177,8126465,8388609,12320769,12386305,21430273,21561345,21626881,21692417,21757953,21823489,21889025,22020097,22085634,22347777,22544385,22609921,22675457,22806529,23330817,23396354,23461889,23527425,23592961,23658497,23724033,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707073,24772610,25231361],"serves":[1769473,1835009,1900545,1966081,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3276801,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4456449,21561345,21626881,21692417,21757953,22020097,22085633,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23658497,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,25231361],"set":[2031617,2097155,5570561,5832705,5898241,5963777,7012354,12255233,14221314,14548993,14614529,14811137,17760260,17825798,18153477,18219012,19267589,20250628,20316164,21430273,21823489,21889027,22347778,23003137,23068673,23265281],"streaming":[2162694,3866627,6094850,6160386,6225922,9961473,10027009,10092545,12320774,12451841,13172739,13697025,13762562,13828097,15400961,15859713,16056321,16187393,16318465,20316161,21561346,21626883,21692418,21954566,22413313,22740993,24051713,24313859,24379393,24903681],"scenario":[2162691,6094849,6160385,6225921,21954563],"sends":[2162691,3604482,6094849,6160385,6225921,9764866,21954563,24051714],"single":[2162689,2752513,2818049,2883585,3866626,6094849,7208961,10158082,12320772,13172738,14221313,17825793,21757954,21954561,22020097,22347777,23003137,23068673,23265281,23789572,23986177,24313858],"sending":[2162689,6160385,21954561],"simple":[2162690,4325377,6291457,6356993,11730945,21954562,24969217],"starting":[2228226,6553602,22020098],"shallow":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"shutdownasync":[2228225,3538945,6619141,10813445,22020097,23986177],"setlogger":[2621441,7143430,22806529],"sets":[2621441,3473409,7143425,14680065,15269891,18219009,22806529,23134209,23920644],"severity":[3014662,3080198,7405569,7471105,7536641,7667713,7733249,7798785,7929857,7995393,8060929,8192001,8257537,8323073,12713986,12779522,12845058,12910594,23396358,23461894],"serializer":[3145729,8388615,8454149,15007746,18808838,23527425,23592962],"subsequent":[3473409,14548993,14614529,14811137,18153473,23003137,23068673,23265281,23920641],"serializationinfo":[3473409,23920641],"shutdown":[3538948,10420226,10813442,12320769,22806529,23986180],"serviced":[3538945,10813441,23986177],"starts":[3538945,10878977,23986177],"servercallcontext":[3604483,6029313,9699331,9764866,12320770,15400963,19791874,19857410,19922946,19988482,20054018,20119554,20185090,20250626,20316162,22413317,22740997,23134209,24051719,24379397,24838149],"servercredentials":[3670019,3932161,9830406,9895941,10551302,12320769,13238273,15466499,20381704,20512774,24117257,24444929,24641541],"serverservicedefinition":[3801092,3866627,9961479,10027015,10092551,10158087,10223625,10289154,10354696,10682374,10747910,12320772,13172737,24248329,24313862,24510468],"serverstreamingservermethod":[3866625,10092550,12320769,13172737,24313857,24379397],"serverportcollection":[3932163,10485763,10551298,10616834,12320769,13238274,20709382,24444935],"servicedefinitioncollection":[3997699,10682371,10747906,12320769,20774918,24510471],"service":[3997698,9502721,10289153,10354689,10682370,12320770,14745601,15204353,15335425,18415617,19595265,20774913,23199745,23855105,23986177,24248321,24510467,24772610],"sslcredentials":[4063235,11010054,11075591,11141126,12320769,13303813,15597571,20905986,20971522,22675457,24576010],"sslservercredentials":[4128771,11206662,11272198,12320769,13369348,15663107,21037058,21102594,21168130,24117249,24641545],"system":[4521985,5701633,5767170,5832705,5898241,6029314,6422530,6488066,6553601,6684677,6750210,6815747,7012354,7340034,7405574,7471116,7536646,7667718,7733260,7798790,7929862,7995404,8060934,8192006,8257548,8323078,8388622,8454146,8585224,8650760,8847364,8978434,9043970,9240580,9371651,9502722,9633793,9895938,10289153,10354689,10551298,10944513,11075586,11141121,11206657,11272195,11403265,11468807,11599882,11665412,11730956,11796481,11862018,11993090,12058625,12124162,12386305,19267586,21495809,21561345,21626881,21692417,21757953,21954561,22020097,22085633,22151169,22347777,22544385,22609921,22675457,22806529,22872065,23330817,23396354,23527425,23658497,23855105,23920642,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24772613,24903681,24969217,25034753,25100289,25231361],"sub":[4653057,4915201,5111809,5308417,5636097,5701633,5767169,6029313,6422529,6488065,6750209,6815745,6946817,7012353,7077889,7143425,7340033,7405569,7471105,7536641,7667713,7733249,7798785,7864321,7929857,7995393,8060929,8192001,8257537,8323073,8454145,8519681,8585217,8650753,8716289,8847361,8978433,9043969,9240577,9371649,9437185,9502721,9568257,9633793,9830401,9895937,10289153,10682369,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11403265,11730945,11796481,11862017,12058625,12124161,12189697,22872065],"sealed":[4653057,4915201,5111809,5308417,7405569,7471105,7536641,7602177,7667713,7733249,7798785,8519681,8716289,8781825,8847361,9109505,9175041,9240577,9306113,9371649,10616833,10747905,18874369,19202049,19267586,19333121,19398657,19595265,19660801,21495809,21561346,21626882,21692418,21757954,21954561,22085634,22151169,23330818,23527425,23658498,24576002,24903681,24969217,25034753,25100289],"struct":[5636097,5701633,5767169,6029313,6094850,6160386,6225922,6291458,6356994,6881282,8978433,9043969,9961474,10027010,10092546,10158082,11468801,11534337,11599873,11665409,12517379,13041666,21823493,21889027,23592962,23724036,24707074],"sent":[6029313,12320773,15400961,20119553,23658501,23789571,24051713],"stringvalue":[6488069,14155777,17367045,22085633],"specific":[6750209,6815745,7864321,12648450,15269889,22020098,23396353,23920641],"secure":[6750210,6815745,9895937,10551297,12320769,12648449,22020097,22675457],"serialize":[8454145,13959169,16777217,21823489],"summary":[8519681,8585217,8650753,8716289,8781825,8847361,9109505,9175041,9240577,9306113,9371649,18874369,19202049,19267585,20447233,20512769,20578305,20643841],"servicename":[9502725,10289157,10354693,14745601,15204353,18415621,19595271,23199745,23855105],"send":[9764865,13697025,13762561,14024705,15400962,15859713,16056321,17039361,20185089,20250625,21561345,21626881,21889025,24051714],"servicedefinition":[10682374],"streamreader":[11468806,11534342],"streamwriter":[11599878,11665414],"stubs":[12255233,12320769,21495809,22347777],"servers":[12320769,22020097],"supported":[12320770,22151169,23789569,24772609],"situations":[12320769,22609921],"sense":[12320769,22609921],"supports":[12320769,14221313,17825793,22347777,23658497],"services":[12320769,15335426,20774918,23986179],"structures":[12320769],"serializing":[12320769,23592961],"sharing":[12320769,23134209],"simplify":[12451842,24903681,25034753],"started":[14221313,15335426,17760257,20709377,20774913,22347777,23986178],"served":[14221313,17825793,22347777],"security":[14352385,15466497,18022401,20381697,22675457,24117249],"stringmarshaller":[14942209,18677765,23527425],"source":[15269889,23920641],"stacktrace":[15269889,23920641],"stack":[15269889,23920641],"shutdowntask":[15335425,20840453,23986177],"signals":[15400961,19791873,24051713],"setting":[15400961,20316161,24051713],"success":[15728641,21299201,24707073,24772609],"sealedattribute":[21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22085633,22151169,23330817,23527425,23592961,23658497,23724033,24576001,24707073,24903681,24969217,25034753,25100289],"serverstreaming":[23789569],"simultaneously":[23789569],"space":[24772612],"successfully":[24772609],"sequencer":[24772609],"seeking":[24772609]} \ No newline at end of file +{"search":[65537],"sort":[65537],"serializeobjectstate":[131073,23920641],"serialized":[131074,23920642],"state":[131073,2228227,6553602,6684673,12320769,14090242,17563654,22020101,22282241,23920641,24772611],"stats":[196609,655361,22151169],"sequence":[196609,786433,22151169],"streams":[196609,851969,6160385,22151169],"start":[196609,983041,3538945,3932161,3997697,10485761,10682369,10878981,13238273,22151169,23986177,24444929,24510465],"secondaryuseragentstring":[196609,1048581,22151169],"secondary":[196609,1048577,22151169],"ssltargetnameoverride":[196609,1114117,22151169],"ssl":[196609,1114113,11010049,11075585,11141121,11206657,11272193,12320770,13303811,13369346,22151169,24576004,24641539],"suffix":[327681,1245185,8978433,9043969,23658497],"serverport":[393219,1376258,3735555,3932161,9895941,10485773,10616838,12320769,13238273,15532035,20447235,20512771,20578307,20643843,24182792,24444933],"server":[393218,1376258,2162693,3538950,3866625,3932166,3997700,6094849,6160385,6225923,9895938,10092545,10420227,10485765,10551300,10616834,10682373,10747906,10813443,10878979,10944518,11141121,11206657,11272193,12320793,13172737,13238277,13369346,14221313,14745601,15204353,15335432,15466497,15597569,17825793,18284545,19333121,20381697,20447234,20512769,20709386,20774922,20840451,20971521,21430273,21692417,21954565,22347777,22413313,22609922,22740993,23199745,23265281,23658498,23789572,23855105,23986196,24051713,24117250,24182788,24248321,24313857,24379394,24444936,24510469,24576001,24641539,24772609,24838145],"status":[458755,1441799,1507335,1769473,1835009,1900545,1966081,4194308,4784134,4980742,5177350,5439494,9568269,9633805,11337731,11403271,12320772,13107204,15269890,15400962,15728644,19726348,20250637,21233666,21299203,21561345,21626881,21692417,21757953,23658497,23920647,24051714,24707082,24772610],"statuscode":[458754,1441793,1507329,11403274,12320770,15728641,21299211,24707076,24772613],"successful":[458753,1507329,24707073,24772609],"structure":[458753,1441793,1507329,2031617,2097153,3342337,4194305,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,8912897,8978433,9043969,11337729,11403265,12320769,12517377,13041665,13959169,14024705,15138817,15728641,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,18939905,19005441,19070977,19136513,21233665,21299201,21823490,21889026,23724034,24707074],"syntax":[655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572865,1638401,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6094849,6160385,6225921,6291457,6356993,6422529,6488065,6553601,6619137,6684673,6750209,6815745,6881281,6946817,7012353,7077889,7143425,7208961,7274497,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7864321,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388609,8454145,8519681,8585217,8650753,8716289,8781825,8847361,8912897,8978433,9043969,9109505,9175041,9240577,9306113,9371649,9437185,9502721,9568257,9633793,9699329,9764865,9830401,9895937,9961473,10027009,10092545,10158081,10223617,10289153,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11337729,11403265,11468802,11534338,11599874,11665410,11730945,11796481,11862017,11927553,11993089,12058625,12124161,12189697,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18153473,18219009,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19267585,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020097,22085633,22151169,22216705,22282241,22347777,22413313,22478849,22544385,22609921,22675457,22740993,22806529,22872065,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23789569,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24379393,24444929,24510465,24576001,24641537,24707073,24772609,24838145,24903681,24969217,25034753,25100289,25165825,25231361],"string":[655365,720901,786437,851973,917509,983045,1048581,1114117,1245189,1572869,1769473,1835009,1900545,1966081,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014661,3080196,3211265,3276804,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932162,3997697,4063233,4128769,4194305,4390915,4456449,4521989,5701638,5767180,6422534,6488078,6750214,6815750,7340042,7405577,7471115,7536650,7667721,7733259,7798794,7929863,7995401,8060936,8192007,8257545,8323080,8585225,8650770,8912903,8978438,9043981,9502730,9633798,9895941,10289157,10354693,10551302,11075592,11141127,11272198,11337735,11403269,11862022,11993095,12124166,12320769,12517379,12582916,12648450,12713986,12779522,12845058,12910594,12976131,13041667,13107201,13238273,13303811,13369345,13500417,13565953,13631489,14155777,14942209,15138817,15269889,16580614,16646150,17301510,17367047,17498118,17629190,17825799,18284550,18350086,18415622,18546694,18612230,18677767,19005446,19070983,19333127,19398663,19595271,19922950,19988486,20054022,20578310,20971526,21168134,21233670,21561345,21626881,21692417,21757953,21823491,22020099,22085638,22216706,22347777,22544385,22609921,22675457,22806529,22872069,23330817,23396357,23461892,23527425,23592961,23658500,23724037,23855105,23920643,23986177,24051713,24117249,24182785,24248321,24313857,24444930,24510465,24576004,24641538,24707074,25034755,25231361],"static":[655361,720897,786433,851969,917505,983041,1048577,1114113,1179651,1245185,1310723,1376257,1441795,1507331,1572865,1638403,4521987,4587523,6094851,6160387,6225923,6291459,6356995,7143427,8388611,10354691,11468803,11534339,11599875,11665411,11730947,11796483,11862019,11927555,11993091,12058627,12124163,18022403,18087939,18677763,20381699,21495809,21954561,22151169,23527425,24903681,24969217,25034753,25100289],"shared":[1179649,1310721,1441793,1507329,1638401,4521985,4587521,6094849,6160385,6225921,6291457,6356993,7143425,8388609,10354689,11468801,11534337,11599873,11665409,11730945,11796481,11862017,11927553,11993089,12058625,12124161,18022401,18087937,18677761,20381697],"stream":[1769473,1835010,1900545,1966081,2162693,2686978,2818051,2883585,4259845,4653057,4915202,5111809,5308417,6094849,6160387,6225922,7274497,11468801,11534337,11599874,11665409,12320772,13434883,13697025,13762562,13828097,15859713,16056321,16187393,16318465,21561346,21626884,21692418,21757953,21954565,22937603,23003137,23068676,23265282,23789571,24903685,25165825],"specified":[1769473,1835009,1900545,1966081,2031617,2097153,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014658,3080193,3145729,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4456449,7602177,8126465,8388609,12320769,12386305,21430273,21561345,21626881,21692417,21757953,21823489,21889025,22020097,22085634,22347777,22544385,22609921,22675457,22806529,23330817,23396354,23461889,23527425,23592961,23658497,23724033,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707073,24772610,25231361],"serves":[1769473,1835009,1900545,1966081,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4456449,21561345,21626881,21692417,21757953,22020097,22085633,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23592961,23658497,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,25231361],"set":[2031617,2097155,5570561,5832705,5898241,5963777,7012354,12255233,14221314,14548993,14614529,14811137,17760260,17825798,18153477,18219012,19267589,20250628,20316164,21430273,21823489,21889027,22347778,23003137,23068673,23265281],"streaming":[2162694,3866627,6094850,6160386,6225922,9961473,10027009,10092545,12320774,12451841,13172739,13697025,13762562,13828097,15400961,15859713,16056321,16187393,16318465,20316161,21561346,21626883,21692418,21954566,22413313,22740993,24051713,24313859,24379393,24903681],"scenario":[2162691,6094849,6160385,6225921,21954563],"sends":[2162691,3604482,6094849,6160385,6225921,9764866,21954563,24051714],"single":[2162689,2752513,2818049,2883585,3866626,6094849,7208961,10158082,12320772,13172738,14221313,17825793,21757954,21954561,22020097,22347777,23003137,23068673,23265281,23789572,23986177,24313858],"sending":[2162689,6160385,21954561],"simple":[2162690,4325377,6291457,6356993,11730945,21954562,24969217],"starting":[2228226,6553602,22020098],"shallow":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3211265,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23592961,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"shutdownasync":[2228225,3538945,6619141,10813445,22020097,23986177],"setlogger":[2621441,7143430,22806529],"sets":[2621441,3473409,7143425,14680065,15269891,18219009,22806529,23134209,23920644],"severity":[3014662,3080198,7405569,7471105,7536641,7667713,7733249,7798785,7929857,7995393,8060929,8192001,8257537,8323073,12713986,12779522,12845058,12910594,23396358,23461894],"serializer":[3145729,8388615,8454149,15007746,18808838,23527425,23592962],"subsequent":[3473409,14548993,14614529,14811137,18153473,23003137,23068673,23265281,23920641],"serializationinfo":[3473409,23920641],"shutdown":[3538948,10420226,10813442,12320769,22806529,23986180],"serviced":[3538945,10813441,23986177],"starts":[3538945,10878977,23986177],"servercallcontext":[3604483,6029313,9699331,9764866,12320770,15400963,19791874,19857410,19922946,19988482,20054018,20119554,20185090,20250626,20316162,22413317,22740997,23134209,24051719,24379397,24838149],"servercredentials":[3670019,3932161,9830406,9895941,10551302,12320769,13238273,15466499,20381704,20512774,24117257,24444929,24641541],"serverservicedefinition":[3801092,3866627,9961479,10027015,10092551,10158087,10223625,10289154,10354696,10682374,10747910,12320772,13172737,24248329,24313862,24510468],"serverstreamingservermethod":[3866625,10092550,12320769,13172737,24313857,24379397],"serverportcollection":[3932163,10485763,10551298,10616834,12320769,13238274,20709382,24444935],"servicedefinitioncollection":[3997699,10682371,10747906,12320769,20774918,24510471],"service":[3997698,9502721,10289153,10354689,10682370,12320770,14745601,15204353,15335425,18415617,19595265,20774913,23199745,23855105,23986177,24248321,24510467,24772610],"sslcredentials":[4063235,11010054,11075591,11141126,12320769,13303813,15597571,20905986,20971522,22675457,24576010],"sslservercredentials":[4128771,11206662,11272198,12320769,13369348,15663107,21037058,21102594,21168130,24117249,24641545],"system":[4521985,5701633,5767170,5832705,5898241,6029314,6422530,6488066,6553601,6684677,6750210,6815747,7012354,7340034,7405574,7471116,7536646,7667718,7733260,7798790,7929862,7995404,8060934,8192006,8257548,8323078,8388622,8454146,8585224,8650760,8847364,8978434,9043970,9240580,9371651,9502722,9633793,9895938,10289153,10354689,10551298,10944513,11075586,11141121,11206657,11272195,11403265,11468807,11599882,11665412,11730956,11796481,11862018,11993090,12058625,12124162,12386305,19267586,21495809,21561345,21626881,21692417,21757953,21954561,22020097,22085633,22151169,22347777,22544385,22609921,22675457,22806529,22872065,23330817,23396354,23527425,23592961,23658497,23855105,23920642,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24772613,24903681,24969217,25034753,25100289,25231361],"sub":[4653057,4915201,5111809,5308417,5636097,5701633,5767169,6029313,6422529,6488065,6750209,6815745,6946817,7012353,7077889,7143425,7340033,7405569,7471105,7536641,7667713,7733249,7798785,7864321,7929857,7995393,8060929,8192001,8257537,8323073,8454145,8519681,8585217,8650753,8716289,8847361,8978433,9043969,9240577,9371649,9437185,9502721,9568257,9633793,9830401,9895937,10289153,10682369,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11403265,11730945,11796481,11862017,12058625,12124161,12189697,22872065],"sealed":[4653057,4915201,5111809,5308417,7405569,7471105,7536641,7602177,7667713,7733249,7798785,8519681,8716289,8781825,8847361,9109505,9175041,9240577,9306113,9371649,10616833,10747905,18874369,19202049,19267586,19333121,19398657,19595265,19660801,21495809,21561346,21626882,21692418,21757954,21954561,22085634,22151169,23330818,23527425,23658498,24576002,24903681,24969217,25034753,25100289],"struct":[5636097,5701633,5767169,6029313,6094850,6160386,6225922,6291458,6356994,6881282,8978433,9043969,9961474,10027010,10092546,10158082,11468801,11534337,11599873,11665409,12517379,13041666,21823493,21889027,23724036,24707074],"sent":[6029313,12320773,15400961,20119553,23658501,23789571,24051713],"stringvalue":[6488069,14155777,17367045,22085633],"specific":[6750209,6815745,7864321,12648450,15269889,22020098,23396353,23920641],"secure":[6750210,6815745,9895937,10551297,12320769,12648449,22020097,22675457],"serialize":[8454145,13959169,16777217,21823489],"summary":[8519681,8585217,8650753,8716289,8781825,8847361,9109505,9175041,9240577,9306113,9371649,18874369,19202049,19267585,20447233,20512769,20578305,20643841],"servicename":[9502725,10289157,10354693,14745601,15204353,18415621,19595271,23199745,23855105],"send":[9764865,13697025,13762561,14024705,15400962,15859713,16056321,17039361,20185089,20250625,21561345,21626881,21889025,24051714],"servicedefinition":[10682374],"streamreader":[11468806,11534342],"streamwriter":[11599878,11665414],"stubs":[12255233,12320769,21495809,22347777],"servers":[12320769,22020097],"supported":[12320770,22151169,23789569,24772609],"situations":[12320769,22609921],"sense":[12320769,22609921],"serializing":[12320769,23592961],"supports":[12320769,14221313,17825793,22347777,23658497],"services":[12320769,15335426,20774918,23986179],"structures":[12320769],"sharing":[12320769,23134209],"simplify":[12451842,24903681,25034753],"started":[14221313,15335426,17760257,20709377,20774913,22347777,23986178],"served":[14221313,17825793,22347777],"security":[14352385,15466497,18022401,20381697,22675457,24117249],"stringmarshaller":[14942209,18677765,23527425],"source":[15269889,23920641],"stacktrace":[15269889,23920641],"stack":[15269889,23920641],"shutdowntask":[15335425,20840453,23986177],"signals":[15400961,19791873,24051713],"setting":[15400961,20316161,24051713],"success":[15728641,21299201,24707073,24772609],"sealedattribute":[21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22085633,22151169,23330817,23527425,23658497,23724033,24576001,24707073,24903681,24969217,25034753,25100289],"serverstreaming":[23789569],"simultaneously":[23789569],"space":[24772612],"successfully":[24772609],"sequencer":[24772609],"seeking":[24772609]} \ No newline at end of file diff --git a/doc/ref/csharp/html/fti/FTI_116.json b/doc/ref/csharp/html/fti/FTI_116.json index 5e6f03ef40..2aa9de3782 100644 --- a/doc/ref/csharp/html/fti/FTI_116.json +++ b/doc/ref/csharp/html/fti/FTI_116.json @@ -1 +1 @@ -{"topic":[1],"title":[65537],"type":[131073,196609,262145,327681,393217,458753,524289,589825,655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572865,1638401,1703938,1769474,1835010,1900546,1966082,2031619,2097155,2162689,2228226,2293762,2359298,2424834,2490370,2555906,2621442,2686977,2752513,2818049,2883585,2949122,3014659,3080194,3145729,3211267,3276802,3342338,3407874,3473410,3538946,3604482,3670018,3735554,3801090,3866626,3932164,3997698,4063234,4128770,4194306,4259841,4325377,4456450,4521986,4587523,4718593,4784129,4849665,4980737,5046273,5177345,5242881,5373953,5439489,5505025,5570562,5636099,5701636,5767174,5832706,5898242,5963778,6029317,6094852,6160389,6225925,6291461,6356997,6422530,6488066,6553602,6619137,6684675,6750211,6815748,6881286,6946817,7012354,7143425,7208962,7274497,7340034,7405570,7471107,7536642,7602179,7667714,7733251,7798786,7864321,7929858,7995395,8060930,8126467,8192002,8257539,8323074,8388612,8454146,8519681,8585218,8650754,8781826,8847362,8912897,8978434,9043970,9109505,9175042,9240578,9306114,9371649,9502731,9568257,9633794,9699330,9764866,9895940,9961476,10027012,10092548,10158084,10223617,10289153,10354690,10420225,10485763,10551301,10616833,10682369,10747905,10813441,10944513,11075585,11141122,11206657,11272195,11337729,11403266,11468805,11534340,11599878,11665413,11730947,11796481,11862018,11927555,11993092,12058625,12124162,12189697,12320773,13238274,13697025,13762561,13828097,13893633,13959169,14024705,14090241,14155779,14221313,14286849,14352385,14417921,14483457,14548993,14614529,14680065,14745603,14811137,14876673,14942210,15007745,15073281,15138817,15204355,15269889,15335425,15400961,15466497,15532033,15597569,15663105,15728641,15794177,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432583,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18153473,18219009,18284545,18350081,18415617,18481159,18546689,18612225,18677762,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19267586,19333121,19398657,19464193,19529729,19595265,19660809,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21495811,21561351,21626887,21692422,21757958,21823495,21889028,21954562,22020099,22085637,22151170,22216706,22282241,22347779,22413319,22478849,22544387,22609923,22675459,22741000,22806531,22872068,22937604,23003140,23068676,23134210,23199748,23265283,23330819,23396357,23461891,23527427,23592965,23658499,23724035,23789569,23855112,23920643,23986179,24051715,24117251,24182787,24248323,24313859,24379400,24444933,24510467,24576003,24641539,24707075,24772609,24838151,24903682,24969218,25034753,25100290,25165825,25231363],"top":[131073,196609,262145,327681,393217,458753,524289,589825,1703937,1769473,1835009,1900545,1966081,2031617,2097153,2162689,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2686978,2752513,2818050,2883586,2949121,3014657,3080193,3145729,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4259841,4325377,4390913,4456449,12517377,12582913,12648449,12713985,12779521,12845057,12910593,12976129,13041665,13107201,13172737,13238273,13303809,13369345,13434881,13500417,13565953,13631489,13697025,13762561,13828097,13893633,13959169,14024705,14090241,14155777,14221313,14286849,14352385,14417921,14483457,14548993,14614529,14680065,14745601,14811137,14876673,14942209,15007745,15073281,15138817,15204353,15269889,15335425,15400961,15466497,15532033,15597569,15663105,15728641,15794177,21495809,21561346,21626882,21692418,21757954,21823491,21889027,21954561,22020099,22085635,22151169,22347779,22544388,22609921,22675459,22806530,22937603,23003138,23068675,23134209,23199745,23265283,23330819,23396354,23461889,23527426,23592963,23658500,23724035,23855107,23920644,23986179,24051714,24117251,24182788,24248321,24313858,24444929,24510465,24576003,24641539,24707076,24903681,24969217,25034753,25100289,25231364],"tracing":[196609,655361,12320769,22151169,22609921],"transports":[196609,786433,22151169],"target":[196609,1114113,6750214,14090242,14221313,17629190,17825793,22020098,22151169,22347777],"testing":[196609,1114113,14942209,18677761,22151169,23527425],"token":[1703938,3604481,4521986,4587521,5832705,6029313,7012353,9699329,12320771,14024706,14286849,15400961,16908289,17104897,17891329,19791873,21495810,21889026,22544385,22609923,24051714],"trequest":[1769475,1835011,2031620,2162693,2359297,3407875,3866636,4653058,4718594,4784130,4849666,4915202,4980738,5046274,5570568,5636106,5701642,5767178,6094866,6160402,6225938,6291474,6357010,6881298,9502727,9961492,10027028,10092564,10158100,12320776,12517387,13172748,13697027,13762563,13959171,15204355,15859720,15925250,15990786,16056328,16121858,16187394,16515074,16580610,16646146,16711682,16777224,16842754,19333122,19398658,19464200,19529730,19595266,19660802,21561352,21626888,21823505,21954565,22347777,22413324,22741004,23855113,24313868,24379404,24838156],"tresponse":[1769475,1835011,1900547,1966083,2031620,2162693,2359297,3407875,3866636,4653058,4718599,4784130,4849666,4915202,4980738,5046274,5111810,5177346,5242882,5308418,5373959,5439490,5505026,5570568,5636106,5701642,5767178,6094866,6160402,6225938,6291474,6357010,6881298,9502727,9961492,10027028,10092564,10158100,12320778,12517387,13172748,13697027,13762563,13828099,13893635,13959171,15204355,15859714,15925256,15990786,16056322,16121858,16187400,16252930,16318472,16384008,16449538,16515074,16580610,16646146,16711682,16777218,16842760,19333122,19398658,19464194,19529736,19595266,19660802,21561352,21626888,21692424,21757960,21823505,21954565,22347777,22413324,22741004,23855113,24313868,24379404,24838156],"terminate":[1769473,1835009,1900545,1966081,4653057,4915201,5111809,5308417,21561345,21626881,21692417,21757953],"throws":[1769474,1835010,1900546,1966082,4390918,4784129,4849665,4980737,5046273,5177345,5242881,5439489,5505025,11796481,11862017,11927553,11993089,12058625,12124161,13500418,13565954,13631490,15269889,21561346,21626882,21692418,21757954,23920641,25034758],"trailing":[1769473,1835009,1900545,1966081,4849665,5046273,5242881,5505025,21561345,21626881,21692417,21757953],"tostring":[1769473,1835009,1900545,1966081,2031617,2097153,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3342338,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194306,4456449,8912902,11337734,21561345,21626881,21692417,21757953,21823489,21889025,22020097,22085633,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23592961,23658497,23724034,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707074,25231361],"time":[2162689,2752513,2818049,2883585,6160385,7208961,14221313,17760257,21954561,22347777,23003137,23068673,23265281],"task":[2228227,3538946,6553607,6619141,6684678,7208965,7274501,9764870,10420230,10813446,11468813,11534341,11599877,11665413,15925254,15990790,16121862,16252934,16384006,16449542,20840454,22020099,22413317,22740997,23986178,24379397,24838149],"try":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"tasks":[2228225,2686977,6684673,11468803,22020097,22937601],"tolistasync":[2686977,4259841,11534343,22937601,24903681],"tokens":[4587521],"taskawaiter":[4718597,5373957],"threading":[5832705,6029313,11468803],"typename":[6094850,6160386,6225922,6291458,6356994,6881282,7602177,8126465,8388609,9961474,10027010,10092546,10158082,11468801,11534337,11599873,11665409,11927553,11993089,21561346,21626882,21692417,21757953,21823490,22413314,22740994,22937601,23003137,23068673,23265281,23592961,23855106,24379394,24838146],"true":[7012362,11272193,11599876,14286850,15138817,15663105,17891329,17956865,18939905,21037057,22544386,23724033,24641537],"typeparam":[7602177,8126465,8388609,11468801,11534337,11599873,11665409,11927553,11993089,23265281,23592961],"types":[12320770,23658497,23789569],"trailers":[12320769,15400961,20185089,23658497,24051713],"thrown":[12320769,23920641],"targetsite":[15269889,23920641],"termination":[15335425,20840449,23986177],"transientfailure":[22282241],"typically":[24772610],"transaction":[24772609],"transient":[24772609]} \ No newline at end of file +{"topic":[1],"title":[65537],"type":[131073,196609,262145,327681,393217,458753,524289,589825,655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572865,1638401,1703938,1769474,1835010,1900546,1966082,2031619,2097155,2162689,2228226,2293762,2359298,2424834,2490370,2555906,2621442,2686977,2752513,2818049,2883585,2949122,3014659,3080194,3145729,3211266,3276802,3342338,3407874,3473410,3538946,3604482,3670018,3735554,3801090,3866626,3932164,3997698,4063234,4128770,4194306,4259841,4325377,4456450,4521986,4587523,4718593,4784129,4849665,4980737,5046273,5177345,5242881,5373953,5439489,5505025,5570562,5636099,5701636,5767174,5832706,5898242,5963778,6029317,6094852,6160389,6225925,6291461,6356997,6422530,6488066,6553602,6619137,6684675,6750211,6815748,6881286,6946817,7012354,7143425,7208962,7274497,7340034,7405570,7471107,7536642,7602179,7667714,7733251,7798786,7864321,7929858,7995395,8060930,8126467,8192002,8257539,8323074,8388612,8454146,8519681,8585218,8650754,8781826,8847362,8912897,8978434,9043970,9109505,9175042,9240578,9306114,9371649,9502731,9568257,9633794,9699330,9764866,9895940,9961476,10027012,10092548,10158084,10223617,10289153,10354690,10420225,10485763,10551301,10616833,10682369,10747905,10813441,10944513,11075585,11141122,11206657,11272195,11337729,11403266,11468805,11534340,11599878,11665413,11730947,11796481,11862018,11927555,11993092,12058625,12124162,12189697,12320773,13238274,13697025,13762561,13828097,13893633,13959169,14024705,14090241,14155779,14221313,14286849,14352385,14417921,14483457,14548993,14614529,14680065,14745603,14811137,14876673,14942210,15007745,15073281,15138817,15204355,15269889,15335425,15400961,15466497,15532033,15597569,15663105,15728641,15794177,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432583,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18153473,18219009,18284545,18350081,18415617,18481159,18546689,18612225,18677762,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19267586,19333121,19398657,19464193,19529729,19595265,19660809,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21495811,21561351,21626887,21692422,21757958,21823495,21889028,21954562,22020099,22085637,22151170,22216706,22282241,22347779,22413319,22478849,22544387,22609923,22675459,22741000,22806531,22872068,22937604,23003140,23068676,23134210,23199748,23265283,23330819,23396357,23461891,23527427,23592964,23658499,23724035,23789569,23855112,23920643,23986179,24051715,24117251,24182787,24248323,24313859,24379400,24444933,24510467,24576003,24641539,24707075,24772609,24838151,24903682,24969218,25034753,25100290,25165825,25231363],"top":[131073,196609,262145,327681,393217,458753,524289,589825,1703937,1769473,1835009,1900545,1966081,2031617,2097153,2162689,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2686978,2752513,2818050,2883586,2949121,3014657,3080193,3145729,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4259841,4325377,4390913,4456449,12517377,12582913,12648449,12713985,12779521,12845057,12910593,12976129,13041665,13107201,13172737,13238273,13303809,13369345,13434881,13500417,13565953,13631489,13697025,13762561,13828097,13893633,13959169,14024705,14090241,14155777,14221313,14286849,14352385,14417921,14483457,14548993,14614529,14680065,14745601,14811137,14876673,14942209,15007745,15073281,15138817,15204353,15269889,15335425,15400961,15466497,15532033,15597569,15663105,15728641,15794177,21495809,21561346,21626882,21692418,21757954,21823491,21889027,21954561,22020099,22085635,22151169,22347779,22544388,22609921,22675459,22806530,22937603,23003138,23068675,23134209,23199745,23265283,23330819,23396354,23461889,23527426,23592963,23658500,23724035,23855107,23920644,23986179,24051714,24117251,24182788,24248321,24313858,24444929,24510465,24576003,24641539,24707076,24903681,24969217,25034753,25100289,25231364],"tracing":[196609,655361,12320769,22151169,22609921],"transports":[196609,786433,22151169],"target":[196609,1114113,6750214,14090242,14221313,17629190,17825793,22020098,22151169,22347777],"testing":[196609,1114113,14942209,18677761,22151169,23527425],"token":[1703938,3604481,4521986,4587521,5832705,6029313,7012353,9699329,12320771,14024706,14286849,15400961,16908289,17104897,17891329,19791873,21495810,21889026,22544385,22609923,24051714],"trequest":[1769475,1835011,2031620,2162693,2359297,3407875,3866636,4653058,4718594,4784130,4849666,4915202,4980738,5046274,5570568,5636106,5701642,5767178,6094866,6160402,6225938,6291474,6357010,6881298,9502727,9961492,10027028,10092564,10158100,12320776,12517387,13172748,13697027,13762563,13959171,15204355,15859720,15925250,15990786,16056328,16121858,16187394,16515074,16580610,16646146,16711682,16777224,16842754,19333122,19398658,19464200,19529730,19595266,19660802,21561352,21626888,21823505,21954565,22347777,22413324,22741004,23855113,24313868,24379404,24838156],"tresponse":[1769475,1835011,1900547,1966083,2031620,2162693,2359297,3407875,3866636,4653058,4718599,4784130,4849666,4915202,4980738,5046274,5111810,5177346,5242882,5308418,5373959,5439490,5505026,5570568,5636106,5701642,5767178,6094866,6160402,6225938,6291474,6357010,6881298,9502727,9961492,10027028,10092564,10158100,12320778,12517387,13172748,13697027,13762563,13828099,13893635,13959171,15204355,15859714,15925256,15990786,16056322,16121858,16187400,16252930,16318472,16384008,16449538,16515074,16580610,16646146,16711682,16777218,16842760,19333122,19398658,19464194,19529736,19595266,19660802,21561352,21626888,21692424,21757960,21823505,21954565,22347777,22413324,22741004,23855113,24313868,24379404,24838156],"terminate":[1769473,1835009,1900545,1966081,4653057,4915201,5111809,5308417,21561345,21626881,21692417,21757953],"throws":[1769474,1835010,1900546,1966082,4390918,4784129,4849665,4980737,5046273,5177345,5242881,5439489,5505025,11796481,11862017,11927553,11993089,12058625,12124161,13500418,13565954,13631490,15269889,21561346,21626882,21692418,21757954,23920641,25034758],"trailing":[1769473,1835009,1900545,1966081,4849665,5046273,5242881,5505025,21561345,21626881,21692417,21757953],"tostring":[1769473,1835009,1900545,1966081,2031617,2097153,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3211265,3276801,3342338,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194306,4456449,8912902,11337734,21561345,21626881,21692417,21757953,21823489,21889025,22020097,22085633,22347777,22544385,22609921,22675457,22806529,23330817,23396353,23592961,23658497,23724034,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24576001,24641537,24707074,25231361],"time":[2162689,2752513,2818049,2883585,6160385,7208961,14221313,17760257,21954561,22347777,23003137,23068673,23265281],"task":[2228227,3538946,6553607,6619141,6684678,7208965,7274501,9764870,10420230,10813446,11468813,11534341,11599877,11665413,15925254,15990790,16121862,16252934,16384006,16449542,20840454,22020099,22413317,22740997,23986178,24379397,24838149],"try":[2228225,2359297,2424833,2490369,2555905,2621441,3014657,3211265,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23592961,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"tasks":[2228225,2686977,6684673,11468803,22020097,22937601],"tolistasync":[2686977,4259841,11534343,22937601,24903681],"tokens":[4587521],"taskawaiter":[4718597,5373957],"threading":[5832705,6029313,11468803],"typename":[6094850,6160386,6225922,6291458,6356994,6881282,7602177,8126465,8388609,9961474,10027010,10092546,10158082,11468801,11534337,11599873,11665409,11927553,11993089,21561346,21626882,21692417,21757953,21823490,22413314,22740994,22937601,23003137,23068673,23265281,23592961,23855106,24379394,24838146],"true":[7012362,11272193,11599876,14286850,15138817,15663105,17891329,17956865,18939905,21037057,22544386,23724033,24641537],"typeparam":[7602177,8126465,8388609,11468801,11534337,11599873,11665409,11927553,11993089,23265281,23592961],"types":[12320770,23658497,23789569],"trailers":[12320769,15400961,20185089,23658497,24051713],"thrown":[12320769,23920641],"targetsite":[15269889,23920641],"termination":[15335425,20840449,23986177],"transientfailure":[22282241],"typically":[24772610],"transaction":[24772609],"transient":[24772609]} \ No newline at end of file diff --git a/doc/ref/csharp/html/fti/FTI_118.json b/doc/ref/csharp/html/fti/FTI_118.json index 934344f41f..e6d0315afc 100644 --- a/doc/ref/csharp/html/fti/FTI_118.json +++ b/doc/ref/csharp/html/fti/FTI_118.json @@ -1 +1 @@ -{"value":[393217,655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376258,1441793,1507329,1572865,1638401,2031617,2097155,3932162,4521985,4587521,4718593,4784129,4849665,4980737,5046273,5177345,5242881,5373953,5439489,5505025,5570562,5832706,5898242,5963778,6094849,6160385,6225921,6291457,6356993,6422530,6488066,6553601,6619137,6684673,6881281,7208961,7274497,7602177,8126465,8388609,8650758,8781825,8912897,8978434,9043975,9109505,9175041,9306113,9699329,9764865,9895937,9961473,10027009,10092545,10158081,10223617,10354689,10420225,10485762,10551298,10616833,10747905,10813441,11337729,11468801,11534337,11599873,11665409,11927553,11993089,12582914,13041666,13238274,14155778,14548993,14614529,14811137,15138820,15269890,15400961,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235970,17301505,17367042,17432577,17498113,17563649,17629185,17694721,17760258,17825794,17891329,17956865,18022401,18087937,18153475,18219010,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939906,19005441,19070983,19136514,19202049,19267586,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250626,20316163,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21823490,21889028,22085636,22216707,22282241,22413313,22478849,22740993,23003137,23068673,23265281,23592961,23724039,23789569,23920642,24051713,24182785,24379393,24444930,24707073,24772610,24838145,25165825],"versioninfo":[524291,1572866,12320769,25100295],"version":[524289,655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572866,1638401,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6094849,6160385,6225921,6291457,6356993,6422529,6488065,6553601,6619137,6684673,6750209,6815745,6881281,6946817,7012353,7077889,7143425,7208961,7274497,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7864321,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388609,8454145,8519681,8585217,8650753,8716289,8781825,8847361,8912897,8978433,9043969,9109505,9175041,9240577,9306113,9371649,9437185,9502721,9568257,9633793,9699329,9764865,9830401,9895937,9961473,10027009,10092545,10158081,10223617,10289153,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11337729,11403265,11468801,11534337,11599873,11665409,11730945,11796481,11862017,11927553,11993089,12058625,12124161,12189697,12320769,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18153473,18219009,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19267585,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020097,22085633,22151169,22216705,22282241,22347777,22413313,22478849,22544385,22609921,22675457,22740993,22806529,22872065,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23789569,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24379393,24444929,24510465,24576001,24641537,24707073,24772609,24838145,24903681,24969217,25034753,25100291,25165825,25231361],"val":[655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572865,1638401],"valuetype":[2031619,2097155,3211267,3342339,4194307,21823491,21889027,23592963,23724035,24707075],"values":[2031617,2097155,5570561,5832705,5898241,5963777,15728641,21299201,21823489,21889027,24707073],"void":[4653058,4915202,5111810,5308418,7143426,7405570,7471106,7536642,7667714,7733250,7798786,7929858,7995394,8060930,8192002,8257538,8323074,8519682,8585218,8650754,8716290,8847362,9240578,9371650,10682370,10878978,11730946,11796482,11862018,12058626,12124162,17760257,17825793,18153473,18219009,19267585,20250625,20316161,22872066],"virtual":[4653057,4915201,5111809,5308417,7405569,7471105,7536641,7602177,7667713,7733249,7798785,8519681,8716289,8781825,8847361,8912897,9109505,9175041,9240577,9306113,9371649,10616833,10747905,11337729,18874369,19202049,19267585,19333121,19398657,19595265,19660801],"valuebytes":[8585222,8978437,15138817,19136517,23724033],"valued":[8978433,9043969],"variable":[11010049,13303809,24576001],"visual":[11468802,11534338,11599874,11665410],"various":[12451841,21430273],"valid":[24772610]} \ No newline at end of file +{"value":[393217,655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376258,1441793,1507329,1572865,1638401,2031617,2097155,3932162,4521985,4587521,4718593,4784129,4849665,4980737,5046273,5177345,5242881,5373953,5439489,5505025,5570562,5832706,5898242,5963778,6094849,6160385,6225921,6291457,6356993,6422530,6488066,6553601,6619137,6684673,6881281,7208961,7274497,7602177,8126465,8388609,8650758,8781825,8912897,8978434,9043975,9109505,9175041,9306113,9699329,9764865,9895937,9961473,10027009,10092545,10158081,10223617,10354689,10420225,10485762,10551298,10616833,10747905,10813441,11337729,11468801,11534337,11599873,11665409,11927553,11993089,12582914,13041666,13238274,14155778,14548993,14614529,14811137,15138820,15269890,15400961,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235970,17301505,17367042,17432577,17498113,17563649,17629185,17694721,17760258,17825794,17891329,17956865,18022401,18087937,18153475,18219010,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939906,19005441,19070983,19136514,19202049,19267586,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250626,20316163,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21823490,21889028,22085636,22216707,22282241,22413313,22478849,22740993,23003137,23068673,23265281,23724039,23789569,23920642,24051713,24182785,24379393,24444930,24707073,24772610,24838145,25165825],"versioninfo":[524291,1572866,12320769,25100295],"version":[524289,655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572866,1638401,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6094849,6160385,6225921,6291457,6356993,6422529,6488065,6553601,6619137,6684673,6750209,6815745,6881281,6946817,7012353,7077889,7143425,7208961,7274497,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7864321,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388609,8454145,8519681,8585217,8650753,8716289,8781825,8847361,8912897,8978433,9043969,9109505,9175041,9240577,9306113,9371649,9437185,9502721,9568257,9633793,9699329,9764865,9830401,9895937,9961473,10027009,10092545,10158081,10223617,10289153,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11337729,11403265,11468801,11534337,11599873,11665409,11730945,11796481,11862017,11927553,11993089,12058625,12124161,12189697,12320769,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18153473,18219009,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19267585,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020097,22085633,22151169,22216705,22282241,22347777,22413313,22478849,22544385,22609921,22675457,22740993,22806529,22872065,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23789569,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24379393,24444929,24510465,24576001,24641537,24707073,24772609,24838145,24903681,24969217,25034753,25100291,25165825,25231361],"val":[655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572865,1638401],"valuetype":[2031619,2097155,3342339,4194307,21823491,21889027,23724035,24707075],"values":[2031617,2097155,5570561,5832705,5898241,5963777,15728641,21299201,21823489,21889027,24707073],"void":[4653058,4915202,5111810,5308418,7143426,7405570,7471106,7536642,7667714,7733250,7798786,7929858,7995394,8060930,8192002,8257538,8323074,8519682,8585218,8650754,8716290,8847362,9240578,9371650,10682370,10878978,11730946,11796482,11862018,12058626,12124162,17760257,17825793,18153473,18219009,19267585,20250625,20316161,22872066],"virtual":[4653057,4915201,5111809,5308417,7405569,7471105,7536641,7602177,7667713,7733249,7798785,8519681,8716289,8781825,8847361,8912897,9109505,9175041,9240577,9306113,9371649,10616833,10747905,11337729,18874369,19202049,19267585,19333121,19398657,19595265,19660801],"valuebytes":[8585222,8978437,15138817,19136517,23724033],"valued":[8978433,9043969],"variable":[11010049,13303809,24576001],"visual":[11468802,11534338,11599874,11665410],"various":[12451841,21430273],"valid":[24772610]} \ No newline at end of file diff --git a/doc/ref/csharp/html/fti/FTI_97.json b/doc/ref/csharp/html/fti/FTI_97.json index 2a75124bdf..0f399972cc 100644 --- a/doc/ref/csharp/html/fti/FTI_97.json +++ b/doc/ref/csharp/html/fti/FTI_97.json @@ -1 +1 @@ -{"automatically":[1,9895937,10551297,20447233],"authority":[196609,720897,22151169],"allow":[196609,851969,15335425,20840449,22151169,23986177],"agent":[196612,983042,1048578,22151172],"added":[393217,1376257,24182785],"assembly":[655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572865,1638401,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6094849,6160385,6225921,6291457,6356993,6422529,6488065,6553601,6619137,6684673,6750209,6815745,6881281,6946817,7012353,7077889,7143425,7208961,7274497,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7864321,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388609,8454145,8519681,8585217,8650753,8716289,8781825,8847361,8912897,8978433,9043969,9109505,9175041,9240577,9306113,9371649,9437185,9502721,9568257,9633793,9699329,9764865,9830401,9895937,9961473,10027009,10092545,10158081,10223617,10289153,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11337729,11403265,11468801,11534337,11599873,11665409,11730945,11796481,11862017,11927553,11993089,12058625,12124161,12189697,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18153473,18219009,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19267585,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020097,22085633,22151169,22216705,22282241,22347777,22413313,22478849,22544385,22609921,22675457,22740993,22806529,22872065,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23789569,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24379393,24444929,24510465,24576001,24641537,24707073,24772609,24838145,24903681,24969217,25034753,25100289,25165825,25231361],"authinterceptors":[1703939,4521986,4587522,12255233,21495815],"access":[1703938,4521986,4587522,6094849,6160385,6225921,6291457,13697025,13762561,13828097,13893633,15990785,16121857,16252929,16449537,21495810,21561345,21626881,21692417,21757953],"authorization":[1703937,4521985,12255233,21495810],"auth":[1703937,4521988,4587524,12255235,21430275,21495813],"asyncclientstreamingcall":[1769475,2162689,4653058,4718594,4784130,4849666,6094858,12320769,13697027,15859714,15925250,15990786,21561351,21954561],"async":[1769473,1835009,1900545,1966081,2686977,4259841,4653057,4915201,5111809,5308417,11468801,13697025,13762562,13828097,15859713,16056321,16187393,16318465,21561346,21626883,21692418,21757953,22937601,24903681],"associated":[1769473,1835009,1900545,1966081,2686977,3014659,3080195,4653057,4915201,5111809,5308417,7471105,7602177,7733249,7864321,7995393,8126465,8257537,9568257,9633793,12320769,12713985,12779521,12845057,12910593,13107202,13959169,14221313,15269889,16515073,17694721,21561345,21626881,21692417,21757953,21823489,22347777,22937601,23396356,23461891,23920644],"allows":[1769473,1966081,2228226,2359297,2424833,2490369,2555905,2621441,3014657,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,4718593,5373953,6553601,12320770,15400961,20316161,21561345,21757953,22020098,22347777,22544385,22609922,22675457,22806529,23134209,23396353,23855105,23920641,23986177,24051714,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"awaiting":[1769473,1966081,4718593,5373953,15335425,20840449,21561345,21757953,23986177],"asyncduplexstreamingcall":[1835011,2162689,4915202,4980738,5046274,6160394,12320769,13762563,16056322,16121858,16187394,21626887,21954561],"asyncserverstreamingcall":[1900547,2162689,5111810,5177346,5242882,6225930,12320769,13828099,16252930,16318466,21692423,21954561],"asyncunarycall":[1966083,2162689,5308418,5373954,5439490,5505026,6291466,12320769,13893635,16384002,16449538,21757959,21954561],"asynchronously":[2162692,2752513,2818049,2883585,3604481,6094849,6160385,6225921,6291457,7208961,9764865,21954564,23003137,23068673,23265281,24051713],"active":[2228225,6619137,22020097],"application":[2621441,2686977,7143425,12386305,14417921,15269889,18087937,21430273,22806530,22937601,23920641],"action":[2686977,4259841,11468801,11730958,22937601,24903681],"asyncstreamextensions":[2686978,2818049,2883585,4259843,11468805,11534340,11599878,11665413,12451841,13434882,22937602,23068673,23265281,24903687],"add":[3276803,3932162,3997697,8519690,8585225,8650761,10485767,10551302,10682374,12976132,13238275,23658499,24444930,24510465],"addmethod":[3866628,9961478,10027014,10092550,10158086,13172741,24313860],"adds":[3866628,3932162,3997697,9961473,10027009,10092545,10158081,10485761,10551297,10682369,13172740,13238274,24313860,24444930,24510465],"argumentexception":[4390914,11796481,11862017,13500418,25034754],"argumentnullexception":[4390914,11927553,11993089,13565954,25034754],"accesstoken":[4521989],"abstract":[4653057,4915201,5111809,5308417,7208961,7274497,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8519681,8716289,8781825,8847361,8912897,9109505,9175041,9240577,9306113,9371649,10616833,10747905,11337729,18153473,18219009,18284545,18350081,18415617,18481153,18874369,19202049,19267585,19333121,19398657,19595265,19660801,21495809,21954561,22151169,22347778,22675458,23527425,24117250,24903681,24969217,25034753,25100289],"awaitable":[6094849,6291457],"asynchronous":[6160385,6225921,13697026,13762561,13828097,13893634,15925249,15990785,16121857,16252929,16384001,16449537,21561346,21626881,21692417,21757954],"address":[6815745,14090241,15400961,17498113,20054017,22020097,24051713,24772610],"array":[7405569,7471105,7536641,7667713,7733249,7798785,7929857,7995393,8060929,8192001,8257537,8323073,8388610,8454146,8585217,8847368,8978433,18743298,18808834,19136514],"arrayindex":[8847367],"ascii":[9043970,13041665,23724033],"allowed":[9043969],"autheticate":[11206657,13369345,24641537],"authenticate":[11272193],"asyncaction":[11468806],"authentication":[12255233,21430273,24772609],"apis":[12255233,21430273,24772609],"autogenerated":[12255233,12320769,21495809,24248321],"abstraction":[12320769,22020097],"accessible":[12320769,22609921],"arbitrary":[12320769,23789569,23986177],"additional":[15269889,23920641],"assigned":[15269889,23920641],"adding":[15335426,20709377,20774913,23986178],"authenticity":[15663105,21037057,24641537],"actually":[20447233],"abstractclassattribute":[21495809,21954561,22151169,22347777,22675457,23527425,24117249,24903681,24969217,25034753,25100289],"authuri":[22872069],"argument":[24772609],"arguments":[24772609],"alreadyexists":[24772609],"attempted":[24772610],"applied":[24772609],"aborted":[24772610],"aborts":[24772609]} \ No newline at end of file +{"automatically":[1,9895937,10551297,20447233],"authority":[196609,720897,22151169],"allow":[196609,851969,15335425,20840449,22151169,23986177],"agent":[196612,983042,1048578,22151172],"added":[393217,1376257,24182785],"assembly":[655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572865,1638401,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6094849,6160385,6225921,6291457,6356993,6422529,6488065,6553601,6619137,6684673,6750209,6815745,6881281,6946817,7012353,7077889,7143425,7208961,7274497,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7864321,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388609,8454145,8519681,8585217,8650753,8716289,8781825,8847361,8912897,8978433,9043969,9109505,9175041,9240577,9306113,9371649,9437185,9502721,9568257,9633793,9699329,9764865,9830401,9895937,9961473,10027009,10092545,10158081,10223617,10289153,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11337729,11403265,11468801,11534337,11599873,11665409,11730945,11796481,11862017,11927553,11993089,12058625,12124161,12189697,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18153473,18219009,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19267585,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020097,22085633,22151169,22216705,22282241,22347777,22413313,22478849,22544385,22609921,22675457,22740993,22806529,22872065,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396353,23461889,23527425,23592961,23658497,23724033,23789569,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24379393,24444929,24510465,24576001,24641537,24707073,24772609,24838145,24903681,24969217,25034753,25100289,25165825,25231361],"authinterceptors":[1703939,4521986,4587522,12255233,21495815],"access":[1703938,4521986,4587522,6094849,6160385,6225921,6291457,13697025,13762561,13828097,13893633,15990785,16121857,16252929,16449537,21495810,21561345,21626881,21692417,21757953],"authorization":[1703937,4521985,12255233,21495810],"auth":[1703937,4521988,4587524,12255235,21430275,21495813],"asyncclientstreamingcall":[1769475,2162689,4653058,4718594,4784130,4849666,6094858,12320769,13697027,15859714,15925250,15990786,21561351,21954561],"async":[1769473,1835009,1900545,1966081,2686977,4259841,4653057,4915201,5111809,5308417,11468801,13697025,13762562,13828097,15859713,16056321,16187393,16318465,21561346,21626883,21692418,21757953,22937601,24903681],"associated":[1769473,1835009,1900545,1966081,2686977,3014659,3080195,4653057,4915201,5111809,5308417,7471105,7602177,7733249,7864321,7995393,8126465,8257537,9568257,9633793,12320769,12713985,12779521,12845057,12910593,13107202,13959169,14221313,15269889,16515073,17694721,21561345,21626881,21692417,21757953,21823489,22347777,22937601,23396356,23461891,23920644],"allows":[1769473,1966081,2228226,2359297,2424833,2490369,2555905,2621441,3014657,3211265,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,4718593,5373953,6553601,12320770,15400961,20316161,21561345,21757953,22020098,22347777,22544385,22609922,22675457,22806529,23134209,23396353,23592961,23855105,23920641,23986177,24051714,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"awaiting":[1769473,1966081,4718593,5373953,15335425,20840449,21561345,21757953,23986177],"asyncduplexstreamingcall":[1835011,2162689,4915202,4980738,5046274,6160394,12320769,13762563,16056322,16121858,16187394,21626887,21954561],"asyncserverstreamingcall":[1900547,2162689,5111810,5177346,5242882,6225930,12320769,13828099,16252930,16318466,21692423,21954561],"asyncunarycall":[1966083,2162689,5308418,5373954,5439490,5505026,6291466,12320769,13893635,16384002,16449538,21757959,21954561],"asynchronously":[2162692,2752513,2818049,2883585,3604481,6094849,6160385,6225921,6291457,7208961,9764865,21954564,23003137,23068673,23265281,24051713],"active":[2228225,6619137,22020097],"application":[2621441,2686977,7143425,12386305,14417921,15269889,18087937,21430273,22806530,22937601,23920641],"action":[2686977,4259841,11468801,11730958,22937601,24903681],"asyncstreamextensions":[2686978,2818049,2883585,4259843,11468805,11534340,11599878,11665413,12451841,13434882,22937602,23068673,23265281,24903687],"add":[3276803,3932162,3997697,8519690,8585225,8650761,10485767,10551302,10682374,12976132,13238275,23658499,24444930,24510465],"addmethod":[3866628,9961478,10027014,10092550,10158086,13172741,24313860],"adds":[3866628,3932162,3997697,9961473,10027009,10092545,10158081,10485761,10551297,10682369,13172740,13238274,24313860,24444930,24510465],"argumentexception":[4390914,11796481,11862017,13500418,25034754],"argumentnullexception":[4390914,11927553,11993089,13565954,25034754],"accesstoken":[4521989],"abstract":[4653057,4915201,5111809,5308417,7208961,7274497,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8519681,8716289,8781825,8847361,8912897,9109505,9175041,9240577,9306113,9371649,10616833,10747905,11337729,18153473,18219009,18284545,18350081,18415617,18481153,18874369,19202049,19267585,19333121,19398657,19595265,19660801,21495809,21954561,22151169,22347778,22675458,23527425,24117250,24903681,24969217,25034753,25100289],"awaitable":[6094849,6291457],"asynchronous":[6160385,6225921,13697026,13762561,13828097,13893634,15925249,15990785,16121857,16252929,16384001,16449537,21561346,21626881,21692417,21757954],"address":[6815745,14090241,15400961,17498113,20054017,22020097,24051713,24772610],"array":[7405569,7471105,7536641,7667713,7733249,7798785,7929857,7995393,8060929,8192001,8257537,8323073,8388610,8454146,8585217,8847368,8978433,18743298,18808834,19136514],"arrayindex":[8847367],"ascii":[9043970,13041665,23724033],"allowed":[9043969],"autheticate":[11206657,13369345,24641537],"authenticate":[11272193],"asyncaction":[11468806],"authentication":[12255233,21430273,24772609],"apis":[12255233,21430273,24772609],"autogenerated":[12255233,12320769,21495809,24248321],"abstraction":[12320769,22020097],"accessible":[12320769,22609921],"arbitrary":[12320769,23789569,23986177],"additional":[15269889,23920641],"assigned":[15269889,23920641],"adding":[15335426,20709377,20774913,23986178],"authenticity":[15663105,21037057,24641537],"actually":[20447233],"abstractclassattribute":[21495809,21954561,22151169,22347777,22675457,23527425,24117249,24903681,24969217,25034753,25100289],"authuri":[22872069],"argument":[24772609],"arguments":[24772609],"alreadyexists":[24772609],"attempted":[24772610],"applied":[24772609],"aborted":[24772610],"aborts":[24772609]} \ No newline at end of file diff --git a/doc/ref/csharp/html/fti/FTI_99.json b/doc/ref/csharp/html/fti/FTI_99.json index a53458d4f3..b399ce4a01 100644 --- a/doc/ref/csharp/html/fti/FTI_99.json +++ b/doc/ref/csharp/html/fti/FTI_99.json @@ -1 +1 @@ -{"create":[131073,3145729,8388616,10944513,12255233,14090241,17629185,21495809,22020097,23527425,23920641,23986177,24772609],"contains":[131073,3276801,5701633,5767169,8781833,12320769,21430273,23658497,23920641],"class":[131073,196609,262145,327681,393217,524289,589825,655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1572865,1638401,1703937,1769473,1835009,1900545,1966081,2162689,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3145729,3276801,3407873,3473411,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4259841,4325377,4390913,4456449,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,6094855,6160391,6225927,6291463,6356999,6422529,6488065,6553601,6619137,6684673,6750209,6815745,6881287,6946818,7012353,7077890,7143425,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7864321,8388609,8519681,8585217,8650753,8716289,8781825,8847361,9109505,9175041,9240577,9306113,9371649,9437185,9502722,9568257,9633793,9699329,9764865,9830402,9895937,9961481,10027017,10092553,10158089,10223617,10289153,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11468804,11534340,11599876,11665412,11730945,11796481,11862017,11927553,11993089,12058625,12124161,12189698,12255233,12320772,12386305,12451841,12582913,12648449,12713985,12779521,12976129,13107201,13172737,13238273,13303809,13369345,13434881,13500417,13565953,13631489,13697025,13762561,13828097,13893633,14090241,14155777,14221313,14286849,14352385,14417921,14876673,14942209,15073281,15204353,15269889,15335425,15400961,15466497,15532033,15597569,15663105,15794177,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18546689,18612225,18677761,18874369,19202049,19267585,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21364737,21495813,21561349,21626885,21692421,21757957,21823489,21889025,21954566,22020101,22085637,22151173,22216705,22282241,22347783,22413318,22478849,22544389,22609925,22675462,22740998,22806533,22937601,23003137,23068673,23134209,23199745,23265281,23330821,23396357,23461889,23527429,23592961,23658501,23724033,23789569,23855110,23920647,23986181,24051717,24117254,24182789,24248325,24313862,24379398,24444933,24510469,24576005,24641541,24707073,24772609,24838150,24903685,24969221,25034757,25100293,25165825,25231366],"core":[131073,196609,262145,327681,393217,458753,524289,589825,655364,720900,786436,851972,917508,983044,1048580,1114116,1179652,1245188,1310724,1376260,1441796,1507332,1572868,1638404,1769473,1835009,1900545,1966081,2031617,2097153,2162689,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2686977,2752513,2818049,2883585,2949121,3014657,3080193,3145729,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4259841,4325377,4390913,4456449,4653060,4718596,4784132,4849668,4915204,4980740,5046276,5111812,5177348,5242884,5308420,5373956,5439492,5505028,5570567,5636103,5701639,5767176,5832708,5898244,5963781,6029319,6094853,6160389,6225925,6291461,6356997,6422532,6488068,6553604,6619140,6684681,6750213,6815749,6881286,6946821,7012356,7077892,7143431,7208964,7274500,7340036,7405574,7471111,7536646,7602181,7667718,7733255,7798790,7864324,7929862,7995399,8060934,8126469,8192006,8257543,8323078,8388615,8454148,8519689,8585223,8650759,8716293,8781833,8847371,8912900,8978436,9043972,9109509,9175049,9240587,9306121,9371654,9437188,9502727,9568261,9633797,9699335,9764869,9830404,9895941,9961478,10027014,10092550,10158086,10223620,10289156,10354692,10420228,10485767,10551301,10616836,10682375,10747908,10813444,10878980,10944516,11010052,11075589,11141125,11206660,11272196,11337732,11403269,11468811,11534345,11599885,11665419,11730951,11796484,11862020,11927557,11993093,12058628,12124164,12189701,12320771,12386305,12451841,12517377,12582913,12648449,12713985,12779521,12845057,12910593,12976129,13041665,13107201,13172737,13238273,13303809,13369345,13434881,13500417,13565953,13631489,13697025,13762561,13828097,13893633,13959169,14024705,14090241,14155777,14221313,14286849,14352385,14417921,14483457,14548993,14614529,14680065,14745601,14811137,14876673,14942209,15007745,15073281,15138817,15204353,15269889,15335425,15400961,15466497,15532033,15597569,15663105,15728641,15794177,15859716,15925252,15990788,16056324,16121860,16187396,16252932,16318468,16384004,16449540,16515076,16580612,16646148,16711684,16777220,16842756,16908292,16973828,17039364,17104900,17170436,17235972,17301508,17367044,17432580,17498116,17563652,17629188,17694724,17760260,17825796,17891332,17956868,18022404,18087940,18153476,18219012,18284548,18350084,18415620,18481156,18546692,18612228,18677764,18743300,18808836,18874373,18939908,19005444,19070980,19136516,19202053,19267589,19333124,19398660,19464196,19529732,19595268,19660804,19726340,19791876,19857412,19922948,19988484,20054020,20119556,20185092,20250628,20316164,20381700,20447237,20512773,20578309,20643845,20709380,20774916,20840452,20905988,20971524,21037060,21102596,21168132,21233668,21299204,21364740,21430275,21561349,21626885,21692421,21757957,21823492,21889028,21954565,22020101,22085637,22151173,22216708,22282244,22347781,22413318,22478852,22544389,22609925,22675462,22740999,22806533,22872070,22937604,23003140,23068676,23134212,23199748,23265285,23330821,23396357,23461892,23527429,23592965,23658501,23724036,23789572,23855109,23920645,23986181,24051717,24117254,24182789,24248325,24313861,24379398,24444933,24510469,24576006,24641542,24707076,24772612,24838149,24903685,24969221,25034757,25100293,25165828,25231365],"channeloptions":[196611,655362,720898,786434,851970,917506,983042,1048578,1114114,12320769,22151175],"census":[196610,655366,22151170],"collection":[196609,655361,2228225,2359297,2424833,2490369,2555905,2621441,3014657,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932162,3997698,4128769,4456449,10616833,10747905,12320771,15269889,15335426,20709377,20774913,22020097,22151169,22347777,22544385,22609921,22675457,22806529,23396353,23658497,23855105,23920642,23986179,24051713,24117249,24182785,24248321,24313857,24444931,24510467,24641537,25231361],"calls":[196609,720897,2162691,2228225,3538946,6094850,6160386,6225922,6291458,6356994,6619137,10420225,10813441,12320778,12451841,15400961,20316161,21561345,21626881,21692417,21889025,21954569,22020098,22151169,22609922,23986178,24051713,24903681],"concurrent":[196609,851969,22151169],"connection":[196609,851969,2228225,6553601,22020097,22151169],"channel":[196609,917505,2228233,5636108,5701644,5767180,6422529,6488065,6553605,6619140,6684677,6750220,6815753,6946827,10944513,12320779,12517379,12582914,12648456,13959170,14090245,14221314,14352385,16515084,17498114,17563651,17629187,17694732,18022401,21823493,22020121,22085636,22151170,22216706,22282246,22347778,22675458],"check":[196609,1114113,15663105,21037057,22151169,24641537,24772609],"contextpropagationoptions":[262147,1179655,2424835,7012357,9699334,12320769,14286851,17891330,17956866,22544392],"context":[262145,1179649,3604481,6029313,7012353,9699329,12320771,14024705,17104897,21889025,22413317,22544386,22609922,22740997,24051714,24379397,24838149],"containing":[327681,1310721,2686977,4259841,11075585,11141121,11534337,13303809,22937601,23658497,24576001,24903681],"choose":[393217,1376257,24182785],"contain":[393217,1376257,24182785],"cancelled":[458754,1441794,2228226,6553601,6684673,15400961,19791873,22020098,24051713,24707074,24772610],"currentversion":[524289,1572869,25100289],"current":[524289,1572865,1769475,1835011,1900547,1966083,2031617,2097153,2228228,2293763,2359300,2424836,2490372,2555908,2621444,2949123,3014660,3211265,3276803,3342338,3407876,3473412,3538948,3604485,3670020,3735556,3801092,3866628,3932164,3997700,4063235,4128772,4194306,4456452,8912897,9764865,11337729,12320769,14090241,14483457,15269891,17563649,21561347,21626883,21692419,21757955,21823489,21889025,22020101,22085635,22347780,22544388,22609924,22675460,22806532,22937601,23330819,23396356,23592961,23658499,23724034,23855108,23920647,23986180,24051717,24117252,24182788,24248324,24313860,24444932,24510468,24576003,24641540,24707074,25100290,25231364],"copy":[655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572865,1638401,2228225,2359297,2424833,2490369,2555905,2621441,3014657,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6094849,6160385,6225921,6291457,6356993,6422529,6488065,6553601,6619137,6684673,6750209,6815745,6881281,6946817,7012353,7077889,7143425,7208961,7274497,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7864321,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388609,8454145,8519681,8585217,8650753,8716289,8781825,8847361,8912897,8978433,9043969,9109505,9175041,9240577,9306113,9371649,9437185,9502721,9568257,9633793,9699329,9764865,9830401,9895937,9961473,10027009,10092545,10158081,10223617,10289153,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11337729,11403265,11468801,11534337,11599873,11665409,11730945,11796481,11862017,11927553,11993089,12058625,12124161,12189697,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18153473,18219009,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19267585,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020098,22085633,22151169,22216705,22282241,22347778,22413313,22478849,22544386,22609922,22675458,22740993,22806530,22872065,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396354,23461889,23527425,23592961,23658497,23724033,23789569,23855106,23920642,23986178,24051714,24117250,24182786,24248322,24313858,24379393,24444930,24510466,24576001,24641538,24707073,24772609,24838145,24903681,24969217,25034753,25100289,25165825,25231362],"const":[655362,720898,786434,851970,917506,983042,1048578,1114114,1245186,1376258,1572866],"creates":[1703938,2228225,2359298,2424833,2490369,2555905,2621441,2686977,3014657,3145729,3407873,3473410,3538945,3604482,3670017,3735553,3801090,3866626,3932161,3997697,4128769,4259841,4456449,4521985,4587521,6029313,6422529,6488065,6750209,6815745,6881281,7012353,7340033,7864321,8388609,9568257,9633793,9699329,9895937,10223617,10289153,10354689,11010049,11075585,11141121,11206657,11272193,11403265,11534337,12582914,12648450,13107202,13303811,13369346,21495810,21889025,22020099,22085634,22347778,22544386,22609921,22675457,22806529,22937601,23330817,23396354,23527425,23855105,23920644,23986177,24051714,24117249,24182786,24248322,24313859,24444929,24510465,24576003,24641539,24707073,24903681,25231361],"credential":[1703937,4587527,14352385,15466497,18022401,20381697,21495809,22675457,24117249],"cleanup":[1769473,1835009,1900545,1966081,2228225,2359297,2424833,2490369,2555905,2621441,3014657,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,4653057,4915201,5111809,5308417,21561345,21626881,21692417,21757953,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"call":[1769482,1835017,1900553,1966090,2162693,2228225,2359297,3604484,3932161,3997697,4653062,4784130,4849666,4915205,4980738,5046274,5111813,5177346,5242882,5308422,5439490,5505026,5636099,5701635,5767170,6029316,6094856,6160392,6225928,6291464,6356999,6553601,6881283,6946817,7012354,9568257,9633793,9699330,9764866,10485761,10682369,11468802,11534338,11599874,11665410,12320788,13238273,13697025,13893633,13959170,14024709,14221313,14286850,15269890,15400961,15925249,16384001,16515073,16711681,16908289,16973825,17039361,17104897,17170433,17760257,17891329,17956865,19726337,19791873,21561357,21626891,21692426,21757965,21823493,21889029,21954565,22020098,22347778,22413313,22544386,22609922,22740993,22872065,23658501,23920644,24051718,24248321,24379393,24444929,24510465,24772609,24838145],"completed":[1769473,1835009,1966081,4653057,4915201,5308417,21561345,21626881,21757953,24772609],"cancellation":[1769473,1835009,1900545,1966081,4653057,4915201,5111809,5308417,5832705,6029313,7012353,12320769,14286849,15400961,17891329,19791873,21561345,21626881,21692417,21757953,22544385,22609921,24051713],"callinvocationdetails":[2031620,5570569,5636103,5701639,5767175,6094853,6160389,6225925,6291461,6356997,6881285,12320769,12517384,13959171,16515074,16580610,16646146,16711682,16777218,16842754,21823501],"code":[2031617,2097153,3211265,3342337,4194305,11403265,12320769,12451841,15728641,21299201,21823489,21889025,23592961,23724033,24248321,24707074,25034753],"calloptions":[2097158,5570566,5636102,5701638,5767174,5832712,5898248,5963784,6029318,6881285,12320769,12517379,14024707,16711686,16908290,16973826,17039362,17104898,17170434,21823491,21889035],"cancellationtoken":[2097153,5832715,6029324,14024705,15400961,16908299,19791883,21889026,24051713],"client":[2162693,3604481,3866625,6094851,6160385,6225921,9764865,9961473,11010049,11075585,11141121,11206658,11272195,12255234,12320780,13172737,13303811,13369346,14221314,15400963,15597570,15663106,17694721,17760257,20119553,20185089,20250625,20905986,21037057,21168129,21430273,21495810,21561345,21823489,21889025,21954566,22020097,22347779,22413313,22675457,23068673,23658497,23789572,24051716,24313857,24576006,24641540,24772609],"completely":[2162689,6160385,21954561,25165825],"connectasync":[2228225,6553605,22020097],"connect":[2228225,6553601,22020097],"completes":[2228226,2818050,4259841,6553601,6684673,7274497,11599873,13434881,22020098,23068674,24903681],"case":[2228225,6553601,22020097],"cleans":[2228225,3538945,6619137,10813441,22020097,23986177],"channeloption":[2293763,6422534,6488070,6750214,6815750,10944517,12320771,12582916,12648450,14155783,17235971,17301507,17367043,17432585,22020098,22085645,22216706],"clientbase":[2359299,6881282,6946822,12255233,12320769,14221315,17694722,17760258,17825794,21495809,22347785],"createcall":[2359297,6881285,22347777],"contextpropagationtoken":[2490371,6029317,9699333,12320770,17104902,22544385,22609927],"credentials":[2555907,6750220,6815756,7077894,9895942,10551302,11010049,11075585,11141121,11206657,11272193,12320773,12648450,13303811,13369346,14352387,15532033,18022408,20512775,22020098,22675466,24117249,24182785,24576009,24641539,24772609],"completeasync":[2818049,7274501,23068673],"closes":[2818049,7274497,23068673],"called":[2818049,3604481,7274497,9764865,13959169,15400962,16646145,19922945,19988481,21823489,23068673,24051715],"calling":[2818049,7274497,23068673],"close":[2818049,4259841,11599873,12320769,13434881,23068674,24903681],"consolelogger":[3014659,7405572,7471109,7536644,7602179,7667716,7733253,7798788,7864325,12386305,12713986,12779522,23396360],"clear":[3276801,8716296,23658497],"copyto":[3276801,8847370,23658497],"cause":[3473409,23920641],"cancelling":[3538945,10420225,14024705,16908289,21889025,23986177],"complete":[3538946,10420225,10813441,11599880,23986178,24772609],"createpropagationtoken":[3604481,9699334,24051713],"child":[3604481,7012354,9699329,12320770,14286850,17891329,17956865,22544386,22609922,24051713],"createbuilder":[3801089,10354693,24248321],"clientstreamingservermethod":[3866625,9961478,12320769,13172737,22413317,24313857],"checkargument":[4390914,11796486,11862022,13500419,25034754],"condition":[4390916,11796487,11862023,12058631,12124167,13500418,13631490,24772609,25034756],"checknotnull":[4390914,11927559,11993095,13565955,25034754],"checkstate":[4390914,12058630,12124166,13631491,25034754],"constructor":[5636097,5701633,5767169,6029313,6422529,6488065,6750209,6815745,6946817,7012353,7077889,7340033,7864321,8454145,8978433,9043969,9437185,9502721,9568257,9633793,9830401,9895937,10289153,10944513,11010049,11075585,11141121,11206658,11272193,11403265,12189697,12517377,12582913,12648449,13041665,13107201,13303809,13369346,24641537],"channelstate":[6684679,12320769,17563654,22282245],"connects":[6750209,6815745,12648450,22020098],"collections":[6750209,6815745,10944513,11206657,11272193,11599877,11665412],"cal":[7012354,14286850,17891329,17956865,22544386],"customlogger":[7143430],"certificate":[7340034,11141121,12320769,14876673,15597570,15663105,18546689,20905986,21102593,23330819,24576002,24641537],"chain":[7340034,14876673,18546689,23330818],"certificatechain":[7340037,14876673,18546693,23330817],"console":[7864321,12386305,23396354],"char":[8388610,8454146,8585217,8978433,18743298,18808834,19136514],"characters":[9043969],"chosen":[9895937,10551297],"certificates":[11010049,11075585,11141121,11206658,11272194,13303810,13369345,15597569,15663105,20971521,21168129,24576003,24641538],"ctor":[11075585],"currently":[12255233,21430273,24772609],"consists":[12255233,12320769,21430273,24707073],"classes":[12255234,12320769,12386305,12451841,21495809],"created":[12255233,12320769,21495809,24248321],"concepts":[12320769,21430273],"clients":[12320769,21954561],"channels":[12320769,22020097],"connections":[12320769,22020097],"creating":[12320771,14352385,15466497,18022401,20381697,22020097,22085633,22675457,23527425,24117249],"compared":[12320769,22020097],"corresponds":[12320769,22085633],"contexts":[12320769,22609921],"creation":[12320769,22675457],"capability":[12320769,23068673],"connectivity":[12320769,14090241,17563649,22020097,22282241],"compressionlevel":[12320769,22478853],"compression":[12320770,22478854,25165825],"checking":[12451841,25034753],"custom":[14221313,17760257,22347777],"count":[15073281,18874376,23658497],"coded":[15269889,23920641],"caused":[15269889,23920641,24772609],"causes":[15269889,23920641],"convenience":[15400961,20316161,24051713],"constructors":[21823489,21889025,22020097,22085633,22347777,22544385,22675457,23330817,23396353,23592961,23658497,23724033,23855105,23920641,23986177,24117249,24182785,24313857,24576001,24641537,24707073,25231361],"connecting":[22282242],"clientstreaming":[23789569],"caller":[24772611],"converted":[24772609],"change":[24772609],"concurrency":[24772609],"corrected":[24772609],"corruption":[24772609],"completion":[25165825]} \ No newline at end of file +{"create":[131073,3145729,8388616,10944513,12255233,14090241,17629185,21495809,22020097,23527425,23920641,23986177,24772609],"contains":[131073,3276801,5701633,5767169,8781833,12320769,21430273,23658497,23920641],"class":[131073,196609,262145,327681,393217,524289,589825,655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1572865,1638401,1703937,1769473,1835009,1900545,1966081,2162689,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2949121,3014657,3145729,3211265,3276801,3407873,3473411,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4259841,4325377,4390913,4456449,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,6094855,6160391,6225927,6291463,6356999,6422529,6488065,6553601,6619137,6684673,6750209,6815745,6881287,6946818,7012353,7077890,7143425,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7864321,8388609,8454145,8519681,8585217,8650753,8716289,8781825,8847361,9109505,9175041,9240577,9306113,9371649,9437185,9502722,9568257,9633793,9699329,9764865,9830402,9895937,9961481,10027017,10092553,10158089,10223617,10289153,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11468804,11534340,11599876,11665412,11730945,11796481,11862017,11927553,11993089,12058625,12124161,12189698,12255233,12320772,12386305,12451841,12582913,12648449,12713985,12779521,12976129,13107201,13172737,13238273,13303809,13369345,13434881,13500417,13565953,13631489,13697025,13762561,13828097,13893633,14090241,14155777,14221313,14286849,14352385,14417921,14876673,14942209,15007745,15073281,15204353,15269889,15335425,15400961,15466497,15532033,15597569,15663105,15794177,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18546689,18612225,18677761,18743297,18808833,18874369,19202049,19267585,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21364737,21495813,21561349,21626885,21692421,21757957,21823489,21889025,21954566,22020101,22085637,22151173,22216705,22282241,22347783,22413318,22478849,22544389,22609925,22675462,22740998,22806533,22937601,23003137,23068673,23134209,23199745,23265281,23330821,23396357,23461889,23527429,23592965,23658501,23724033,23789569,23855110,23920647,23986181,24051717,24117254,24182789,24248325,24313862,24379398,24444933,24510469,24576005,24641541,24707073,24772609,24838150,24903685,24969221,25034757,25100293,25165825,25231366],"core":[131073,196609,262145,327681,393217,458753,524289,589825,655364,720900,786436,851972,917508,983044,1048580,1114116,1179652,1245188,1310724,1376260,1441796,1507332,1572868,1638404,1769473,1835009,1900545,1966081,2031617,2097153,2162689,2228225,2293761,2359297,2424833,2490369,2555905,2621441,2686977,2752513,2818049,2883585,2949121,3014657,3080193,3145729,3211265,3276801,3342337,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4063233,4128769,4194305,4259841,4325377,4390913,4456449,4653060,4718596,4784132,4849668,4915204,4980740,5046276,5111812,5177348,5242884,5308420,5373956,5439492,5505028,5570567,5636103,5701639,5767176,5832708,5898244,5963781,6029319,6094853,6160389,6225925,6291461,6356997,6422532,6488068,6553604,6619140,6684681,6750213,6815749,6881286,6946821,7012356,7077892,7143431,7208964,7274500,7340036,7405574,7471111,7536646,7602181,7667718,7733255,7798790,7864324,7929862,7995399,8060934,8126469,8192006,8257543,8323078,8388615,8454148,8519689,8585223,8650759,8716293,8781833,8847371,8912900,8978436,9043972,9109509,9175049,9240587,9306121,9371654,9437188,9502727,9568261,9633797,9699335,9764869,9830404,9895941,9961478,10027014,10092550,10158086,10223620,10289156,10354692,10420228,10485767,10551301,10616836,10682375,10747908,10813444,10878980,10944516,11010052,11075589,11141125,11206660,11272196,11337732,11403269,11468811,11534345,11599885,11665419,11730951,11796484,11862020,11927557,11993093,12058628,12124164,12189701,12320771,12386305,12451841,12517377,12582913,12648449,12713985,12779521,12845057,12910593,12976129,13041665,13107201,13172737,13238273,13303809,13369345,13434881,13500417,13565953,13631489,13697025,13762561,13828097,13893633,13959169,14024705,14090241,14155777,14221313,14286849,14352385,14417921,14483457,14548993,14614529,14680065,14745601,14811137,14876673,14942209,15007745,15073281,15138817,15204353,15269889,15335425,15400961,15466497,15532033,15597569,15663105,15728641,15794177,15859716,15925252,15990788,16056324,16121860,16187396,16252932,16318468,16384004,16449540,16515076,16580612,16646148,16711684,16777220,16842756,16908292,16973828,17039364,17104900,17170436,17235972,17301508,17367044,17432580,17498116,17563652,17629188,17694724,17760260,17825796,17891332,17956868,18022404,18087940,18153476,18219012,18284548,18350084,18415620,18481156,18546692,18612228,18677764,18743300,18808836,18874373,18939908,19005444,19070980,19136516,19202053,19267589,19333124,19398660,19464196,19529732,19595268,19660804,19726340,19791876,19857412,19922948,19988484,20054020,20119556,20185092,20250628,20316164,20381700,20447237,20512773,20578309,20643845,20709380,20774916,20840452,20905988,20971524,21037060,21102596,21168132,21233668,21299204,21364740,21430275,21561349,21626885,21692421,21757957,21823492,21889028,21954565,22020101,22085637,22151173,22216708,22282244,22347781,22413318,22478852,22544389,22609925,22675462,22740999,22806533,22872070,22937604,23003140,23068676,23134212,23199748,23265285,23330821,23396357,23461892,23527429,23592966,23658501,23724036,23789572,23855109,23920645,23986181,24051717,24117254,24182789,24248325,24313861,24379398,24444933,24510469,24576006,24641542,24707076,24772612,24838149,24903685,24969221,25034757,25100293,25165828,25231365],"channeloptions":[196611,655362,720898,786434,851970,917506,983042,1048578,1114114,12320769,22151175],"census":[196610,655366,22151170],"collection":[196609,655361,2228225,2359297,2424833,2490369,2555905,2621441,3014657,3211265,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932162,3997698,4128769,4456449,10616833,10747905,12320771,15269889,15335426,20709377,20774913,22020097,22151169,22347777,22544385,22609921,22675457,22806529,23396353,23592961,23658497,23855105,23920642,23986179,24051713,24117249,24182785,24248321,24313857,24444931,24510467,24641537,25231361],"calls":[196609,720897,2162691,2228225,3538946,6094850,6160386,6225922,6291458,6356994,6619137,10420225,10813441,12320778,12451841,15400961,20316161,21561345,21626881,21692417,21889025,21954569,22020098,22151169,22609922,23986178,24051713,24903681],"concurrent":[196609,851969,22151169],"connection":[196609,851969,2228225,6553601,22020097,22151169],"channel":[196609,917505,2228233,5636108,5701644,5767180,6422529,6488065,6553605,6619140,6684677,6750220,6815753,6946827,10944513,12320779,12517379,12582914,12648456,13959170,14090245,14221314,14352385,16515084,17498114,17563651,17629187,17694732,18022401,21823493,22020121,22085636,22151170,22216706,22282246,22347778,22675458],"check":[196609,1114113,15663105,21037057,22151169,24641537,24772609],"contextpropagationoptions":[262147,1179655,2424835,7012357,9699334,12320769,14286851,17891330,17956866,22544392],"context":[262145,1179649,3604481,6029313,7012353,9699329,12320771,14024705,17104897,21889025,22413317,22544386,22609922,22740997,24051714,24379397,24838149],"containing":[327681,1310721,2686977,4259841,11075585,11141121,11534337,13303809,22937601,23658497,24576001,24903681],"choose":[393217,1376257,24182785],"contain":[393217,1376257,24182785],"cancelled":[458754,1441794,2228226,6553601,6684673,15400961,19791873,22020098,24051713,24707074,24772610],"currentversion":[524289,1572869,25100289],"current":[524289,1572865,1769475,1835011,1900547,1966083,2031617,2097153,2228228,2293763,2359300,2424836,2490372,2555908,2621444,2949123,3014660,3211268,3276803,3342338,3407876,3473412,3538948,3604485,3670020,3735556,3801092,3866628,3932164,3997700,4063235,4128772,4194306,4456452,8912897,9764865,11337729,12320769,14090241,14483457,15269891,17563649,21561347,21626883,21692419,21757955,21823489,21889025,22020101,22085635,22347780,22544388,22609924,22675460,22806532,22937601,23330819,23396356,23592964,23658499,23724034,23855108,23920647,23986180,24051717,24117252,24182788,24248324,24313860,24444932,24510468,24576003,24641540,24707074,25100290,25231364],"copy":[655361,720897,786433,851969,917505,983041,1048577,1114113,1179649,1245185,1310721,1376257,1441793,1507329,1572865,1638401,2228225,2359297,2424833,2490369,2555905,2621441,3014657,3211265,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,4521985,4587521,4653057,4718593,4784129,4849665,4915201,4980737,5046273,5111809,5177345,5242881,5308417,5373953,5439489,5505025,5570561,5636097,5701633,5767169,5832705,5898241,5963777,6029313,6094849,6160385,6225921,6291457,6356993,6422529,6488065,6553601,6619137,6684673,6750209,6815745,6881281,6946817,7012353,7077889,7143425,7208961,7274497,7340033,7405569,7471105,7536641,7602177,7667713,7733249,7798785,7864321,7929857,7995393,8060929,8126465,8192001,8257537,8323073,8388609,8454145,8519681,8585217,8650753,8716289,8781825,8847361,8912897,8978433,9043969,9109505,9175041,9240577,9306113,9371649,9437185,9502721,9568257,9633793,9699329,9764865,9830401,9895937,9961473,10027009,10092545,10158081,10223617,10289153,10354689,10420225,10485761,10551297,10616833,10682369,10747905,10813441,10878977,10944513,11010049,11075585,11141121,11206657,11272193,11337729,11403265,11468801,11534337,11599873,11665409,11730945,11796481,11862017,11927553,11993089,12058625,12124161,12189697,15859713,15925249,15990785,16056321,16121857,16187393,16252929,16318465,16384001,16449537,16515073,16580609,16646145,16711681,16777217,16842753,16908289,16973825,17039361,17104897,17170433,17235969,17301505,17367041,17432577,17498113,17563649,17629185,17694721,17760257,17825793,17891329,17956865,18022401,18087937,18153473,18219009,18284545,18350081,18415617,18481153,18546689,18612225,18677761,18743297,18808833,18874369,18939905,19005441,19070977,19136513,19202049,19267585,19333121,19398657,19464193,19529729,19595265,19660801,19726337,19791873,19857409,19922945,19988481,20054017,20119553,20185089,20250625,20316161,20381697,20447233,20512769,20578305,20643841,20709377,20774913,20840449,20905985,20971521,21037057,21102593,21168129,21233665,21299201,21364737,21495809,21561345,21626881,21692417,21757953,21823489,21889025,21954561,22020098,22085633,22151169,22216705,22282241,22347778,22413313,22478849,22544386,22609922,22675458,22740993,22806530,22872065,22937601,23003137,23068673,23134209,23199745,23265281,23330817,23396354,23461889,23527425,23592962,23658497,23724033,23789569,23855106,23920642,23986178,24051714,24117250,24182786,24248322,24313858,24379393,24444930,24510466,24576001,24641538,24707073,24772609,24838145,24903681,24969217,25034753,25100289,25165825,25231362],"const":[655362,720898,786434,851970,917506,983042,1048578,1114114,1245186,1376258,1572866],"creates":[1703938,2228225,2359298,2424833,2490369,2555905,2621441,2686977,3014657,3145729,3211265,3407873,3473410,3538945,3604482,3670017,3735553,3801090,3866626,3932161,3997697,4128769,4259841,4456449,4521985,4587521,6029313,6422529,6488065,6750209,6815745,6881281,7012353,7340033,7864321,8388609,9568257,9633793,9699329,9895937,10223617,10289153,10354689,11010049,11075585,11141121,11206657,11272193,11403265,11534337,12582914,12648450,13107202,13303811,13369346,21495810,21889025,22020099,22085634,22347778,22544386,22609921,22675457,22806529,22937601,23330817,23396354,23527425,23592961,23855105,23920644,23986177,24051714,24117249,24182786,24248322,24313859,24444929,24510465,24576003,24641539,24707073,24903681,25231361],"credential":[1703937,4587527,14352385,15466497,18022401,20381697,21495809,22675457,24117249],"cleanup":[1769473,1835009,1900545,1966081,2228225,2359297,2424833,2490369,2555905,2621441,3014657,3211265,3407873,3473409,3538945,3604481,3670017,3735553,3801089,3866625,3932161,3997697,4128769,4456449,4653057,4915201,5111809,5308417,21561345,21626881,21692417,21757953,22020097,22347777,22544385,22609921,22675457,22806529,23396353,23592961,23855105,23920641,23986177,24051713,24117249,24182785,24248321,24313857,24444929,24510465,24641537,25231361],"call":[1769482,1835017,1900553,1966090,2162693,2228225,2359297,3604484,3932161,3997697,4653062,4784130,4849666,4915205,4980738,5046274,5111813,5177346,5242882,5308422,5439490,5505026,5636099,5701635,5767170,6029316,6094856,6160392,6225928,6291464,6356999,6553601,6881283,6946817,7012354,9568257,9633793,9699330,9764866,10485761,10682369,11468802,11534338,11599874,11665410,12320788,13238273,13697025,13893633,13959170,14024709,14221313,14286850,15269890,15400961,15925249,16384001,16515073,16711681,16908289,16973825,17039361,17104897,17170433,17760257,17891329,17956865,19726337,19791873,21561357,21626891,21692426,21757965,21823493,21889029,21954565,22020098,22347778,22413313,22544386,22609922,22740993,22872065,23658501,23920644,24051718,24248321,24379393,24444929,24510465,24772609,24838145],"completed":[1769473,1835009,1966081,4653057,4915201,5308417,21561345,21626881,21757953,24772609],"cancellation":[1769473,1835009,1900545,1966081,4653057,4915201,5111809,5308417,5832705,6029313,7012353,12320769,14286849,15400961,17891329,19791873,21561345,21626881,21692417,21757953,22544385,22609921,24051713],"callinvocationdetails":[2031620,5570569,5636103,5701639,5767175,6094853,6160389,6225925,6291461,6356997,6881285,12320769,12517384,13959171,16515074,16580610,16646146,16711682,16777218,16842754,21823501],"code":[2031617,2097153,3342337,4194305,11403265,12320769,12451841,15728641,21299201,21823489,21889025,23724033,24248321,24707074,25034753],"calloptions":[2097158,5570566,5636102,5701638,5767174,5832712,5898248,5963784,6029318,6881285,12320769,12517379,14024707,16711686,16908290,16973826,17039362,17104898,17170434,21823491,21889035],"cancellationtoken":[2097153,5832715,6029324,14024705,15400961,16908299,19791883,21889026,24051713],"client":[2162693,3604481,3866625,6094851,6160385,6225921,9764865,9961473,11010049,11075585,11141121,11206658,11272195,12255234,12320780,13172737,13303811,13369346,14221314,15400963,15597570,15663106,17694721,17760257,20119553,20185089,20250625,20905986,21037057,21168129,21430273,21495810,21561345,21823489,21889025,21954566,22020097,22347779,22413313,22675457,23068673,23658497,23789572,24051716,24313857,24576006,24641540,24772609],"completely":[2162689,6160385,21954561,25165825],"connectasync":[2228225,6553605,22020097],"connect":[2228225,6553601,22020097],"completes":[2228226,2818050,4259841,6553601,6684673,7274497,11599873,13434881,22020098,23068674,24903681],"case":[2228225,6553601,22020097],"cleans":[2228225,3538945,6619137,10813441,22020097,23986177],"channeloption":[2293763,6422534,6488070,6750214,6815750,10944517,12320771,12582916,12648450,14155783,17235971,17301507,17367043,17432585,22020098,22085645,22216706],"clientbase":[2359299,6881282,6946822,12255233,12320769,14221315,17694722,17760258,17825794,21495809,22347785],"createcall":[2359297,6881285,22347777],"contextpropagationtoken":[2490371,6029317,9699333,12320770,17104902,22544385,22609927],"credentials":[2555907,6750220,6815756,7077894,9895942,10551302,11010049,11075585,11141121,11206657,11272193,12320773,12648450,13303811,13369346,14352387,15532033,18022408,20512775,22020098,22675466,24117249,24182785,24576009,24641539,24772609],"completeasync":[2818049,7274501,23068673],"closes":[2818049,7274497,23068673],"called":[2818049,3604481,7274497,9764865,13959169,15400962,16646145,19922945,19988481,21823489,23068673,24051715],"calling":[2818049,7274497,23068673],"close":[2818049,4259841,11599873,12320769,13434881,23068674,24903681],"consolelogger":[3014659,7405572,7471109,7536644,7602179,7667716,7733253,7798788,7864325,12386305,12713986,12779522,23396360],"clear":[3276801,8716296,23658497],"copyto":[3276801,8847370,23658497],"cause":[3473409,23920641],"cancelling":[3538945,10420225,14024705,16908289,21889025,23986177],"complete":[3538946,10420225,10813441,11599880,23986178,24772609],"createpropagationtoken":[3604481,9699334,24051713],"child":[3604481,7012354,9699329,12320770,14286850,17891329,17956865,22544386,22609922,24051713],"createbuilder":[3801089,10354693,24248321],"clientstreamingservermethod":[3866625,9961478,12320769,13172737,22413317,24313857],"checkargument":[4390914,11796486,11862022,13500419,25034754],"condition":[4390916,11796487,11862023,12058631,12124167,13500418,13631490,24772609,25034756],"checknotnull":[4390914,11927559,11993095,13565955,25034754],"checkstate":[4390914,12058630,12124166,13631491,25034754],"constructor":[5636097,5701633,5767169,6029313,6422529,6488065,6750209,6815745,6946817,7012353,7077889,7340033,7864321,8454145,8978433,9043969,9437185,9502721,9568257,9633793,9830401,9895937,10289153,10944513,11010049,11075585,11141121,11206658,11272193,11403265,12189697,12517377,12582913,12648449,13041665,13107201,13303809,13369346,24641537],"channelstate":[6684679,12320769,17563654,22282245],"connects":[6750209,6815745,12648450,22020098],"collections":[6750209,6815745,10944513,11206657,11272193,11599877,11665412],"cal":[7012354,14286850,17891329,17956865,22544386],"customlogger":[7143430],"certificate":[7340034,11141121,12320769,14876673,15597570,15663105,18546689,20905986,21102593,23330819,24576002,24641537],"chain":[7340034,14876673,18546689,23330818],"certificatechain":[7340037,14876673,18546693,23330817],"console":[7864321,12386305,23396354],"char":[8388610,8454146,8585217,8978433,18743298,18808834,19136514],"characters":[9043969],"chosen":[9895937,10551297],"certificates":[11010049,11075585,11141121,11206658,11272194,13303810,13369345,15597569,15663105,20971521,21168129,24576003,24641538],"ctor":[11075585],"currently":[12255233,21430273,24772609],"consists":[12255233,12320769,21430273,24707073],"classes":[12255234,12320769,12386305,12451841,21495809],"created":[12255233,12320769,21495809,24248321],"concepts":[12320769,21430273],"clients":[12320769,21954561],"channels":[12320769,22020097],"connections":[12320769,22020097],"creating":[12320771,14352385,15466497,18022401,20381697,22020097,22085633,22675457,23527425,24117249],"compared":[12320769,22020097],"corresponds":[12320769,22085633],"contexts":[12320769,22609921],"creation":[12320769,22675457],"capability":[12320769,23068673],"connectivity":[12320769,14090241,17563649,22020097,22282241],"compressionlevel":[12320769,22478853],"compression":[12320770,22478854,25165825],"checking":[12451841,25034753],"custom":[14221313,17760257,22347777],"count":[15073281,18874376,23658497],"coded":[15269889,23920641],"caused":[15269889,23920641,24772609],"causes":[15269889,23920641],"convenience":[15400961,20316161,24051713],"constructors":[21823489,21889025,22020097,22085633,22347777,22544385,22675457,23330817,23396353,23592961,23658497,23724033,23855105,23920641,23986177,24117249,24182785,24313857,24576001,24641537,24707073,25231361],"connecting":[22282242],"clientstreaming":[23789569],"caller":[24772611],"converted":[24772609],"change":[24772609],"concurrency":[24772609],"corrected":[24772609],"corruption":[24772609],"completion":[25165825]} \ No newline at end of file diff --git a/doc/ref/csharp/html/fti/FTI_Files.json b/doc/ref/csharp/html/fti/FTI_Files.json index 7439f6f829..78844e03e2 100644 --- a/doc/ref/csharp/html/fti/FTI_Files.json +++ b/doc/ref/csharp/html/fti/FTI_Files.json @@ -1 +1 @@ -["gRPC C# - Redirect\u0000index.html\u000018","gRPC C# - Search\u0000search.html\u000012","RpcException Events\u0000html/Events_T_Grpc_Core_RpcException.htm\u000055","ChannelOptions Fields\u0000html/Fields_T_Grpc_Core_ChannelOptions.htm\u0000111","ContextPropagationOptions Fields\u0000html/Fields_T_Grpc_Core_ContextPropagationOptions.htm\u000039","Metadata Fields\u0000html/Fields_T_Grpc_Core_Metadata.htm\u000047","ServerPort Fields\u0000html/Fields_T_Grpc_Core_ServerPort.htm\u000060","Status Fields\u0000html/Fields_T_Grpc_Core_Status.htm\u000057","VersionInfo Fields\u0000html/Fields_T_Grpc_Core_VersionInfo.htm\u000032","WriteOptions Fields\u0000html/Fields_T_Grpc_Core_WriteOptions.htm\u000032","ChannelOptions.Census Field\u0000html/F_Grpc_Core_ChannelOptions_Census.htm\u000082","ChannelOptions.DefaultAuthority Field\u0000html/F_Grpc_Core_ChannelOptions_DefaultAuthority.htm\u000080","ChannelOptions.Http2InitialSequenceNumber Field\u0000html/F_Grpc_Core_ChannelOptions_Http2InitialSequenceNumber.htm\u000081","ChannelOptions.MaxConcurrentStreams Field\u0000html/F_Grpc_Core_ChannelOptions_MaxConcurrentStreams.htm\u000087","ChannelOptions.MaxMessageLength Field\u0000html/F_Grpc_Core_ChannelOptions_MaxMessageLength.htm\u000083","ChannelOptions.PrimaryUserAgentString Field\u0000html/F_Grpc_Core_ChannelOptions_PrimaryUserAgentString.htm\u000088","ChannelOptions.SecondaryUserAgentString Field\u0000html/F_Grpc_Core_ChannelOptions_SecondaryUserAgentString.htm\u000088","ChannelOptions.SslTargetNameOverride Field\u0000html/F_Grpc_Core_ChannelOptions_SslTargetNameOverride.htm\u000087","ContextPropagationOptions.Default Field\u0000html/F_Grpc_Core_ContextPropagationOptions_Default.htm\u000088","Metadata.BinaryHeaderSuffix Field\u0000html/F_Grpc_Core_Metadata_BinaryHeaderSuffix.htm\u000083","Metadata.Empty Field\u0000html/F_Grpc_Core_Metadata_Empty.htm\u000087","ServerPort.PickUnused Field\u0000html/F_Grpc_Core_ServerPort_PickUnused.htm\u0000105","Status.DefaultCancelled Field\u0000html/F_Grpc_Core_Status_DefaultCancelled.htm\u000089","Status.DefaultSuccess Field\u0000html/F_Grpc_Core_Status_DefaultSuccess.htm\u000089","VersionInfo.CurrentVersion Field\u0000html/F_Grpc_Core_VersionInfo_CurrentVersion.htm\u000079","WriteOptions.Default Field\u0000html/F_Grpc_Core_WriteOptions_Default.htm\u000081","AuthInterceptors Methods\u0000html/Methods_T_Grpc_Auth_AuthInterceptors.htm\u000065","AsyncClientStreamingCall(TRequest, TResponse) Methods\u0000html/Methods_T_Grpc_Core_AsyncClientStreamingCall_2.htm\u0000215","AsyncDuplexStreamingCall(TRequest, TResponse) Methods\u0000html/Methods_T_Grpc_Core_AsyncDuplexStreamingCall_2.htm\u0000209","AsyncServerStreamingCall(TResponse) Methods\u0000html/Methods_T_Grpc_Core_AsyncServerStreamingCall_1.htm\u0000196","AsyncUnaryCall(TResponse) Methods\u0000html/Methods_T_Grpc_Core_AsyncUnaryCall_1.htm\u0000208","CallInvocationDetails(TRequest, TResponse) Methods\u0000html/Methods_T_Grpc_Core_CallInvocationDetails_2.htm\u0000132","CallOptions Methods\u0000html/Methods_T_Grpc_Core_CallOptions.htm\u0000162","Calls Methods\u0000html/Methods_T_Grpc_Core_Calls.htm\u0000160","Channel Methods\u0000html/Methods_T_Grpc_Core_Channel.htm\u0000258","ChannelOption Methods\u0000html/Methods_T_Grpc_Core_ChannelOption.htm\u000095","ClientBase Methods\u0000html/Methods_T_Grpc_Core_ClientBase.htm\u0000154","ContextPropagationOptions Methods\u0000html/Methods_T_Grpc_Core_ContextPropagationOptions.htm\u0000142","ContextPropagationToken Methods\u0000html/Methods_T_Grpc_Core_ContextPropagationToken.htm\u0000142","Credentials Methods\u0000html/Methods_T_Grpc_Core_Credentials.htm\u0000142","GrpcEnvironment Methods\u0000html/Methods_T_Grpc_Core_GrpcEnvironment.htm\u0000155","IAsyncStreamReader(T) Methods\u0000html/Methods_T_Grpc_Core_IAsyncStreamReader_1.htm\u0000113","IAsyncStreamWriter(T) Methods\u0000html/Methods_T_Grpc_Core_IAsyncStreamWriter_1.htm\u000047","IClientStreamWriter(T) Methods\u0000html/Methods_T_Grpc_Core_IClientStreamWriter_1.htm\u0000113","IServerStreamWriter(T) Methods\u0000html/Methods_T_Grpc_Core_IServerStreamWriter_1.htm\u000079","KeyCertificatePair Methods\u0000html/Methods_T_Grpc_Core_KeyCertificatePair.htm\u000095","ConsoleLogger Methods\u0000html/Methods_T_Grpc_Core_Logging_ConsoleLogger.htm\u0000234","ILogger Methods\u0000html/Methods_T_Grpc_Core_Logging_ILogger.htm\u0000119","Marshallers Methods\u0000html/Methods_T_Grpc_Core_Marshallers.htm\u000038","Marshaller(T) Methods\u0000html/Methods_T_Grpc_Core_Marshaller_1.htm\u0000100","Metadata Methods\u0000html/Methods_T_Grpc_Core_Metadata.htm\u0000118","Entry Methods\u0000html/Methods_T_Grpc_Core_Metadata_Entry.htm\u000099","Method(TRequest, TResponse) Methods\u0000html/Methods_T_Grpc_Core_Method_2.htm\u0000153","RpcException Methods\u0000html/Methods_T_Grpc_Core_RpcException.htm\u0000199","Server Methods\u0000html/Methods_T_Grpc_Core_Server.htm\u0000198","ServerCallContext Methods\u0000html/Methods_T_Grpc_Core_ServerCallContext.htm\u0000211","ServerCredentials Methods\u0000html/Methods_T_Grpc_Core_ServerCredentials.htm\u0000142","ServerPort Methods\u0000html/Methods_T_Grpc_Core_ServerPort.htm\u0000142","ServerServiceDefinition Methods\u0000html/Methods_T_Grpc_Core_ServerServiceDefinition.htm\u0000152","Builder Methods\u0000html/Methods_T_Grpc_Core_ServerServiceDefinition_Builder.htm\u0000261","ServerPortCollection Methods\u0000html/Methods_T_Grpc_Core_Server_ServerPortCollection.htm\u0000215","ServiceDefinitionCollection Methods\u0000html/Methods_T_Grpc_Core_Server_ServiceDefinitionCollection.htm\u0000181","SslCredentials Methods\u0000html/Methods_T_Grpc_Core_SslCredentials.htm\u000095","SslServerCredentials Methods\u0000html/Methods_T_Grpc_Core_SslServerCredentials.htm\u0000142","Status Methods\u0000html/Methods_T_Grpc_Core_Status.htm\u000096","AsyncStreamExtensions Methods\u0000html/Methods_T_Grpc_Core_Utils_AsyncStreamExtensions.htm\u0000113","BenchmarkUtil Methods\u0000html/Methods_T_Grpc_Core_Utils_BenchmarkUtil.htm\u000038","Preconditions Methods\u0000html/Methods_T_Grpc_Core_Utils_Preconditions.htm\u000096","WriteOptions Methods\u0000html/Methods_T_Grpc_Core_WriteOptions.htm\u0000142","AuthInterceptors.FromAccessToken Method\u0000html/M_Grpc_Auth_AuthInterceptors_FromAccessToken.htm\u0000129","AuthInterceptors.FromCredential Method\u0000html/M_Grpc_Auth_AuthInterceptors_FromCredential.htm\u0000145","AsyncClientStreamingCall(TRequest, TResponse).Dispose Method\u0000html/M_Grpc_Core_AsyncClientStreamingCall_2_Dispose.htm\u0000161","AsyncClientStreamingCall(TRequest, TResponse).GetAwaiter Method\u0000html/M_Grpc_Core_AsyncClientStreamingCall_2_GetAwaiter.htm\u0000108","AsyncClientStreamingCall(TRequest, TResponse).GetStatus Method\u0000html/M_Grpc_Core_AsyncClientStreamingCall_2_GetStatus.htm\u0000101","AsyncClientStreamingCall(TRequest, TResponse).GetTrailers Method\u0000html/M_Grpc_Core_AsyncClientStreamingCall_2_GetTrailers.htm\u0000104","AsyncDuplexStreamingCall(TRequest, TResponse).Dispose Method\u0000html/M_Grpc_Core_AsyncDuplexStreamingCall_2_Dispose.htm\u0000162","AsyncDuplexStreamingCall(TRequest, TResponse).GetStatus Method\u0000html/M_Grpc_Core_AsyncDuplexStreamingCall_2_GetStatus.htm\u0000101","AsyncDuplexStreamingCall(TRequest, TResponse).GetTrailers Method\u0000html/M_Grpc_Core_AsyncDuplexStreamingCall_2_GetTrailers.htm\u0000104","AsyncServerStreamingCall(TResponse).Dispose Method\u0000html/M_Grpc_Core_AsyncServerStreamingCall_1_Dispose.htm\u0000151","AsyncServerStreamingCall(TResponse).GetStatus Method\u0000html/M_Grpc_Core_AsyncServerStreamingCall_1_GetStatus.htm\u000096","AsyncServerStreamingCall(TResponse).GetTrailers Method\u0000html/M_Grpc_Core_AsyncServerStreamingCall_1_GetTrailers.htm\u000099","AsyncUnaryCall(TResponse).Dispose Method\u0000html/M_Grpc_Core_AsyncUnaryCall_1_Dispose.htm\u0000156","AsyncUnaryCall(TResponse).GetAwaiter Method\u0000html/M_Grpc_Core_AsyncUnaryCall_1_GetAwaiter.htm\u0000103","AsyncUnaryCall(TResponse).GetStatus Method\u0000html/M_Grpc_Core_AsyncUnaryCall_1_GetStatus.htm\u000096","AsyncUnaryCall(TResponse).GetTrailers Method\u0000html/M_Grpc_Core_AsyncUnaryCall_1_GetTrailers.htm\u000099","CallInvocationDetails(TRequest, TResponse).WithOptions Method\u0000html/M_Grpc_Core_CallInvocationDetails_2_WithOptions.htm\u0000186","CallInvocationDetails(TRequest, TResponse) Constructor (Channel, Method(TRequest, TResponse), CallOptions)\u0000html/M_Grpc_Core_CallInvocationDetails_2__ctor.htm\u0000221","CallInvocationDetails(TRequest, TResponse) Constructor (Channel, Method(TRequest, TResponse), String, CallOptions)\u0000html/M_Grpc_Core_CallInvocationDetails_2__ctor_1.htm\u0000265","CallInvocationDetails(TRequest, TResponse) Constructor (Channel, String, String, Marshaller(TRequest), Marshaller(TResponse), CallOptions)\u0000html/M_Grpc_Core_CallInvocationDetails_2__ctor_2.htm\u0000317","CallOptions.WithCancellationToken Method\u0000html/M_Grpc_Core_CallOptions_WithCancellationToken.htm\u0000127","CallOptions.WithDeadline Method\u0000html/M_Grpc_Core_CallOptions_WithDeadline.htm\u0000125","CallOptions.WithHeaders Method\u0000html/M_Grpc_Core_CallOptions_WithHeaders.htm\u0000128","CallOptions Constructor\u0000html/M_Grpc_Core_CallOptions__ctor.htm\u0000397","Calls.AsyncClientStreamingCall(TRequest, TResponse) Method\u0000html/M_Grpc_Core_Calls_AsyncClientStreamingCall__2.htm\u0000283","Calls.AsyncDuplexStreamingCall(TRequest, TResponse) Method\u0000html/M_Grpc_Core_Calls_AsyncDuplexStreamingCall__2.htm\u0000305","Calls.AsyncServerStreamingCall(TRequest, TResponse) Method\u0000html/M_Grpc_Core_Calls_AsyncServerStreamingCall__2.htm\u0000297","Calls.AsyncUnaryCall(TRequest, TResponse) Method\u0000html/M_Grpc_Core_Calls_AsyncUnaryCall__2.htm\u0000278","Calls.BlockingUnaryCall(TRequest, TResponse) Method\u0000html/M_Grpc_Core_Calls_BlockingUnaryCall__2.htm\u0000258","ChannelOption Constructor (String, Int32)\u0000html/M_Grpc_Core_ChannelOption__ctor.htm\u0000137","ChannelOption Constructor (String, String)\u0000html/M_Grpc_Core_ChannelOption__ctor_1.htm\u0000139","Channel.ConnectAsync Method\u0000html/M_Grpc_Core_Channel_ConnectAsync.htm\u0000229","Channel.ShutdownAsync Method\u0000html/M_Grpc_Core_Channel_ShutdownAsync.htm\u0000102","Channel.WaitForStateChangedAsync Method\u0000html/M_Grpc_Core_Channel_WaitForStateChangedAsync.htm\u0000266","Channel Constructor (String, Credentials, IEnumerable(ChannelOption))\u0000html/M_Grpc_Core_Channel__ctor.htm\u0000252","Channel Constructor (String, Int32, Credentials, IEnumerable(ChannelOption))\u0000html/M_Grpc_Core_Channel__ctor_1.htm\u0000270","ClientBase.CreateCall(TRequest, TResponse) Method\u0000html/M_Grpc_Core_ClientBase_CreateCall__2.htm\u0000283","ClientBase Constructor\u0000html/M_Grpc_Core_ClientBase__ctor.htm\u0000110","ContextPropagationOptions Constructor\u0000html/M_Grpc_Core_ContextPropagationOptions__ctor.htm\u0000205","Credentials Constructor\u0000html/M_Grpc_Core_Credentials__ctor.htm\u000076","GrpcEnvironment.SetLogger Method\u0000html/M_Grpc_Core_GrpcEnvironment_SetLogger.htm\u0000139","IAsyncStreamWriter(T).WriteAsync Method\u0000html/M_Grpc_Core_IAsyncStreamWriter_1_WriteAsync.htm\u0000125","IClientStreamWriter(T).CompleteAsync Method\u0000html/M_Grpc_Core_IClientStreamWriter_1_CompleteAsync.htm\u0000101","KeyCertificatePair Constructor\u0000html/M_Grpc_Core_KeyCertificatePair__ctor.htm\u0000139","ConsoleLogger.Debug Method\u0000html/M_Grpc_Core_Logging_ConsoleLogger_Debug.htm\u0000238","ConsoleLogger.Error Method (Exception, String, Object[])\u0000html/M_Grpc_Core_Logging_ConsoleLogger_Error.htm\u0000320","ConsoleLogger.Error Method (String, Object[])\u0000html/M_Grpc_Core_Logging_ConsoleLogger_Error_1.htm\u0000246","ConsoleLogger.ForType(T) Method\u0000html/M_Grpc_Core_Logging_ConsoleLogger_ForType__1.htm\u0000147","ConsoleLogger.Info Method\u0000html/M_Grpc_Core_Logging_ConsoleLogger_Info.htm\u0000238","ConsoleLogger.Warning Method (Exception, String, Object[])\u0000html/M_Grpc_Core_Logging_ConsoleLogger_Warning.htm\u0000320","ConsoleLogger.Warning Method (String, Object[])\u0000html/M_Grpc_Core_Logging_ConsoleLogger_Warning_1.htm\u0000246","ConsoleLogger Constructor\u0000html/M_Grpc_Core_Logging_ConsoleLogger__ctor.htm\u000081","ILogger.Debug Method\u0000html/M_Grpc_Core_Logging_ILogger_Debug.htm\u0000202","ILogger.Error Method (Exception, String, Object[])\u0000html/M_Grpc_Core_Logging_ILogger_Error.htm\u0000276","ILogger.Error Method (String, Object[])\u0000html/M_Grpc_Core_Logging_ILogger_Error_1.htm\u0000210","ILogger.ForType(T) Method\u0000html/M_Grpc_Core_Logging_ILogger_ForType__1.htm\u0000127","ILogger.Info Method\u0000html/M_Grpc_Core_Logging_ILogger_Info.htm\u0000202","ILogger.Warning Method (Exception, String, Object[])\u0000html/M_Grpc_Core_Logging_ILogger_Warning.htm\u0000276","ILogger.Warning Method (String, Object[])\u0000html/M_Grpc_Core_Logging_ILogger_Warning_1.htm\u0000210","Marshallers.Create(T) Method\u0000html/M_Grpc_Core_Marshallers_Create__1.htm\u0000390","Marshaller(T) Constructor\u0000html/M_Grpc_Core_Marshaller_1__ctor.htm\u0000229","Metadata.Add Method (Metadata.Entry)\u0000html/M_Grpc_Core_Metadata_Add.htm\u0000172","Metadata.Add Method (String, Byte[])\u0000html/M_Grpc_Core_Metadata_Add_1.htm\u0000220","Metadata.Add Method (String, String)\u0000html/M_Grpc_Core_Metadata_Add_2.htm\u0000199","Metadata.Clear Method\u0000html/M_Grpc_Core_Metadata_Clear.htm\u0000102","Metadata.Contains Method\u0000html/M_Grpc_Core_Metadata_Contains.htm\u0000173","Metadata.CopyTo Method\u0000html/M_Grpc_Core_Metadata_CopyTo.htm\u0000254","Metadata.Entry.ToString Method\u0000html/M_Grpc_Core_Metadata_Entry_ToString.htm\u0000107","Metadata.Entry Constructor (String, Byte[])\u0000html/M_Grpc_Core_Metadata_Entry__ctor.htm\u0000174","Metadata.Entry Constructor (String, String)\u0000html/M_Grpc_Core_Metadata_Entry__ctor_1.htm\u0000165","Metadata.GetEnumerator Method\u0000html/M_Grpc_Core_Metadata_GetEnumerator.htm\u0000143","Metadata.IndexOf Method\u0000html/M_Grpc_Core_Metadata_IndexOf.htm\u0000173","Metadata.Insert Method\u0000html/M_Grpc_Core_Metadata_Insert.htm\u0000229","Metadata.Remove Method\u0000html/M_Grpc_Core_Metadata_Remove.htm\u0000173","Metadata.RemoveAt Method\u0000html/M_Grpc_Core_Metadata_RemoveAt.htm\u0000155","Metadata Constructor\u0000html/M_Grpc_Core_Metadata__ctor.htm\u000076","Method(TRequest, TResponse) Constructor\u0000html/M_Grpc_Core_Method_2__ctor.htm\u0000270","RpcException Constructor (Status)\u0000html/M_Grpc_Core_RpcException__ctor.htm\u0000111","RpcException Constructor (Status, String)\u0000html/M_Grpc_Core_RpcException__ctor_1.htm\u0000145","ServerCallContext.CreatePropagationToken Method\u0000html/M_Grpc_Core_ServerCallContext_CreatePropagationToken.htm\u0000177","ServerCallContext.WriteResponseHeadersAsync Method\u0000html/M_Grpc_Core_ServerCallContext_WriteResponseHeadersAsync.htm\u0000174","ServerCredentials Constructor\u0000html/M_Grpc_Core_ServerCredentials__ctor.htm\u000076","ServerPort Constructor\u0000html/M_Grpc_Core_ServerPort__ctor.htm\u0000189","ServerServiceDefinition.Builder.AddMethod(TRequest, TResponse) Method (Method(TRequest, TResponse), ClientStreamingServerMethod(TRequest, TResponse))\u0000html/M_Grpc_Core_ServerServiceDefinition_Builder_AddMethod__2.htm\u0000310","ServerServiceDefinition.Builder.AddMethod(TRequest, TResponse) Method (Method(TRequest, TResponse), DuplexStreamingServerMethod(TRequest, TResponse))\u0000html/M_Grpc_Core_ServerServiceDefinition_Builder_AddMethod__2_1.htm\u0000310","ServerServiceDefinition.Builder.AddMethod(TRequest, TResponse) Method (Method(TRequest, TResponse), ServerStreamingServerMethod(TRequest, TResponse))\u0000html/M_Grpc_Core_ServerServiceDefinition_Builder_AddMethod__2_2.htm\u0000310","ServerServiceDefinition.Builder.AddMethod(TRequest, TResponse) Method (Method(TRequest, TResponse), UnaryServerMethod(TRequest, TResponse))\u0000html/M_Grpc_Core_ServerServiceDefinition_Builder_AddMethod__2_3.htm\u0000314","ServerServiceDefinition.Builder.Build Method\u0000html/M_Grpc_Core_ServerServiceDefinition_Builder_Build.htm\u000095","ServerServiceDefinition.Builder Constructor\u0000html/M_Grpc_Core_ServerServiceDefinition_Builder__ctor.htm\u0000105","ServerServiceDefinition.CreateBuilder Method\u0000html/M_Grpc_Core_ServerServiceDefinition_CreateBuilder.htm\u0000131","Server.KillAsync Method\u0000html/M_Grpc_Core_Server_KillAsync.htm\u0000102","Server.ServerPortCollection.Add Method (ServerPort)\u0000html/M_Grpc_Core_Server_ServerPortCollection_Add.htm\u0000168","Server.ServerPortCollection.Add Method (String, Int32, ServerCredentials)\u0000html/M_Grpc_Core_Server_ServerPortCollection_Add_1.htm\u0000212","Server.ServerPortCollection.GetEnumerator Method\u0000html/M_Grpc_Core_Server_ServerPortCollection_GetEnumerator.htm\u0000131","Server.ServiceDefinitionCollection.Add Method\u0000html/M_Grpc_Core_Server_ServiceDefinitionCollection_Add.htm\u0000153","Server.ServiceDefinitionCollection.GetEnumerator Method\u0000html/M_Grpc_Core_Server_ServiceDefinitionCollection_GetEnumerator.htm\u0000131","Server.ShutdownAsync Method\u0000html/M_Grpc_Core_Server_ShutdownAsync.htm\u0000109","Server.Start Method\u0000html/M_Grpc_Core_Server_Start.htm\u000076","Server Constructor\u0000html/M_Grpc_Core_Server__ctor.htm\u0000155","SslCredentials Constructor\u0000html/M_Grpc_Core_SslCredentials__ctor.htm\u0000103","SslCredentials Constructor (String)\u0000html/M_Grpc_Core_SslCredentials__ctor_1.htm\u0000135","SslCredentials Constructor (String, KeyCertificatePair)\u0000html/M_Grpc_Core_SslCredentials__ctor_2.htm\u0000145","SslServerCredentials Constructor (IEnumerable(KeyCertificatePair))\u0000html/M_Grpc_Core_SslServerCredentials__ctor.htm\u0000152","SslServerCredentials Constructor (IEnumerable(KeyCertificatePair), String, Boolean)\u0000html/M_Grpc_Core_SslServerCredentials__ctor_1.htm\u0000213","Status.ToString Method\u0000html/M_Grpc_Core_Status_ToString.htm\u0000104","Status Constructor\u0000html/M_Grpc_Core_Status__ctor.htm\u0000130","AsyncStreamExtensions.ForEachAsync(T) Method\u0000html/M_Grpc_Core_Utils_AsyncStreamExtensions_ForEachAsync__1.htm\u0000440","AsyncStreamExtensions.ToListAsync(T) Method\u0000html/M_Grpc_Core_Utils_AsyncStreamExtensions_ToListAsync__1.htm\u0000358","AsyncStreamExtensions.WriteAllAsync(T) Method (IClientStreamWriter(T), IEnumerable(T), Boolean)\u0000html/M_Grpc_Core_Utils_AsyncStreamExtensions_WriteAllAsync__1.htm\u0000541","AsyncStreamExtensions.WriteAllAsync(T) Method (IServerStreamWriter(T), IEnumerable(T))\u0000html/M_Grpc_Core_Utils_AsyncStreamExtensions_WriteAllAsync__1_1.htm\u0000428","BenchmarkUtil.RunBenchmark Method\u0000html/M_Grpc_Core_Utils_BenchmarkUtil_RunBenchmark.htm\u0000243","Preconditions.CheckArgument Method (Boolean)\u0000html/M_Grpc_Core_Utils_Preconditions_CheckArgument.htm\u0000115","Preconditions.CheckArgument Method (Boolean, String)\u0000html/M_Grpc_Core_Utils_Preconditions_CheckArgument_1.htm\u0000150","Preconditions.CheckNotNull(T) Method (T)\u0000html/M_Grpc_Core_Utils_Preconditions_CheckNotNull__1.htm\u0000169","Preconditions.CheckNotNull(T) Method (T, String)\u0000html/M_Grpc_Core_Utils_Preconditions_CheckNotNull__1_1.htm\u0000202","Preconditions.CheckState Method (Boolean)\u0000html/M_Grpc_Core_Utils_Preconditions_CheckState.htm\u0000115","Preconditions.CheckState Method (Boolean, String)\u0000html/M_Grpc_Core_Utils_Preconditions_CheckState_1.htm\u0000150","WriteOptions Constructor\u0000html/M_Grpc_Core_WriteOptions__ctor.htm\u0000130","Grpc.Auth Namespace\u0000html/N_Grpc_Auth.htm\u000066","Grpc.Core Namespace\u0000html/N_Grpc_Core.htm\u0000823","Grpc.Core.Logging Namespace\u0000html/N_Grpc_Core_Logging.htm\u000039","Grpc.Core.Utils Namespace\u0000html/N_Grpc_Core_Utils.htm\u000048","CallInvocationDetails(TRequest, TResponse) Constructor\u0000html/Overload_Grpc_Core_CallInvocationDetails_2__ctor.htm\u0000116","ChannelOption Constructor\u0000html/Overload_Grpc_Core_ChannelOption__ctor.htm\u000048","Channel Constructor\u0000html/Overload_Grpc_Core_Channel__ctor.htm\u000079","ConsoleLogger.Error Method\u0000html/Overload_Grpc_Core_Logging_ConsoleLogger_Error.htm\u000054","ConsoleLogger.Warning Method\u0000html/Overload_Grpc_Core_Logging_ConsoleLogger_Warning.htm\u000054","ILogger.Error Method\u0000html/Overload_Grpc_Core_Logging_ILogger_Error.htm\u000054","ILogger.Warning Method\u0000html/Overload_Grpc_Core_Logging_ILogger_Warning.htm\u000054","Metadata.Add Method\u0000html/Overload_Grpc_Core_Metadata_Add.htm\u000036","Entry Constructor\u0000html/Overload_Grpc_Core_Metadata_Entry__ctor.htm\u000062","RpcException Constructor\u0000html/Overload_Grpc_Core_RpcException__ctor.htm\u000048","Builder.AddMethod Method\u0000html/Overload_Grpc_Core_ServerServiceDefinition_Builder_AddMethod.htm\u0000130","ServerPortCollection.Add Method\u0000html/Overload_Grpc_Core_Server_ServerPortCollection_Add.htm\u000086","SslCredentials Constructor\u0000html/Overload_Grpc_Core_SslCredentials__ctor.htm\u000082","SslServerCredentials Constructor\u0000html/Overload_Grpc_Core_SslServerCredentials__ctor.htm\u000064","AsyncStreamExtensions.WriteAllAsync Method\u0000html/Overload_Grpc_Core_Utils_AsyncStreamExtensions_WriteAllAsync.htm\u000076","Preconditions.CheckArgument Method\u0000html/Overload_Grpc_Core_Utils_Preconditions_CheckArgument.htm\u000047","Preconditions.CheckNotNull Method\u0000html/Overload_Grpc_Core_Utils_Preconditions_CheckNotNull.htm\u000048","Preconditions.CheckState Method\u0000html/Overload_Grpc_Core_Utils_Preconditions_CheckState.htm\u000047","AsyncClientStreamingCall(TRequest, TResponse) Properties\u0000html/Properties_T_Grpc_Core_AsyncClientStreamingCall_2.htm\u000058","AsyncDuplexStreamingCall(TRequest, TResponse) Properties\u0000html/Properties_T_Grpc_Core_AsyncDuplexStreamingCall_2.htm\u000061","AsyncServerStreamingCall(TResponse) Properties\u0000html/Properties_T_Grpc_Core_AsyncServerStreamingCall_1.htm\u000046","AsyncUnaryCall(TResponse) Properties\u0000html/Properties_T_Grpc_Core_AsyncUnaryCall_1.htm\u000043","CallInvocationDetails(TRequest, TResponse) Properties\u0000html/Properties_T_Grpc_Core_CallInvocationDetails_2.htm\u000083","CallOptions Properties\u0000html/Properties_T_Grpc_Core_CallOptions.htm\u000072","Channel Properties\u0000html/Properties_T_Grpc_Core_Channel.htm\u000057","ChannelOption Properties\u0000html/Properties_T_Grpc_Core_ChannelOption.htm\u000063","ClientBase Properties\u0000html/Properties_T_Grpc_Core_ClientBase.htm\u0000108","ContextPropagationOptions Properties\u0000html/Properties_T_Grpc_Core_ContextPropagationOptions.htm\u000056","Credentials Properties\u0000html/Properties_T_Grpc_Core_Credentials.htm\u000049","GrpcEnvironment Properties\u0000html/Properties_T_Grpc_Core_GrpcEnvironment.htm\u000036","IAsyncStreamReader(T) Properties\u0000html/Properties_T_Grpc_Core_IAsyncStreamReader_1.htm\u000040","IAsyncStreamWriter(T) Properties\u0000html/Properties_T_Grpc_Core_IAsyncStreamWriter_1.htm\u000064","IClientStreamWriter(T) Properties\u0000html/Properties_T_Grpc_Core_IClientStreamWriter_1.htm\u000072","IHasWriteOptions Properties\u0000html/Properties_T_Grpc_Core_IHasWriteOptions.htm\u000035","IMethod Properties\u0000html/Properties_T_Grpc_Core_IMethod.htm\u000080","IServerStreamWriter(T) Properties\u0000html/Properties_T_Grpc_Core_IServerStreamWriter_1.htm\u000072","KeyCertificatePair Properties\u0000html/Properties_T_Grpc_Core_KeyCertificatePair.htm\u000039","Marshallers Properties\u0000html/Properties_T_Grpc_Core_Marshallers.htm\u000041","Marshaller(T) Properties\u0000html/Properties_T_Grpc_Core_Marshaller_1.htm\u000043","Metadata Properties\u0000html/Properties_T_Grpc_Core_Metadata.htm\u000030","Entry Properties\u0000html/Properties_T_Grpc_Core_Metadata_Entry.htm\u000068","Method(TRequest, TResponse) Properties\u0000html/Properties_T_Grpc_Core_Method_2.htm\u0000109","RpcException Properties\u0000html/Properties_T_Grpc_Core_RpcException.htm\u0000203","Server Properties\u0000html/Properties_T_Grpc_Core_Server.htm\u000087","ServerCallContext Properties\u0000html/Properties_T_Grpc_Core_ServerCallContext.htm\u0000135","ServerCredentials Properties\u0000html/Properties_T_Grpc_Core_ServerCredentials.htm\u000050","ServerPort Properties\u0000html/Properties_T_Grpc_Core_ServerPort.htm\u000031","SslCredentials Properties\u0000html/Properties_T_Grpc_Core_SslCredentials.htm\u000056","SslServerCredentials Properties\u0000html/Properties_T_Grpc_Core_SslServerCredentials.htm\u000052","Status Properties\u0000html/Properties_T_Grpc_Core_Status.htm\u000050","WriteOptions Properties\u0000html/Properties_T_Grpc_Core_WriteOptions.htm\u000033","AsyncClientStreamingCall(TRequest, TResponse).RequestStream Property\u0000html/P_Grpc_Core_AsyncClientStreamingCall_2_RequestStream.htm\u0000126","AsyncClientStreamingCall(TRequest, TResponse).ResponseAsync Property\u0000html/P_Grpc_Core_AsyncClientStreamingCall_2_ResponseAsync.htm\u0000123","AsyncClientStreamingCall(TRequest, TResponse).ResponseHeadersAsync Property\u0000html/P_Grpc_Core_AsyncClientStreamingCall_2_ResponseHeadersAsync.htm\u0000135","AsyncDuplexStreamingCall(TRequest, TResponse).RequestStream Property\u0000html/P_Grpc_Core_AsyncDuplexStreamingCall_2_RequestStream.htm\u0000126","AsyncDuplexStreamingCall(TRequest, TResponse).ResponseHeadersAsync Property\u0000html/P_Grpc_Core_AsyncDuplexStreamingCall_2_ResponseHeadersAsync.htm\u0000135","AsyncDuplexStreamingCall(TRequest, TResponse).ResponseStream Property\u0000html/P_Grpc_Core_AsyncDuplexStreamingCall_2_ResponseStream.htm\u0000126","AsyncServerStreamingCall(TResponse).ResponseHeadersAsync Property\u0000html/P_Grpc_Core_AsyncServerStreamingCall_1_ResponseHeadersAsync.htm\u0000130","AsyncServerStreamingCall(TResponse).ResponseStream Property\u0000html/P_Grpc_Core_AsyncServerStreamingCall_1_ResponseStream.htm\u0000121","AsyncUnaryCall(TResponse).ResponseAsync Property\u0000html/P_Grpc_Core_AsyncUnaryCall_1_ResponseAsync.htm\u0000118","AsyncUnaryCall(TResponse).ResponseHeadersAsync Property\u0000html/P_Grpc_Core_AsyncUnaryCall_1_ResponseHeadersAsync.htm\u0000130","CallInvocationDetails(TRequest, TResponse).Channel Property\u0000html/P_Grpc_Core_CallInvocationDetails_2_Channel.htm\u0000109","CallInvocationDetails(TRequest, TResponse).Host Property\u0000html/P_Grpc_Core_CallInvocationDetails_2_Host.htm\u0000107","CallInvocationDetails(TRequest, TResponse).Method Property\u0000html/P_Grpc_Core_CallInvocationDetails_2_Method.htm\u0000110","CallInvocationDetails(TRequest, TResponse).Options Property\u0000html/P_Grpc_Core_CallInvocationDetails_2_Options.htm\u0000103","CallInvocationDetails(TRequest, TResponse).RequestMarshaller Property\u0000html/P_Grpc_Core_CallInvocationDetails_2_RequestMarshaller.htm\u0000124","CallInvocationDetails(TRequest, TResponse).ResponseMarshaller Property\u0000html/P_Grpc_Core_CallInvocationDetails_2_ResponseMarshaller.htm\u0000124","CallOptions.CancellationToken Property\u0000html/P_Grpc_Core_CallOptions_CancellationToken.htm\u0000101","CallOptions.Deadline Property\u0000html/P_Grpc_Core_CallOptions_Deadline.htm\u0000121","CallOptions.Headers Property\u0000html/P_Grpc_Core_CallOptions_Headers.htm\u0000105","CallOptions.PropagationToken Property\u0000html/P_Grpc_Core_CallOptions_PropagationToken.htm\u0000102","CallOptions.WriteOptions Property\u0000html/P_Grpc_Core_CallOptions_WriteOptions.htm\u0000105","ChannelOption.IntValue Property\u0000html/P_Grpc_Core_ChannelOption_IntValue.htm\u000099","ChannelOption.Name Property\u0000html/P_Grpc_Core_ChannelOption_Name.htm\u0000103","ChannelOption.StringValue Property\u0000html/P_Grpc_Core_ChannelOption_StringValue.htm\u0000103","ChannelOption.Type Property\u0000html/P_Grpc_Core_ChannelOption_Type.htm\u0000105","Channel.ResolvedTarget Property\u0000html/P_Grpc_Core_Channel_ResolvedTarget.htm\u0000105","Channel.State Property\u0000html/P_Grpc_Core_Channel_State.htm\u000099","Channel.Target Property\u0000html/P_Grpc_Core_Channel_Target.htm\u0000104","ClientBase.Channel Property\u0000html/P_Grpc_Core_ClientBase_Channel.htm\u0000101","ClientBase.HeaderInterceptor Property\u0000html/P_Grpc_Core_ClientBase_HeaderInterceptor.htm\u0000141","ClientBase.Host Property\u0000html/P_Grpc_Core_ClientBase_Host.htm\u0000155","ContextPropagationOptions.IsPropagateCancellation Property\u0000html/P_Grpc_Core_ContextPropagationOptions_IsPropagateCancellation.htm\u0000105","ContextPropagationOptions.IsPropagateDeadline Property\u0000html/P_Grpc_Core_ContextPropagationOptions_IsPropagateDeadline.htm\u0000104","Credentials.Insecure Property\u0000html/P_Grpc_Core_Credentials_Insecure.htm\u0000120","GrpcEnvironment.Logger Property\u0000html/P_Grpc_Core_GrpcEnvironment_Logger.htm\u0000110","IAsyncStreamWriter(T).WriteOptions Property\u0000html/P_Grpc_Core_IAsyncStreamWriter_1_WriteOptions.htm\u0000141","IHasWriteOptions.WriteOptions Property\u0000html/P_Grpc_Core_IHasWriteOptions_WriteOptions.htm\u0000114","IMethod.FullName Property\u0000html/P_Grpc_Core_IMethod_FullName.htm\u0000112","IMethod.Name Property\u0000html/P_Grpc_Core_IMethod_Name.htm\u000098","IMethod.ServiceName Property\u0000html/P_Grpc_Core_IMethod_ServiceName.htm\u0000102","IMethod.Type Property\u0000html/P_Grpc_Core_IMethod_Type.htm\u000093","KeyCertificatePair.CertificateChain Property\u0000html/P_Grpc_Core_KeyCertificatePair_CertificateChain.htm\u0000100","KeyCertificatePair.PrivateKey Property\u0000html/P_Grpc_Core_KeyCertificatePair_PrivateKey.htm\u0000100","Marshallers.StringMarshaller Property\u0000html/P_Grpc_Core_Marshallers_StringMarshaller.htm\u0000137","Marshaller(T).Deserializer Property\u0000html/P_Grpc_Core_Marshaller_1_Deserializer.htm\u0000159","Marshaller(T).Serializer Property\u0000html/P_Grpc_Core_Marshaller_1_Serializer.htm\u0000155","Metadata.Count Property\u0000html/P_Grpc_Core_Metadata_Count.htm\u0000120","Metadata.Entry.IsBinary Property\u0000html/P_Grpc_Core_Metadata_Entry_IsBinary.htm\u0000104","Metadata.Entry.Key Property\u0000html/P_Grpc_Core_Metadata_Entry_Key.htm\u0000103","Metadata.Entry.Value Property\u0000html/P_Grpc_Core_Metadata_Entry_Value.htm\u0000106","Metadata.Entry.ValueBytes Property\u0000html/P_Grpc_Core_Metadata_Entry_ValueBytes.htm\u0000125","Metadata.IsReadOnly Property\u0000html/P_Grpc_Core_Metadata_IsReadOnly.htm\u0000120","Metadata.Item Property\u0000html/P_Grpc_Core_Metadata_Item.htm\u0000185","Method(TRequest, TResponse).FullName Property\u0000html/P_Grpc_Core_Method_2_FullName.htm\u0000137","Method(TRequest, TResponse).Name Property\u0000html/P_Grpc_Core_Method_2_Name.htm\u0000123","Method(TRequest, TResponse).RequestMarshaller Property\u0000html/P_Grpc_Core_Method_2_RequestMarshaller.htm\u0000125","Method(TRequest, TResponse).ResponseMarshaller Property\u0000html/P_Grpc_Core_Method_2_ResponseMarshaller.htm\u0000125","Method(TRequest, TResponse).ServiceName Property\u0000html/P_Grpc_Core_Method_2_ServiceName.htm\u0000127","Method(TRequest, TResponse).Type Property\u0000html/P_Grpc_Core_Method_2_Type.htm\u0000118","RpcException.Status Property\u0000html/P_Grpc_Core_RpcException_Status.htm\u000097","ServerCallContext.CancellationToken Property\u0000html/P_Grpc_Core_ServerCallContext_CancellationToken.htm\u000099","ServerCallContext.Deadline Property\u0000html/P_Grpc_Core_ServerCallContext_Deadline.htm\u000096","ServerCallContext.Host Property\u0000html/P_Grpc_Core_ServerCallContext_Host.htm\u0000103","ServerCallContext.Method Property\u0000html/P_Grpc_Core_ServerCallContext_Method.htm\u0000103","ServerCallContext.Peer Property\u0000html/P_Grpc_Core_ServerCallContext_Peer.htm\u0000104","ServerCallContext.RequestHeaders Property\u0000html/P_Grpc_Core_ServerCallContext_RequestHeaders.htm\u0000101","ServerCallContext.ResponseTrailers Property\u0000html/P_Grpc_Core_ServerCallContext_ResponseTrailers.htm\u0000105","ServerCallContext.Status Property\u0000html/P_Grpc_Core_ServerCallContext_Status.htm\u0000116","ServerCallContext.WriteOptions Property\u0000html/P_Grpc_Core_ServerCallContext_WriteOptions.htm\u0000147","ServerCredentials.Insecure Property\u0000html/P_Grpc_Core_ServerCredentials_Insecure.htm\u0000121","ServerPort.BoundPort Property\u0000html/P_Grpc_Core_ServerPort_BoundPort.htm\u0000126","ServerPort.Credentials Property\u0000html/P_Grpc_Core_ServerPort_Credentials.htm\u0000114","ServerPort.Host Property\u0000html/P_Grpc_Core_ServerPort_Host.htm\u0000113","ServerPort.Port Property\u0000html/P_Grpc_Core_ServerPort_Port.htm\u0000109","Server.Ports Property\u0000html/P_Grpc_Core_Server_Ports.htm\u0000125","Server.Services Property\u0000html/P_Grpc_Core_Server_Services.htm\u0000126","Server.ShutdownTask Property\u0000html/P_Grpc_Core_Server_ShutdownTask.htm\u0000103","SslCredentials.KeyCertificatePair Property\u0000html/P_Grpc_Core_SslCredentials_KeyCertificatePair.htm\u0000114","SslCredentials.RootCertificates Property\u0000html/P_Grpc_Core_SslCredentials_RootCertificates.htm\u0000103","SslServerCredentials.ForceClientAuthentication Property\u0000html/P_Grpc_Core_SslServerCredentials_ForceClientAuthentication.htm\u0000103","SslServerCredentials.KeyCertificatePairs Property\u0000html/P_Grpc_Core_SslServerCredentials_KeyCertificatePairs.htm\u0000126","SslServerCredentials.RootCertificates Property\u0000html/P_Grpc_Core_SslServerCredentials_RootCertificates.htm\u0000101","Status.Detail Property\u0000html/P_Grpc_Core_Status_Detail.htm\u000099","Status.StatusCode Property\u0000html/P_Grpc_Core_Status_StatusCode.htm\u0000108","WriteOptions.Flags Property\u0000html/P_Grpc_Core_WriteOptions_Flags.htm\u000096","Namespaces\u0000html/R_Project_Documentation.htm\u000084","AuthInterceptors Class\u0000html/T_Grpc_Auth_AuthInterceptors.htm\u0000161","AsyncClientStreamingCall(TRequest, TResponse) Class\u0000html/T_Grpc_Core_AsyncClientStreamingCall_2.htm\u0000362","AsyncDuplexStreamingCall(TRequest, TResponse) Class\u0000html/T_Grpc_Core_AsyncDuplexStreamingCall_2.htm\u0000359","AsyncServerStreamingCall(TResponse) Class\u0000html/T_Grpc_Core_AsyncServerStreamingCall_1.htm\u0000320","AsyncUnaryCall(TResponse) Class\u0000html/T_Grpc_Core_AsyncUnaryCall_1.htm\u0000333","CallInvocationDetails(TRequest, TResponse) Structure\u0000html/T_Grpc_Core_CallInvocationDetails_2.htm\u0000377","CallOptions Structure\u0000html/T_Grpc_Core_CallOptions.htm\u0000282","Calls Class\u0000html/T_Grpc_Core_Calls.htm\u0000262","Channel Class\u0000html/T_Grpc_Core_Channel.htm\u0000461","ChannelOption Class\u0000html/T_Grpc_Core_ChannelOption.htm\u0000244","ChannelOptions Class\u0000html/T_Grpc_Core_ChannelOptions.htm\u0000187","ChannelOption.OptionType Enumeration\u0000html/T_Grpc_Core_ChannelOption_OptionType.htm\u000082","ChannelState Enumeration\u0000html/T_Grpc_Core_ChannelState.htm\u0000113","ClientBase Class\u0000html/T_Grpc_Core_ClientBase.htm\u0000320","ClientStreamingServerMethod(TRequest, TResponse) Delegate\u0000html/T_Grpc_Core_ClientStreamingServerMethod_2.htm\u0000240","CompressionLevel Enumeration\u0000html/T_Grpc_Core_CompressionLevel.htm\u000089","ContextPropagationOptions Class\u0000html/T_Grpc_Core_ContextPropagationOptions.htm\u0000258","ContextPropagationToken Class\u0000html/T_Grpc_Core_ContextPropagationToken.htm\u0000268","Credentials Class\u0000html/T_Grpc_Core_Credentials.htm\u0000257","DuplexStreamingServerMethod(TRequest, TResponse) Delegate\u0000html/T_Grpc_Core_DuplexStreamingServerMethod_2.htm\u0000266","GrpcEnvironment Class\u0000html/T_Grpc_Core_GrpcEnvironment.htm\u0000227","HeaderInterceptor Delegate\u0000html/T_Grpc_Core_HeaderInterceptor.htm\u0000155","IAsyncStreamReader(T) Interface\u0000html/T_Grpc_Core_IAsyncStreamReader_1.htm\u0000234","IAsyncStreamWriter(T) Interface\u0000html/T_Grpc_Core_IAsyncStreamWriter_1.htm\u0000157","IClientStreamWriter(T) Interface\u0000html/T_Grpc_Core_IClientStreamWriter_1.htm\u0000260","IHasWriteOptions Interface\u0000html/T_Grpc_Core_IHasWriteOptions.htm\u000089","IMethod Interface\u0000html/T_Grpc_Core_IMethod.htm\u0000133","IServerStreamWriter(T) Interface\u0000html/T_Grpc_Core_IServerStreamWriter_1.htm\u0000245","KeyCertificatePair Class\u0000html/T_Grpc_Core_KeyCertificatePair.htm\u0000197","ConsoleLogger Class\u0000html/T_Grpc_Core_Logging_ConsoleLogger.htm\u0000320","ILogger Interface\u0000html/T_Grpc_Core_Logging_ILogger.htm\u0000168","Marshallers Class\u0000html/T_Grpc_Core_Marshallers.htm\u0000130","Marshaller(T) Structure\u0000html/T_Grpc_Core_Marshaller_1.htm\u0000226","Metadata Class\u0000html/T_Grpc_Core_Metadata.htm\u0000421","Metadata.Entry Structure\u0000html/T_Grpc_Core_Metadata_Entry.htm\u0000240","MethodType Enumeration\u0000html/T_Grpc_Core_MethodType.htm\u0000126","Method(TRequest, TResponse) Class\u0000html/T_Grpc_Core_Method_2.htm\u0000358","RpcException Class\u0000html/T_Grpc_Core_RpcException.htm\u0000526","Server Class\u0000html/T_Grpc_Core_Server.htm\u0000344","ServerCallContext Class\u0000html/T_Grpc_Core_ServerCallContext.htm\u0000381","ServerCredentials Class\u0000html/T_Grpc_Core_ServerCredentials.htm\u0000250","ServerPort Class\u0000html/T_Grpc_Core_ServerPort.htm\u0000260","ServerServiceDefinition Class\u0000html/T_Grpc_Core_ServerServiceDefinition.htm\u0000239","ServerServiceDefinition.Builder Class\u0000html/T_Grpc_Core_ServerServiceDefinition_Builder.htm\u0000332","ServerStreamingServerMethod(TRequest, TResponse) Delegate\u0000html/T_Grpc_Core_ServerStreamingServerMethod_2.htm\u0000248","Server.ServerPortCollection Class\u0000html/T_Grpc_Core_Server_ServerPortCollection.htm\u0000312","Server.ServiceDefinitionCollection Class\u0000html/T_Grpc_Core_Server_ServiceDefinitionCollection.htm\u0000278","SslCredentials Class\u0000html/T_Grpc_Core_SslCredentials.htm\u0000274","SslServerCredentials Class\u0000html/T_Grpc_Core_SslServerCredentials.htm\u0000289","Status Structure\u0000html/T_Grpc_Core_Status.htm\u0000235","StatusCode Enumeration\u0000html/T_Grpc_Core_StatusCode.htm\u0000545","UnaryServerMethod(TRequest, TResponse) Delegate\u0000html/T_Grpc_Core_UnaryServerMethod_2.htm\u0000221","AsyncStreamExtensions Class\u0000html/T_Grpc_Core_Utils_AsyncStreamExtensions.htm\u0000211","BenchmarkUtil Class\u0000html/T_Grpc_Core_Utils_BenchmarkUtil.htm\u0000115","Preconditions Class\u0000html/T_Grpc_Core_Utils_Preconditions.htm\u0000177","VersionInfo Class\u0000html/T_Grpc_Core_VersionInfo.htm\u0000109","WriteFlags Enumeration\u0000html/T_Grpc_Core_WriteFlags.htm\u0000148","WriteOptions Class\u0000html/T_Grpc_Core_WriteOptions.htm\u0000230"] \ No newline at end of file +["gRPC C# - Redirect\u0000index.html\u000018","gRPC C# - Search\u0000search.html\u000012","RpcException Events\u0000html/Events_T_Grpc_Core_RpcException.htm\u000055","ChannelOptions Fields\u0000html/Fields_T_Grpc_Core_ChannelOptions.htm\u0000111","ContextPropagationOptions Fields\u0000html/Fields_T_Grpc_Core_ContextPropagationOptions.htm\u000039","Metadata Fields\u0000html/Fields_T_Grpc_Core_Metadata.htm\u000047","ServerPort Fields\u0000html/Fields_T_Grpc_Core_ServerPort.htm\u000060","Status Fields\u0000html/Fields_T_Grpc_Core_Status.htm\u000057","VersionInfo Fields\u0000html/Fields_T_Grpc_Core_VersionInfo.htm\u000034","WriteOptions Fields\u0000html/Fields_T_Grpc_Core_WriteOptions.htm\u000032","ChannelOptions.Census Field\u0000html/F_Grpc_Core_ChannelOptions_Census.htm\u000082","ChannelOptions.DefaultAuthority Field\u0000html/F_Grpc_Core_ChannelOptions_DefaultAuthority.htm\u000080","ChannelOptions.Http2InitialSequenceNumber Field\u0000html/F_Grpc_Core_ChannelOptions_Http2InitialSequenceNumber.htm\u000081","ChannelOptions.MaxConcurrentStreams Field\u0000html/F_Grpc_Core_ChannelOptions_MaxConcurrentStreams.htm\u000087","ChannelOptions.MaxMessageLength Field\u0000html/F_Grpc_Core_ChannelOptions_MaxMessageLength.htm\u000083","ChannelOptions.PrimaryUserAgentString Field\u0000html/F_Grpc_Core_ChannelOptions_PrimaryUserAgentString.htm\u000088","ChannelOptions.SecondaryUserAgentString Field\u0000html/F_Grpc_Core_ChannelOptions_SecondaryUserAgentString.htm\u000088","ChannelOptions.SslTargetNameOverride Field\u0000html/F_Grpc_Core_ChannelOptions_SslTargetNameOverride.htm\u000087","ContextPropagationOptions.Default Field\u0000html/F_Grpc_Core_ContextPropagationOptions_Default.htm\u000088","Metadata.BinaryHeaderSuffix Field\u0000html/F_Grpc_Core_Metadata_BinaryHeaderSuffix.htm\u000083","Metadata.Empty Field\u0000html/F_Grpc_Core_Metadata_Empty.htm\u000087","ServerPort.PickUnused Field\u0000html/F_Grpc_Core_ServerPort_PickUnused.htm\u0000105","Status.DefaultCancelled Field\u0000html/F_Grpc_Core_Status_DefaultCancelled.htm\u000089","Status.DefaultSuccess Field\u0000html/F_Grpc_Core_Status_DefaultSuccess.htm\u000089","VersionInfo.CurrentVersion Field\u0000html/F_Grpc_Core_VersionInfo_CurrentVersion.htm\u000081","WriteOptions.Default Field\u0000html/F_Grpc_Core_WriteOptions_Default.htm\u000081","AuthInterceptors Methods\u0000html/Methods_T_Grpc_Auth_AuthInterceptors.htm\u000065","AsyncClientStreamingCall(TRequest, TResponse) Methods\u0000html/Methods_T_Grpc_Core_AsyncClientStreamingCall_2.htm\u0000215","AsyncDuplexStreamingCall(TRequest, TResponse) Methods\u0000html/Methods_T_Grpc_Core_AsyncDuplexStreamingCall_2.htm\u0000209","AsyncServerStreamingCall(TResponse) Methods\u0000html/Methods_T_Grpc_Core_AsyncServerStreamingCall_1.htm\u0000196","AsyncUnaryCall(TResponse) Methods\u0000html/Methods_T_Grpc_Core_AsyncUnaryCall_1.htm\u0000208","CallInvocationDetails(TRequest, TResponse) Methods\u0000html/Methods_T_Grpc_Core_CallInvocationDetails_2.htm\u0000132","CallOptions Methods\u0000html/Methods_T_Grpc_Core_CallOptions.htm\u0000162","Calls Methods\u0000html/Methods_T_Grpc_Core_Calls.htm\u0000160","Channel Methods\u0000html/Methods_T_Grpc_Core_Channel.htm\u0000258","ChannelOption Methods\u0000html/Methods_T_Grpc_Core_ChannelOption.htm\u000095","ClientBase Methods\u0000html/Methods_T_Grpc_Core_ClientBase.htm\u0000154","ContextPropagationOptions Methods\u0000html/Methods_T_Grpc_Core_ContextPropagationOptions.htm\u0000142","ContextPropagationToken Methods\u0000html/Methods_T_Grpc_Core_ContextPropagationToken.htm\u0000142","Credentials Methods\u0000html/Methods_T_Grpc_Core_Credentials.htm\u0000142","GrpcEnvironment Methods\u0000html/Methods_T_Grpc_Core_GrpcEnvironment.htm\u0000155","IAsyncStreamReader(T) Methods\u0000html/Methods_T_Grpc_Core_IAsyncStreamReader_1.htm\u0000113","IAsyncStreamWriter(T) Methods\u0000html/Methods_T_Grpc_Core_IAsyncStreamWriter_1.htm\u000047","IClientStreamWriter(T) Methods\u0000html/Methods_T_Grpc_Core_IClientStreamWriter_1.htm\u0000113","IServerStreamWriter(T) Methods\u0000html/Methods_T_Grpc_Core_IServerStreamWriter_1.htm\u000079","KeyCertificatePair Methods\u0000html/Methods_T_Grpc_Core_KeyCertificatePair.htm\u000095","ConsoleLogger Methods\u0000html/Methods_T_Grpc_Core_Logging_ConsoleLogger.htm\u0000234","ILogger Methods\u0000html/Methods_T_Grpc_Core_Logging_ILogger.htm\u0000119","Marshallers Methods\u0000html/Methods_T_Grpc_Core_Marshallers.htm\u000038","Marshaller(T) Methods\u0000html/Methods_T_Grpc_Core_Marshaller_1.htm\u0000146","Metadata Methods\u0000html/Methods_T_Grpc_Core_Metadata.htm\u0000118","Entry Methods\u0000html/Methods_T_Grpc_Core_Metadata_Entry.htm\u000099","Method(TRequest, TResponse) Methods\u0000html/Methods_T_Grpc_Core_Method_2.htm\u0000153","RpcException Methods\u0000html/Methods_T_Grpc_Core_RpcException.htm\u0000199","Server Methods\u0000html/Methods_T_Grpc_Core_Server.htm\u0000198","ServerCallContext Methods\u0000html/Methods_T_Grpc_Core_ServerCallContext.htm\u0000211","ServerCredentials Methods\u0000html/Methods_T_Grpc_Core_ServerCredentials.htm\u0000142","ServerPort Methods\u0000html/Methods_T_Grpc_Core_ServerPort.htm\u0000142","ServerServiceDefinition Methods\u0000html/Methods_T_Grpc_Core_ServerServiceDefinition.htm\u0000152","Builder Methods\u0000html/Methods_T_Grpc_Core_ServerServiceDefinition_Builder.htm\u0000261","ServerPortCollection Methods\u0000html/Methods_T_Grpc_Core_Server_ServerPortCollection.htm\u0000215","ServiceDefinitionCollection Methods\u0000html/Methods_T_Grpc_Core_Server_ServiceDefinitionCollection.htm\u0000181","SslCredentials Methods\u0000html/Methods_T_Grpc_Core_SslCredentials.htm\u000095","SslServerCredentials Methods\u0000html/Methods_T_Grpc_Core_SslServerCredentials.htm\u0000142","Status Methods\u0000html/Methods_T_Grpc_Core_Status.htm\u000096","AsyncStreamExtensions Methods\u0000html/Methods_T_Grpc_Core_Utils_AsyncStreamExtensions.htm\u0000113","BenchmarkUtil Methods\u0000html/Methods_T_Grpc_Core_Utils_BenchmarkUtil.htm\u000038","Preconditions Methods\u0000html/Methods_T_Grpc_Core_Utils_Preconditions.htm\u000096","WriteOptions Methods\u0000html/Methods_T_Grpc_Core_WriteOptions.htm\u0000142","AuthInterceptors.FromAccessToken Method\u0000html/M_Grpc_Auth_AuthInterceptors_FromAccessToken.htm\u0000129","AuthInterceptors.FromCredential Method\u0000html/M_Grpc_Auth_AuthInterceptors_FromCredential.htm\u0000145","AsyncClientStreamingCall(TRequest, TResponse).Dispose Method\u0000html/M_Grpc_Core_AsyncClientStreamingCall_2_Dispose.htm\u0000161","AsyncClientStreamingCall(TRequest, TResponse).GetAwaiter Method\u0000html/M_Grpc_Core_AsyncClientStreamingCall_2_GetAwaiter.htm\u0000108","AsyncClientStreamingCall(TRequest, TResponse).GetStatus Method\u0000html/M_Grpc_Core_AsyncClientStreamingCall_2_GetStatus.htm\u0000101","AsyncClientStreamingCall(TRequest, TResponse).GetTrailers Method\u0000html/M_Grpc_Core_AsyncClientStreamingCall_2_GetTrailers.htm\u0000104","AsyncDuplexStreamingCall(TRequest, TResponse).Dispose Method\u0000html/M_Grpc_Core_AsyncDuplexStreamingCall_2_Dispose.htm\u0000162","AsyncDuplexStreamingCall(TRequest, TResponse).GetStatus Method\u0000html/M_Grpc_Core_AsyncDuplexStreamingCall_2_GetStatus.htm\u0000101","AsyncDuplexStreamingCall(TRequest, TResponse).GetTrailers Method\u0000html/M_Grpc_Core_AsyncDuplexStreamingCall_2_GetTrailers.htm\u0000104","AsyncServerStreamingCall(TResponse).Dispose Method\u0000html/M_Grpc_Core_AsyncServerStreamingCall_1_Dispose.htm\u0000151","AsyncServerStreamingCall(TResponse).GetStatus Method\u0000html/M_Grpc_Core_AsyncServerStreamingCall_1_GetStatus.htm\u000096","AsyncServerStreamingCall(TResponse).GetTrailers Method\u0000html/M_Grpc_Core_AsyncServerStreamingCall_1_GetTrailers.htm\u000099","AsyncUnaryCall(TResponse).Dispose Method\u0000html/M_Grpc_Core_AsyncUnaryCall_1_Dispose.htm\u0000156","AsyncUnaryCall(TResponse).GetAwaiter Method\u0000html/M_Grpc_Core_AsyncUnaryCall_1_GetAwaiter.htm\u0000103","AsyncUnaryCall(TResponse).GetStatus Method\u0000html/M_Grpc_Core_AsyncUnaryCall_1_GetStatus.htm\u000096","AsyncUnaryCall(TResponse).GetTrailers Method\u0000html/M_Grpc_Core_AsyncUnaryCall_1_GetTrailers.htm\u000099","CallInvocationDetails(TRequest, TResponse).WithOptions Method\u0000html/M_Grpc_Core_CallInvocationDetails_2_WithOptions.htm\u0000186","CallInvocationDetails(TRequest, TResponse) Constructor (Channel, Method(TRequest, TResponse), CallOptions)\u0000html/M_Grpc_Core_CallInvocationDetails_2__ctor.htm\u0000221","CallInvocationDetails(TRequest, TResponse) Constructor (Channel, Method(TRequest, TResponse), String, CallOptions)\u0000html/M_Grpc_Core_CallInvocationDetails_2__ctor_1.htm\u0000265","CallInvocationDetails(TRequest, TResponse) Constructor (Channel, String, String, Marshaller(TRequest), Marshaller(TResponse), CallOptions)\u0000html/M_Grpc_Core_CallInvocationDetails_2__ctor_2.htm\u0000319","CallOptions.WithCancellationToken Method\u0000html/M_Grpc_Core_CallOptions_WithCancellationToken.htm\u0000127","CallOptions.WithDeadline Method\u0000html/M_Grpc_Core_CallOptions_WithDeadline.htm\u0000125","CallOptions.WithHeaders Method\u0000html/M_Grpc_Core_CallOptions_WithHeaders.htm\u0000128","CallOptions Constructor\u0000html/M_Grpc_Core_CallOptions__ctor.htm\u0000397","Calls.AsyncClientStreamingCall(TRequest, TResponse) Method\u0000html/M_Grpc_Core_Calls_AsyncClientStreamingCall__2.htm\u0000283","Calls.AsyncDuplexStreamingCall(TRequest, TResponse) Method\u0000html/M_Grpc_Core_Calls_AsyncDuplexStreamingCall__2.htm\u0000305","Calls.AsyncServerStreamingCall(TRequest, TResponse) Method\u0000html/M_Grpc_Core_Calls_AsyncServerStreamingCall__2.htm\u0000297","Calls.AsyncUnaryCall(TRequest, TResponse) Method\u0000html/M_Grpc_Core_Calls_AsyncUnaryCall__2.htm\u0000278","Calls.BlockingUnaryCall(TRequest, TResponse) Method\u0000html/M_Grpc_Core_Calls_BlockingUnaryCall__2.htm\u0000258","ChannelOption Constructor (String, Int32)\u0000html/M_Grpc_Core_ChannelOption__ctor.htm\u0000137","ChannelOption Constructor (String, String)\u0000html/M_Grpc_Core_ChannelOption__ctor_1.htm\u0000139","Channel.ConnectAsync Method\u0000html/M_Grpc_Core_Channel_ConnectAsync.htm\u0000229","Channel.ShutdownAsync Method\u0000html/M_Grpc_Core_Channel_ShutdownAsync.htm\u0000102","Channel.WaitForStateChangedAsync Method\u0000html/M_Grpc_Core_Channel_WaitForStateChangedAsync.htm\u0000266","Channel Constructor (String, Credentials, IEnumerable(ChannelOption))\u0000html/M_Grpc_Core_Channel__ctor.htm\u0000252","Channel Constructor (String, Int32, Credentials, IEnumerable(ChannelOption))\u0000html/M_Grpc_Core_Channel__ctor_1.htm\u0000270","ClientBase.CreateCall(TRequest, TResponse) Method\u0000html/M_Grpc_Core_ClientBase_CreateCall__2.htm\u0000283","ClientBase Constructor\u0000html/M_Grpc_Core_ClientBase__ctor.htm\u0000110","ContextPropagationOptions Constructor\u0000html/M_Grpc_Core_ContextPropagationOptions__ctor.htm\u0000205","Credentials Constructor\u0000html/M_Grpc_Core_Credentials__ctor.htm\u000076","GrpcEnvironment.SetLogger Method\u0000html/M_Grpc_Core_GrpcEnvironment_SetLogger.htm\u0000139","IAsyncStreamWriter(T).WriteAsync Method\u0000html/M_Grpc_Core_IAsyncStreamWriter_1_WriteAsync.htm\u0000125","IClientStreamWriter(T).CompleteAsync Method\u0000html/M_Grpc_Core_IClientStreamWriter_1_CompleteAsync.htm\u0000101","KeyCertificatePair Constructor\u0000html/M_Grpc_Core_KeyCertificatePair__ctor.htm\u0000139","ConsoleLogger.Debug Method\u0000html/M_Grpc_Core_Logging_ConsoleLogger_Debug.htm\u0000238","ConsoleLogger.Error Method (Exception, String, Object[])\u0000html/M_Grpc_Core_Logging_ConsoleLogger_Error.htm\u0000320","ConsoleLogger.Error Method (String, Object[])\u0000html/M_Grpc_Core_Logging_ConsoleLogger_Error_1.htm\u0000246","ConsoleLogger.ForType(T) Method\u0000html/M_Grpc_Core_Logging_ConsoleLogger_ForType__1.htm\u0000147","ConsoleLogger.Info Method\u0000html/M_Grpc_Core_Logging_ConsoleLogger_Info.htm\u0000238","ConsoleLogger.Warning Method (Exception, String, Object[])\u0000html/M_Grpc_Core_Logging_ConsoleLogger_Warning.htm\u0000320","ConsoleLogger.Warning Method (String, Object[])\u0000html/M_Grpc_Core_Logging_ConsoleLogger_Warning_1.htm\u0000246","ConsoleLogger Constructor\u0000html/M_Grpc_Core_Logging_ConsoleLogger__ctor.htm\u000081","ILogger.Debug Method\u0000html/M_Grpc_Core_Logging_ILogger_Debug.htm\u0000202","ILogger.Error Method (Exception, String, Object[])\u0000html/M_Grpc_Core_Logging_ILogger_Error.htm\u0000276","ILogger.Error Method (String, Object[])\u0000html/M_Grpc_Core_Logging_ILogger_Error_1.htm\u0000210","ILogger.ForType(T) Method\u0000html/M_Grpc_Core_Logging_ILogger_ForType__1.htm\u0000127","ILogger.Info Method\u0000html/M_Grpc_Core_Logging_ILogger_Info.htm\u0000202","ILogger.Warning Method (Exception, String, Object[])\u0000html/M_Grpc_Core_Logging_ILogger_Warning.htm\u0000276","ILogger.Warning Method (String, Object[])\u0000html/M_Grpc_Core_Logging_ILogger_Warning_1.htm\u0000210","Marshallers.Create(T) Method\u0000html/M_Grpc_Core_Marshallers_Create__1.htm\u0000391","Marshaller(T) Constructor\u0000html/M_Grpc_Core_Marshaller_1__ctor.htm\u0000229","Metadata.Add Method (Metadata.Entry)\u0000html/M_Grpc_Core_Metadata_Add.htm\u0000172","Metadata.Add Method (String, Byte[])\u0000html/M_Grpc_Core_Metadata_Add_1.htm\u0000220","Metadata.Add Method (String, String)\u0000html/M_Grpc_Core_Metadata_Add_2.htm\u0000199","Metadata.Clear Method\u0000html/M_Grpc_Core_Metadata_Clear.htm\u0000102","Metadata.Contains Method\u0000html/M_Grpc_Core_Metadata_Contains.htm\u0000173","Metadata.CopyTo Method\u0000html/M_Grpc_Core_Metadata_CopyTo.htm\u0000254","Metadata.Entry.ToString Method\u0000html/M_Grpc_Core_Metadata_Entry_ToString.htm\u0000107","Metadata.Entry Constructor (String, Byte[])\u0000html/M_Grpc_Core_Metadata_Entry__ctor.htm\u0000174","Metadata.Entry Constructor (String, String)\u0000html/M_Grpc_Core_Metadata_Entry__ctor_1.htm\u0000165","Metadata.GetEnumerator Method\u0000html/M_Grpc_Core_Metadata_GetEnumerator.htm\u0000143","Metadata.IndexOf Method\u0000html/M_Grpc_Core_Metadata_IndexOf.htm\u0000173","Metadata.Insert Method\u0000html/M_Grpc_Core_Metadata_Insert.htm\u0000229","Metadata.Remove Method\u0000html/M_Grpc_Core_Metadata_Remove.htm\u0000173","Metadata.RemoveAt Method\u0000html/M_Grpc_Core_Metadata_RemoveAt.htm\u0000155","Metadata Constructor\u0000html/M_Grpc_Core_Metadata__ctor.htm\u000076","Method(TRequest, TResponse) Constructor\u0000html/M_Grpc_Core_Method_2__ctor.htm\u0000272","RpcException Constructor (Status)\u0000html/M_Grpc_Core_RpcException__ctor.htm\u0000111","RpcException Constructor (Status, String)\u0000html/M_Grpc_Core_RpcException__ctor_1.htm\u0000145","ServerCallContext.CreatePropagationToken Method\u0000html/M_Grpc_Core_ServerCallContext_CreatePropagationToken.htm\u0000177","ServerCallContext.WriteResponseHeadersAsync Method\u0000html/M_Grpc_Core_ServerCallContext_WriteResponseHeadersAsync.htm\u0000174","ServerCredentials Constructor\u0000html/M_Grpc_Core_ServerCredentials__ctor.htm\u000076","ServerPort Constructor\u0000html/M_Grpc_Core_ServerPort__ctor.htm\u0000189","ServerServiceDefinition.Builder.AddMethod(TRequest, TResponse) Method (Method(TRequest, TResponse), ClientStreamingServerMethod(TRequest, TResponse))\u0000html/M_Grpc_Core_ServerServiceDefinition_Builder_AddMethod__2.htm\u0000310","ServerServiceDefinition.Builder.AddMethod(TRequest, TResponse) Method (Method(TRequest, TResponse), DuplexStreamingServerMethod(TRequest, TResponse))\u0000html/M_Grpc_Core_ServerServiceDefinition_Builder_AddMethod__2_1.htm\u0000310","ServerServiceDefinition.Builder.AddMethod(TRequest, TResponse) Method (Method(TRequest, TResponse), ServerStreamingServerMethod(TRequest, TResponse))\u0000html/M_Grpc_Core_ServerServiceDefinition_Builder_AddMethod__2_2.htm\u0000310","ServerServiceDefinition.Builder.AddMethod(TRequest, TResponse) Method (Method(TRequest, TResponse), UnaryServerMethod(TRequest, TResponse))\u0000html/M_Grpc_Core_ServerServiceDefinition_Builder_AddMethod__2_3.htm\u0000314","ServerServiceDefinition.Builder.Build Method\u0000html/M_Grpc_Core_ServerServiceDefinition_Builder_Build.htm\u000095","ServerServiceDefinition.Builder Constructor\u0000html/M_Grpc_Core_ServerServiceDefinition_Builder__ctor.htm\u0000105","ServerServiceDefinition.CreateBuilder Method\u0000html/M_Grpc_Core_ServerServiceDefinition_CreateBuilder.htm\u0000131","Server.KillAsync Method\u0000html/M_Grpc_Core_Server_KillAsync.htm\u0000102","Server.ServerPortCollection.Add Method (ServerPort)\u0000html/M_Grpc_Core_Server_ServerPortCollection_Add.htm\u0000168","Server.ServerPortCollection.Add Method (String, Int32, ServerCredentials)\u0000html/M_Grpc_Core_Server_ServerPortCollection_Add_1.htm\u0000212","Server.ServerPortCollection.GetEnumerator Method\u0000html/M_Grpc_Core_Server_ServerPortCollection_GetEnumerator.htm\u0000131","Server.ServiceDefinitionCollection.Add Method\u0000html/M_Grpc_Core_Server_ServiceDefinitionCollection_Add.htm\u0000153","Server.ServiceDefinitionCollection.GetEnumerator Method\u0000html/M_Grpc_Core_Server_ServiceDefinitionCollection_GetEnumerator.htm\u0000131","Server.ShutdownAsync Method\u0000html/M_Grpc_Core_Server_ShutdownAsync.htm\u0000109","Server.Start Method\u0000html/M_Grpc_Core_Server_Start.htm\u000076","Server Constructor\u0000html/M_Grpc_Core_Server__ctor.htm\u0000155","SslCredentials Constructor\u0000html/M_Grpc_Core_SslCredentials__ctor.htm\u0000103","SslCredentials Constructor (String)\u0000html/M_Grpc_Core_SslCredentials__ctor_1.htm\u0000135","SslCredentials Constructor (String, KeyCertificatePair)\u0000html/M_Grpc_Core_SslCredentials__ctor_2.htm\u0000145","SslServerCredentials Constructor (IEnumerable(KeyCertificatePair))\u0000html/M_Grpc_Core_SslServerCredentials__ctor.htm\u0000152","SslServerCredentials Constructor (IEnumerable(KeyCertificatePair), String, Boolean)\u0000html/M_Grpc_Core_SslServerCredentials__ctor_1.htm\u0000213","Status.ToString Method\u0000html/M_Grpc_Core_Status_ToString.htm\u0000104","Status Constructor\u0000html/M_Grpc_Core_Status__ctor.htm\u0000130","AsyncStreamExtensions.ForEachAsync(T) Method\u0000html/M_Grpc_Core_Utils_AsyncStreamExtensions_ForEachAsync__1.htm\u0000440","AsyncStreamExtensions.ToListAsync(T) Method\u0000html/M_Grpc_Core_Utils_AsyncStreamExtensions_ToListAsync__1.htm\u0000358","AsyncStreamExtensions.WriteAllAsync(T) Method (IClientStreamWriter(T), IEnumerable(T), Boolean)\u0000html/M_Grpc_Core_Utils_AsyncStreamExtensions_WriteAllAsync__1.htm\u0000541","AsyncStreamExtensions.WriteAllAsync(T) Method (IServerStreamWriter(T), IEnumerable(T))\u0000html/M_Grpc_Core_Utils_AsyncStreamExtensions_WriteAllAsync__1_1.htm\u0000428","BenchmarkUtil.RunBenchmark Method\u0000html/M_Grpc_Core_Utils_BenchmarkUtil_RunBenchmark.htm\u0000243","Preconditions.CheckArgument Method (Boolean)\u0000html/M_Grpc_Core_Utils_Preconditions_CheckArgument.htm\u0000115","Preconditions.CheckArgument Method (Boolean, String)\u0000html/M_Grpc_Core_Utils_Preconditions_CheckArgument_1.htm\u0000150","Preconditions.CheckNotNull(T) Method (T)\u0000html/M_Grpc_Core_Utils_Preconditions_CheckNotNull__1.htm\u0000169","Preconditions.CheckNotNull(T) Method (T, String)\u0000html/M_Grpc_Core_Utils_Preconditions_CheckNotNull__1_1.htm\u0000202","Preconditions.CheckState Method (Boolean)\u0000html/M_Grpc_Core_Utils_Preconditions_CheckState.htm\u0000115","Preconditions.CheckState Method (Boolean, String)\u0000html/M_Grpc_Core_Utils_Preconditions_CheckState_1.htm\u0000150","WriteOptions Constructor\u0000html/M_Grpc_Core_WriteOptions__ctor.htm\u0000130","Grpc.Auth Namespace\u0000html/N_Grpc_Auth.htm\u000066","Grpc.Core Namespace\u0000html/N_Grpc_Core.htm\u0000823","Grpc.Core.Logging Namespace\u0000html/N_Grpc_Core_Logging.htm\u000039","Grpc.Core.Utils Namespace\u0000html/N_Grpc_Core_Utils.htm\u000048","CallInvocationDetails(TRequest, TResponse) Constructor\u0000html/Overload_Grpc_Core_CallInvocationDetails_2__ctor.htm\u0000116","ChannelOption Constructor\u0000html/Overload_Grpc_Core_ChannelOption__ctor.htm\u000048","Channel Constructor\u0000html/Overload_Grpc_Core_Channel__ctor.htm\u000079","ConsoleLogger.Error Method\u0000html/Overload_Grpc_Core_Logging_ConsoleLogger_Error.htm\u000054","ConsoleLogger.Warning Method\u0000html/Overload_Grpc_Core_Logging_ConsoleLogger_Warning.htm\u000054","ILogger.Error Method\u0000html/Overload_Grpc_Core_Logging_ILogger_Error.htm\u000054","ILogger.Warning Method\u0000html/Overload_Grpc_Core_Logging_ILogger_Warning.htm\u000054","Metadata.Add Method\u0000html/Overload_Grpc_Core_Metadata_Add.htm\u000036","Entry Constructor\u0000html/Overload_Grpc_Core_Metadata_Entry__ctor.htm\u000062","RpcException Constructor\u0000html/Overload_Grpc_Core_RpcException__ctor.htm\u000048","Builder.AddMethod Method\u0000html/Overload_Grpc_Core_ServerServiceDefinition_Builder_AddMethod.htm\u0000130","ServerPortCollection.Add Method\u0000html/Overload_Grpc_Core_Server_ServerPortCollection_Add.htm\u000086","SslCredentials Constructor\u0000html/Overload_Grpc_Core_SslCredentials__ctor.htm\u000082","SslServerCredentials Constructor\u0000html/Overload_Grpc_Core_SslServerCredentials__ctor.htm\u000064","AsyncStreamExtensions.WriteAllAsync Method\u0000html/Overload_Grpc_Core_Utils_AsyncStreamExtensions_WriteAllAsync.htm\u000076","Preconditions.CheckArgument Method\u0000html/Overload_Grpc_Core_Utils_Preconditions_CheckArgument.htm\u000047","Preconditions.CheckNotNull Method\u0000html/Overload_Grpc_Core_Utils_Preconditions_CheckNotNull.htm\u000048","Preconditions.CheckState Method\u0000html/Overload_Grpc_Core_Utils_Preconditions_CheckState.htm\u000047","AsyncClientStreamingCall(TRequest, TResponse) Properties\u0000html/Properties_T_Grpc_Core_AsyncClientStreamingCall_2.htm\u000058","AsyncDuplexStreamingCall(TRequest, TResponse) Properties\u0000html/Properties_T_Grpc_Core_AsyncDuplexStreamingCall_2.htm\u000061","AsyncServerStreamingCall(TResponse) Properties\u0000html/Properties_T_Grpc_Core_AsyncServerStreamingCall_1.htm\u000046","AsyncUnaryCall(TResponse) Properties\u0000html/Properties_T_Grpc_Core_AsyncUnaryCall_1.htm\u000043","CallInvocationDetails(TRequest, TResponse) Properties\u0000html/Properties_T_Grpc_Core_CallInvocationDetails_2.htm\u000083","CallOptions Properties\u0000html/Properties_T_Grpc_Core_CallOptions.htm\u000072","Channel Properties\u0000html/Properties_T_Grpc_Core_Channel.htm\u000057","ChannelOption Properties\u0000html/Properties_T_Grpc_Core_ChannelOption.htm\u000063","ClientBase Properties\u0000html/Properties_T_Grpc_Core_ClientBase.htm\u0000108","ContextPropagationOptions Properties\u0000html/Properties_T_Grpc_Core_ContextPropagationOptions.htm\u000056","Credentials Properties\u0000html/Properties_T_Grpc_Core_Credentials.htm\u000049","GrpcEnvironment Properties\u0000html/Properties_T_Grpc_Core_GrpcEnvironment.htm\u000036","IAsyncStreamReader(T) Properties\u0000html/Properties_T_Grpc_Core_IAsyncStreamReader_1.htm\u000040","IAsyncStreamWriter(T) Properties\u0000html/Properties_T_Grpc_Core_IAsyncStreamWriter_1.htm\u000064","IClientStreamWriter(T) Properties\u0000html/Properties_T_Grpc_Core_IClientStreamWriter_1.htm\u000072","IHasWriteOptions Properties\u0000html/Properties_T_Grpc_Core_IHasWriteOptions.htm\u000035","IMethod Properties\u0000html/Properties_T_Grpc_Core_IMethod.htm\u000080","IServerStreamWriter(T) Properties\u0000html/Properties_T_Grpc_Core_IServerStreamWriter_1.htm\u000072","KeyCertificatePair Properties\u0000html/Properties_T_Grpc_Core_KeyCertificatePair.htm\u000039","Marshallers Properties\u0000html/Properties_T_Grpc_Core_Marshallers.htm\u000041","Marshaller(T) Properties\u0000html/Properties_T_Grpc_Core_Marshaller_1.htm\u000043","Metadata Properties\u0000html/Properties_T_Grpc_Core_Metadata.htm\u000030","Entry Properties\u0000html/Properties_T_Grpc_Core_Metadata_Entry.htm\u000068","Method(TRequest, TResponse) Properties\u0000html/Properties_T_Grpc_Core_Method_2.htm\u0000109","RpcException Properties\u0000html/Properties_T_Grpc_Core_RpcException.htm\u0000203","Server Properties\u0000html/Properties_T_Grpc_Core_Server.htm\u000087","ServerCallContext Properties\u0000html/Properties_T_Grpc_Core_ServerCallContext.htm\u0000135","ServerCredentials Properties\u0000html/Properties_T_Grpc_Core_ServerCredentials.htm\u000050","ServerPort Properties\u0000html/Properties_T_Grpc_Core_ServerPort.htm\u000031","SslCredentials Properties\u0000html/Properties_T_Grpc_Core_SslCredentials.htm\u000056","SslServerCredentials Properties\u0000html/Properties_T_Grpc_Core_SslServerCredentials.htm\u000052","Status Properties\u0000html/Properties_T_Grpc_Core_Status.htm\u000050","WriteOptions Properties\u0000html/Properties_T_Grpc_Core_WriteOptions.htm\u000033","AsyncClientStreamingCall(TRequest, TResponse).RequestStream Property\u0000html/P_Grpc_Core_AsyncClientStreamingCall_2_RequestStream.htm\u0000126","AsyncClientStreamingCall(TRequest, TResponse).ResponseAsync Property\u0000html/P_Grpc_Core_AsyncClientStreamingCall_2_ResponseAsync.htm\u0000123","AsyncClientStreamingCall(TRequest, TResponse).ResponseHeadersAsync Property\u0000html/P_Grpc_Core_AsyncClientStreamingCall_2_ResponseHeadersAsync.htm\u0000135","AsyncDuplexStreamingCall(TRequest, TResponse).RequestStream Property\u0000html/P_Grpc_Core_AsyncDuplexStreamingCall_2_RequestStream.htm\u0000126","AsyncDuplexStreamingCall(TRequest, TResponse).ResponseHeadersAsync Property\u0000html/P_Grpc_Core_AsyncDuplexStreamingCall_2_ResponseHeadersAsync.htm\u0000135","AsyncDuplexStreamingCall(TRequest, TResponse).ResponseStream Property\u0000html/P_Grpc_Core_AsyncDuplexStreamingCall_2_ResponseStream.htm\u0000126","AsyncServerStreamingCall(TResponse).ResponseHeadersAsync Property\u0000html/P_Grpc_Core_AsyncServerStreamingCall_1_ResponseHeadersAsync.htm\u0000130","AsyncServerStreamingCall(TResponse).ResponseStream Property\u0000html/P_Grpc_Core_AsyncServerStreamingCall_1_ResponseStream.htm\u0000121","AsyncUnaryCall(TResponse).ResponseAsync Property\u0000html/P_Grpc_Core_AsyncUnaryCall_1_ResponseAsync.htm\u0000118","AsyncUnaryCall(TResponse).ResponseHeadersAsync Property\u0000html/P_Grpc_Core_AsyncUnaryCall_1_ResponseHeadersAsync.htm\u0000130","CallInvocationDetails(TRequest, TResponse).Channel Property\u0000html/P_Grpc_Core_CallInvocationDetails_2_Channel.htm\u0000109","CallInvocationDetails(TRequest, TResponse).Host Property\u0000html/P_Grpc_Core_CallInvocationDetails_2_Host.htm\u0000107","CallInvocationDetails(TRequest, TResponse).Method Property\u0000html/P_Grpc_Core_CallInvocationDetails_2_Method.htm\u0000110","CallInvocationDetails(TRequest, TResponse).Options Property\u0000html/P_Grpc_Core_CallInvocationDetails_2_Options.htm\u0000103","CallInvocationDetails(TRequest, TResponse).RequestMarshaller Property\u0000html/P_Grpc_Core_CallInvocationDetails_2_RequestMarshaller.htm\u0000126","CallInvocationDetails(TRequest, TResponse).ResponseMarshaller Property\u0000html/P_Grpc_Core_CallInvocationDetails_2_ResponseMarshaller.htm\u0000126","CallOptions.CancellationToken Property\u0000html/P_Grpc_Core_CallOptions_CancellationToken.htm\u0000101","CallOptions.Deadline Property\u0000html/P_Grpc_Core_CallOptions_Deadline.htm\u0000121","CallOptions.Headers Property\u0000html/P_Grpc_Core_CallOptions_Headers.htm\u0000105","CallOptions.PropagationToken Property\u0000html/P_Grpc_Core_CallOptions_PropagationToken.htm\u0000102","CallOptions.WriteOptions Property\u0000html/P_Grpc_Core_CallOptions_WriteOptions.htm\u0000105","ChannelOption.IntValue Property\u0000html/P_Grpc_Core_ChannelOption_IntValue.htm\u000099","ChannelOption.Name Property\u0000html/P_Grpc_Core_ChannelOption_Name.htm\u0000103","ChannelOption.StringValue Property\u0000html/P_Grpc_Core_ChannelOption_StringValue.htm\u0000103","ChannelOption.Type Property\u0000html/P_Grpc_Core_ChannelOption_Type.htm\u0000105","Channel.ResolvedTarget Property\u0000html/P_Grpc_Core_Channel_ResolvedTarget.htm\u0000105","Channel.State Property\u0000html/P_Grpc_Core_Channel_State.htm\u000099","Channel.Target Property\u0000html/P_Grpc_Core_Channel_Target.htm\u0000104","ClientBase.Channel Property\u0000html/P_Grpc_Core_ClientBase_Channel.htm\u0000101","ClientBase.HeaderInterceptor Property\u0000html/P_Grpc_Core_ClientBase_HeaderInterceptor.htm\u0000141","ClientBase.Host Property\u0000html/P_Grpc_Core_ClientBase_Host.htm\u0000155","ContextPropagationOptions.IsPropagateCancellation Property\u0000html/P_Grpc_Core_ContextPropagationOptions_IsPropagateCancellation.htm\u0000105","ContextPropagationOptions.IsPropagateDeadline Property\u0000html/P_Grpc_Core_ContextPropagationOptions_IsPropagateDeadline.htm\u0000104","Credentials.Insecure Property\u0000html/P_Grpc_Core_Credentials_Insecure.htm\u0000120","GrpcEnvironment.Logger Property\u0000html/P_Grpc_Core_GrpcEnvironment_Logger.htm\u0000110","IAsyncStreamWriter(T).WriteOptions Property\u0000html/P_Grpc_Core_IAsyncStreamWriter_1_WriteOptions.htm\u0000141","IHasWriteOptions.WriteOptions Property\u0000html/P_Grpc_Core_IHasWriteOptions_WriteOptions.htm\u0000114","IMethod.FullName Property\u0000html/P_Grpc_Core_IMethod_FullName.htm\u0000112","IMethod.Name Property\u0000html/P_Grpc_Core_IMethod_Name.htm\u000098","IMethod.ServiceName Property\u0000html/P_Grpc_Core_IMethod_ServiceName.htm\u0000102","IMethod.Type Property\u0000html/P_Grpc_Core_IMethod_Type.htm\u000093","KeyCertificatePair.CertificateChain Property\u0000html/P_Grpc_Core_KeyCertificatePair_CertificateChain.htm\u0000100","KeyCertificatePair.PrivateKey Property\u0000html/P_Grpc_Core_KeyCertificatePair_PrivateKey.htm\u0000100","Marshallers.StringMarshaller Property\u0000html/P_Grpc_Core_Marshallers_StringMarshaller.htm\u0000139","Marshaller(T).Deserializer Property\u0000html/P_Grpc_Core_Marshaller_1_Deserializer.htm\u0000159","Marshaller(T).Serializer Property\u0000html/P_Grpc_Core_Marshaller_1_Serializer.htm\u0000155","Metadata.Count Property\u0000html/P_Grpc_Core_Metadata_Count.htm\u0000120","Metadata.Entry.IsBinary Property\u0000html/P_Grpc_Core_Metadata_Entry_IsBinary.htm\u0000104","Metadata.Entry.Key Property\u0000html/P_Grpc_Core_Metadata_Entry_Key.htm\u0000103","Metadata.Entry.Value Property\u0000html/P_Grpc_Core_Metadata_Entry_Value.htm\u0000106","Metadata.Entry.ValueBytes Property\u0000html/P_Grpc_Core_Metadata_Entry_ValueBytes.htm\u0000125","Metadata.IsReadOnly Property\u0000html/P_Grpc_Core_Metadata_IsReadOnly.htm\u0000120","Metadata.Item Property\u0000html/P_Grpc_Core_Metadata_Item.htm\u0000185","Method(TRequest, TResponse).FullName Property\u0000html/P_Grpc_Core_Method_2_FullName.htm\u0000137","Method(TRequest, TResponse).Name Property\u0000html/P_Grpc_Core_Method_2_Name.htm\u0000123","Method(TRequest, TResponse).RequestMarshaller Property\u0000html/P_Grpc_Core_Method_2_RequestMarshaller.htm\u0000127","Method(TRequest, TResponse).ResponseMarshaller Property\u0000html/P_Grpc_Core_Method_2_ResponseMarshaller.htm\u0000127","Method(TRequest, TResponse).ServiceName Property\u0000html/P_Grpc_Core_Method_2_ServiceName.htm\u0000127","Method(TRequest, TResponse).Type Property\u0000html/P_Grpc_Core_Method_2_Type.htm\u0000118","RpcException.Status Property\u0000html/P_Grpc_Core_RpcException_Status.htm\u000097","ServerCallContext.CancellationToken Property\u0000html/P_Grpc_Core_ServerCallContext_CancellationToken.htm\u000099","ServerCallContext.Deadline Property\u0000html/P_Grpc_Core_ServerCallContext_Deadline.htm\u000096","ServerCallContext.Host Property\u0000html/P_Grpc_Core_ServerCallContext_Host.htm\u0000103","ServerCallContext.Method Property\u0000html/P_Grpc_Core_ServerCallContext_Method.htm\u0000103","ServerCallContext.Peer Property\u0000html/P_Grpc_Core_ServerCallContext_Peer.htm\u0000104","ServerCallContext.RequestHeaders Property\u0000html/P_Grpc_Core_ServerCallContext_RequestHeaders.htm\u0000101","ServerCallContext.ResponseTrailers Property\u0000html/P_Grpc_Core_ServerCallContext_ResponseTrailers.htm\u0000105","ServerCallContext.Status Property\u0000html/P_Grpc_Core_ServerCallContext_Status.htm\u0000116","ServerCallContext.WriteOptions Property\u0000html/P_Grpc_Core_ServerCallContext_WriteOptions.htm\u0000147","ServerCredentials.Insecure Property\u0000html/P_Grpc_Core_ServerCredentials_Insecure.htm\u0000121","ServerPort.BoundPort Property\u0000html/P_Grpc_Core_ServerPort_BoundPort.htm\u0000126","ServerPort.Credentials Property\u0000html/P_Grpc_Core_ServerPort_Credentials.htm\u0000114","ServerPort.Host Property\u0000html/P_Grpc_Core_ServerPort_Host.htm\u0000113","ServerPort.Port Property\u0000html/P_Grpc_Core_ServerPort_Port.htm\u0000109","Server.Ports Property\u0000html/P_Grpc_Core_Server_Ports.htm\u0000125","Server.Services Property\u0000html/P_Grpc_Core_Server_Services.htm\u0000126","Server.ShutdownTask Property\u0000html/P_Grpc_Core_Server_ShutdownTask.htm\u0000103","SslCredentials.KeyCertificatePair Property\u0000html/P_Grpc_Core_SslCredentials_KeyCertificatePair.htm\u0000114","SslCredentials.RootCertificates Property\u0000html/P_Grpc_Core_SslCredentials_RootCertificates.htm\u0000103","SslServerCredentials.ForceClientAuthentication Property\u0000html/P_Grpc_Core_SslServerCredentials_ForceClientAuthentication.htm\u0000103","SslServerCredentials.KeyCertificatePairs Property\u0000html/P_Grpc_Core_SslServerCredentials_KeyCertificatePairs.htm\u0000126","SslServerCredentials.RootCertificates Property\u0000html/P_Grpc_Core_SslServerCredentials_RootCertificates.htm\u0000101","Status.Detail Property\u0000html/P_Grpc_Core_Status_Detail.htm\u000099","Status.StatusCode Property\u0000html/P_Grpc_Core_Status_StatusCode.htm\u0000108","WriteOptions.Flags Property\u0000html/P_Grpc_Core_WriteOptions_Flags.htm\u000096","Namespaces\u0000html/R_Project_Documentation.htm\u000084","AuthInterceptors Class\u0000html/T_Grpc_Auth_AuthInterceptors.htm\u0000161","AsyncClientStreamingCall(TRequest, TResponse) Class\u0000html/T_Grpc_Core_AsyncClientStreamingCall_2.htm\u0000362","AsyncDuplexStreamingCall(TRequest, TResponse) Class\u0000html/T_Grpc_Core_AsyncDuplexStreamingCall_2.htm\u0000359","AsyncServerStreamingCall(TResponse) Class\u0000html/T_Grpc_Core_AsyncServerStreamingCall_1.htm\u0000320","AsyncUnaryCall(TResponse) Class\u0000html/T_Grpc_Core_AsyncUnaryCall_1.htm\u0000333","CallInvocationDetails(TRequest, TResponse) Structure\u0000html/T_Grpc_Core_CallInvocationDetails_2.htm\u0000377","CallOptions Structure\u0000html/T_Grpc_Core_CallOptions.htm\u0000282","Calls Class\u0000html/T_Grpc_Core_Calls.htm\u0000262","Channel Class\u0000html/T_Grpc_Core_Channel.htm\u0000461","ChannelOption Class\u0000html/T_Grpc_Core_ChannelOption.htm\u0000244","ChannelOptions Class\u0000html/T_Grpc_Core_ChannelOptions.htm\u0000187","ChannelOption.OptionType Enumeration\u0000html/T_Grpc_Core_ChannelOption_OptionType.htm\u000082","ChannelState Enumeration\u0000html/T_Grpc_Core_ChannelState.htm\u0000113","ClientBase Class\u0000html/T_Grpc_Core_ClientBase.htm\u0000320","ClientStreamingServerMethod(TRequest, TResponse) Delegate\u0000html/T_Grpc_Core_ClientStreamingServerMethod_2.htm\u0000240","CompressionLevel Enumeration\u0000html/T_Grpc_Core_CompressionLevel.htm\u000089","ContextPropagationOptions Class\u0000html/T_Grpc_Core_ContextPropagationOptions.htm\u0000258","ContextPropagationToken Class\u0000html/T_Grpc_Core_ContextPropagationToken.htm\u0000268","Credentials Class\u0000html/T_Grpc_Core_Credentials.htm\u0000257","DuplexStreamingServerMethod(TRequest, TResponse) Delegate\u0000html/T_Grpc_Core_DuplexStreamingServerMethod_2.htm\u0000266","GrpcEnvironment Class\u0000html/T_Grpc_Core_GrpcEnvironment.htm\u0000227","HeaderInterceptor Delegate\u0000html/T_Grpc_Core_HeaderInterceptor.htm\u0000155","IAsyncStreamReader(T) Interface\u0000html/T_Grpc_Core_IAsyncStreamReader_1.htm\u0000234","IAsyncStreamWriter(T) Interface\u0000html/T_Grpc_Core_IAsyncStreamWriter_1.htm\u0000157","IClientStreamWriter(T) Interface\u0000html/T_Grpc_Core_IClientStreamWriter_1.htm\u0000260","IHasWriteOptions Interface\u0000html/T_Grpc_Core_IHasWriteOptions.htm\u000089","IMethod Interface\u0000html/T_Grpc_Core_IMethod.htm\u0000133","IServerStreamWriter(T) Interface\u0000html/T_Grpc_Core_IServerStreamWriter_1.htm\u0000245","KeyCertificatePair Class\u0000html/T_Grpc_Core_KeyCertificatePair.htm\u0000197","ConsoleLogger Class\u0000html/T_Grpc_Core_Logging_ConsoleLogger.htm\u0000320","ILogger Interface\u0000html/T_Grpc_Core_Logging_ILogger.htm\u0000168","Marshallers Class\u0000html/T_Grpc_Core_Marshallers.htm\u0000130","Marshaller(T) Class\u0000html/T_Grpc_Core_Marshaller_1.htm\u0000273","Metadata Class\u0000html/T_Grpc_Core_Metadata.htm\u0000421","Metadata.Entry Structure\u0000html/T_Grpc_Core_Metadata_Entry.htm\u0000240","MethodType Enumeration\u0000html/T_Grpc_Core_MethodType.htm\u0000126","Method(TRequest, TResponse) Class\u0000html/T_Grpc_Core_Method_2.htm\u0000358","RpcException Class\u0000html/T_Grpc_Core_RpcException.htm\u0000526","Server Class\u0000html/T_Grpc_Core_Server.htm\u0000344","ServerCallContext Class\u0000html/T_Grpc_Core_ServerCallContext.htm\u0000381","ServerCredentials Class\u0000html/T_Grpc_Core_ServerCredentials.htm\u0000250","ServerPort Class\u0000html/T_Grpc_Core_ServerPort.htm\u0000260","ServerServiceDefinition Class\u0000html/T_Grpc_Core_ServerServiceDefinition.htm\u0000239","ServerServiceDefinition.Builder Class\u0000html/T_Grpc_Core_ServerServiceDefinition_Builder.htm\u0000332","ServerStreamingServerMethod(TRequest, TResponse) Delegate\u0000html/T_Grpc_Core_ServerStreamingServerMethod_2.htm\u0000248","Server.ServerPortCollection Class\u0000html/T_Grpc_Core_Server_ServerPortCollection.htm\u0000312","Server.ServiceDefinitionCollection Class\u0000html/T_Grpc_Core_Server_ServiceDefinitionCollection.htm\u0000278","SslCredentials Class\u0000html/T_Grpc_Core_SslCredentials.htm\u0000274","SslServerCredentials Class\u0000html/T_Grpc_Core_SslServerCredentials.htm\u0000289","Status Structure\u0000html/T_Grpc_Core_Status.htm\u0000235","StatusCode Enumeration\u0000html/T_Grpc_Core_StatusCode.htm\u0000545","UnaryServerMethod(TRequest, TResponse) Delegate\u0000html/T_Grpc_Core_UnaryServerMethod_2.htm\u0000221","AsyncStreamExtensions Class\u0000html/T_Grpc_Core_Utils_AsyncStreamExtensions.htm\u0000211","BenchmarkUtil Class\u0000html/T_Grpc_Core_Utils_BenchmarkUtil.htm\u0000115","Preconditions Class\u0000html/T_Grpc_Core_Utils_Preconditions.htm\u0000177","VersionInfo Class\u0000html/T_Grpc_Core_VersionInfo.htm\u0000111","WriteFlags Enumeration\u0000html/T_Grpc_Core_WriteFlags.htm\u0000148","WriteOptions Class\u0000html/T_Grpc_Core_WriteOptions.htm\u0000230"] \ No newline at end of file diff --git a/doc/ref/csharp/html/html/F_Grpc_Core_ChannelOptions_Census.htm b/doc/ref/csharp/html/html/F_Grpc_Core_ChannelOptions_Census.htm index ed73663360..4d26b5f04f 100644 --- a/doc/ref/csharp/html/html/F_Grpc_Core_ChannelOptions_Census.htm +++ b/doc/ref/csharp/html/html/F_Grpc_Core_ChannelOptions_Census.htm @@ -1,2 +1,2 @@ -ChannelOptions.Census Field
ChannelOptionsCensus Field
Enable census for tracing and stats collection

Namespace: Grpc.Core
Assembly: Grpc.Core (in Grpc.Core.dll) Version: 0.6.1.0
Syntax
public const string Census