更多內容參考:https://www.grpc.io/docs/guides/ java
gRPC 是一個高性能、開源和通用的 RPC 框架,面向移動和 HTTP/2 設計。目前提供 C、Java 和 Go 語言版本,分別是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.node
gRPC 基於 HTTP/2 標準設計,帶來諸如雙向流、流控、頭部壓縮、單 TCP 鏈接上的多複用請求等特。這些特性使得其在移動設備上表現更好,更省電和節省空間佔用。linux
在 gRPC 裏客戶端應用能夠像調用本地對象同樣直接調用另外一臺不一樣的機器上服務端應用的方法 ,使得您可以更容易地建立分佈式應用和服務。與許多 RPC 系統相似,git
定義一個服務,指定其可以被遠程調用的方法(包含參數和返回類型)。在服務端實現這個接口 ,並運行一個 gRPC 服務器來處理客戶端調用。在客戶端擁有一個存根可以像服務端同樣的方法。github
gRPC 客戶端和服務端能夠在多種環境中運行和交互 - 從 google 內部的服務器到你本身的筆記本 ,而且能夠用任何 gRPC 支持的語言(#quickstart)來編寫。因此,你能夠很容易地用 Java 建立一 個 gRPC 服務端,用 Go、Python、Ruby 來建立客戶端。此外,Google 最新 API 將有 gRPC 版 本的接口,使你很容易地將 Google 的功能集成到你的應用裏。golang
gRPC 默認使用 protocol buffers,這是 Google 開源的一套成熟的結構數據序列化機制(固然也 能夠使用其餘數據格式如 JSON)。express
正如你將在下方例子裏所看到的,你用 proto files 建立 gRPC 服務,用 protocol buffers 消息類型來定義方法參數和返回類型。apache
你能夠在 Protocol Buffers 文檔 (npm
https://developers.google.com/protocol-buffers/docs/overview
)找到更多關於 Protocol Buffers 的資料。windows
儘管 protocol buffers 對於開源用戶來講已經存在了一段時間,例子內使用的卻一種名叫 proto3 的新風格的 protocol buffers,它擁有輕量簡化的語法、一些有用的新功能,而且支持更多新語言 。
當前針對 Java 和 C++ 發佈了 beta 版本,針對 JavaNano(即 Android Java)發佈 alpha 版 本,
在protocol buffers Github 源碼庫裏(https://github.com/google/protobuf/releases)有 Ruby 支持,
在golang/protobuf Github 源碼庫(https://github.com/golang/protobuf)裏還 有針對 Go 語言的生成器, 對更多語言的支持正在開發中。
你能夠在 proto3 語言指南 (https://developers.google.com/protocol-buffers/docs/proto3)裏找到更多內容,
在與當前 默認版本的發佈說明(https://github.com/google/protobuf/releases)比較,看到二者的主要不 同點。更多關於 proto3 的文檔很快就會出現。
雖然你能夠使用 proto2 (當前默認的 protocol buffers 版本), 咱們一般建議你在 gRPC 裏使用 proto3,由於這樣你能夠使用 gRPC 支持所有範 圍的的語言,
而且能避免 proto2 客戶端與 proto3 服務端交互時出現的兼容性問題,反之亦然。
Java 例子代碼在 GitHub 源碼庫裏。你能夠運行以下命令克隆源碼到本地:
git clone -b v1.24.0 https://github.com/grpc/grpc-java
切換當前目錄到grpc-java/examples
cd grpc-java/examples
From the examples
directory:
./gradlew installDist
./build/install/examples/bin/hello-world-server
./build/install/examples/bin/hello-world-client
Congratulations! You’ve just run a client-server application with gRPC.
Go獲取例子:
go get -u github.com/grpc/grpc-go/examples/helloworld/greeter_client
go get -u github.com/grpc/grpc-go/examples/helloworld/greeter_server
切換當前目錄到 examples/helloworld
// Copyright 2015 The gRPC Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; option java_multiple_files = true; option java_package = "io.grpc.examples.helloworld"; option java_outer_classname = "HelloWorldProto"; 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; }
僅當您要更改gRPC-Java或測試/使用gRPC-Java庫的未發行版本(例如主HEAD)時,才須要構建。
構建須要JDK 8,由於咱們的測試使用TLS。
grpc-java有一個用於protoc的C ++代碼生成插件。因爲許多Java開發人員沒有安裝C編譯器,也不須要運行或修改代碼生成,所以該構建能夠跳過它。要跳過,請建立文件 <project-root>/gradle.properties
並添加skipCodegen=true
。
而後,要構建,運行:
$ ./gradlew build
要將工件安裝到您的Maven本地存儲庫中以在您本身的項目中使用,請運行:
$ ./gradlew publishToMavenLocal
當您將項目做爲Gradle項目導入並將IDE生成/運行操做委託給Gradle時,以IntelliJ進行構建的效果最佳。
您能夠在如下位置找到此設置:
-> Build Tools -> Gradle -> Runner
-> Delegate IDE build/run actions to gradle.
僅當您要更改代碼生成時,才須要此部分。大多數用戶只須要skipCodegen=true
如上所述使用便可。
codegen插件是C ++代碼,須要protobuf 3.0.0或更高版本。
對於Linux,Mac和MinGW:
git clone https://github.com/google/protobuf.git cd protobuf git checkout v3.9.0 ./autogen.sh ./configure --disable-shared make make check sudo make install
若是您熟悉C ++編譯和自動工具,你能夠指定 --prefix
爲的Protobuf和使用-I
中CXXFLAGS
,-L
在 LDFLAGS
引用它。在構建grpc-java時將使用環境變量。
Protobuf /usr/local
默認安裝到。
對於Visual C ++,請參閱Protobuf自述文件, 以瞭解如何編譯Protobuf。gRPC-java假定爲Release版本。
若是/usr/local/lib
不在您的庫搜索路徑中,則能夠經過運行如下命令添加它:
sudo sh -c 'echo /usr/local/lib >> /etc/ld.so.conf' sudo ldconfig
Mac OS X的某些版本(例如10.10)沒有/usr/local
默認文件頭文件和庫的搜索路徑。它將使代碼生成的構建失敗。要解決此問題,您將須要設置環境變量:
export CXXFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib"
在Windows和VC ++上構建時,須要爲Gradle指定項目屬性以找到protobuf:
.\gradlew publishToMavenLocal ^ -PvcProtobufInclude=C:\path\to\protobuf-3.9.0\src ^ -PvcProtobufLibs=C:\path\to\protobuf-3.9.0\vsprojects\Release ^ -PtargetArch=x86_32
因爲指定每一個構建的那些屬性很麻煩,所以您能夠<project-root>\gradle.properties
使用以下內容建立:
vcProtobufInclude=C:\\path\\to\\protobuf-3.9.0\\src vcProtobufLibs=C:\\path\\to\\protobuf-3.9.0\\vsprojects\\Release targetArch=x86_32
默認狀況下,構建腳本將爲與系統上安裝的Java運行時相同的體系結構構建代碼生成。若是您使用的是64位JVM,則會將代碼生成爲64位編譯。因爲Protobuf默認狀況下僅針對32位構建,所以這targetArch=x86_32
是必需的。
若是您在Windows上同時安裝了MinGW和VC ++,則默認狀況下將使用VC ++。要覆蓋此默認設置並使用MinGW,請添加-PvcDisable=true
到您的Gradle命令行或添加vcDisable=true
到中 <project-root>\gradle.properties
。
protoc
默認狀況下,構建腳本從Maven Central 提取預編譯的。咱們已經protoc
爲流行的系統構建了二進制文件,可是它們可能不適用於您的系統。若是protoc
沒法下載或沒法運行,則能夠經過將如下屬性添加到來使用本身構建的版本 <project-root>/gradle.properties
:
protoc=/path/to/protoc
或者在build.gradle中配置好插件
group 'com.mikey' version '1.0-SNAPSHOT' //加入grpc插件 apply plugin: 'java' apply plugin: 'com.google.protobuf' //源編譯和目標編譯 sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { // maven庫 def cn = "http://maven.aliyun.com/nexus/content/groups/public/" def abroad = "http://central.maven.org/maven2/" // 先從url中下載jar若沒有找到,則在artifactUrls中尋找 maven { url cn artifactUrls abroad } } dependencies { compile group: 'io.netty', name: 'netty-all', version: '4.1.10.Final' //protobuf用到的庫 compile group: 'com.google.protobuf', name: 'protobuf-java', version: '3.3.1' compile group: 'com.google.protobuf', name: 'protobuf-java-util', version: '3.3.1' //thrift的庫 compile group: 'org.apache.thrift', name: 'libthrift', version: '0.12.0' //grpc用到的庫 compile 'io.grpc:grpc-netty-shaded:1.20.0' compile 'io.grpc:grpc-protobuf:1.20.0' compile 'io.grpc:grpc-stub:1.20.0' } /** *如下都是grpc所使用到的gradle插件 */ buildscript { repositories { mavenCentral() } dependencies { classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.8' } } protobuf { //生成的java代碼路徑 generatedFilesBaseDir = "$projectDir/src" // protoc { artifact = "com.google.protobuf:protoc:3.7.1" } plugins { grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.20.0' } } generateProtoTasks { all()*.plugins { grpc { // 生成的 service 文件路徑 setOutputSubDir 'java' } } } }
參考:https://www.grpc.io/docs/tutorials/basic/java/
proto文件:StudentProto.proto
syntax="proto3"; package com.mikey.grpc; option java_package = "com.mikey.grpcstream"; option java_outer_classname = "StudentProto"; option java_multiple_files = true; service StudentService { //message 2 message rpc GetRealNameByUserName(Request) returns (Response){} } message Request { string username = 1; } message Response { string realname = 2; }
生成代碼:
// Generated by the protocol buffer compiler. DO NOT EDIT! // source: Student.proto package com.mikey.grpc; /** * Protobuf type {@code com.mikey.grpc.Request} */ public final class Request extends com.google.protobuf.GeneratedMessageV3 implements // @@protoc_insertion_point(message_implements:com.mikey.grpc.Request) RequestOrBuilder { private static final long serialVersionUID = 0L; // Use Request.newBuilder() to construct. private Request(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) { super(builder); } private Request() { username_ = ""; } @Override public final com.google.protobuf.UnknownFieldSet getUnknownFields() { return this.unknownFields; } private Request( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { this(); if (extensionRegistry == null) { throw new NullPointerException(); } int mutable_bitField0_ = 0; com.google.protobuf.UnknownFieldSet.Builder unknownFields = com.google.protobuf.UnknownFieldSet.newBuilder(); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; case 10: { String s = input.readStringRequireUtf8(); username_ = s; break; } default: { if (!parseUnknownField( input, unknownFields, extensionRegistry, tag)) { done = true; } break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); } } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { return com.mikey.grpc.StudentProto.internal_static_com_mikey_grpc_Request_descriptor; } @Override protected FieldAccessorTable internalGetFieldAccessorTable() { return com.mikey.grpc.StudentProto.internal_static_com_mikey_grpc_Request_fieldAccessorTable .ensureFieldAccessorsInitialized( Request.class, Builder.class); } public static final int USERNAME_FIELD_NUMBER = 1; private volatile Object username_; /** * <code>string username = 1;</code> */ public String getUsername() { Object ref = username_; if (ref instanceof String) { return (String) ref; } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; String s = bs.toStringUtf8(); username_ = s; return s; } } /** * <code>string username = 1;</code> */ public com.google.protobuf.ByteString getUsernameBytes() { Object ref = username_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( (String) ref); username_ = b; return b; } else { return (com.google.protobuf.ByteString) ref; } } private byte memoizedIsInitialized = -1; @Override public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; memoizedIsInitialized = 1; return true; } @Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (!getUsernameBytes().isEmpty()) { com.google.protobuf.GeneratedMessageV3.writeString(output, 1, username_); } unknownFields.writeTo(output); } @Override public int getSerializedSize() { int size = memoizedSize; if (size != -1) return size; size = 0; if (!getUsernameBytes().isEmpty()) { size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, username_); } size += unknownFields.getSerializedSize(); memoizedSize = size; return size; } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof Request)) { return super.equals(obj); } Request other = (Request) obj; if (!getUsername() .equals(other.getUsername())) return false; if (!unknownFields.equals(other.unknownFields)) return false; return true; } @Override public int hashCode() { if (memoizedHashCode != 0) { return memoizedHashCode; } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); hash = (37 * hash) + USERNAME_FIELD_NUMBER; hash = (53 * hash) + getUsername().hashCode(); hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } public static Request parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static Request parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static Request parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static Request parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static Request parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static Request parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static Request parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } public static Request parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } public static Request parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } public static Request parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } public static Request parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } public static Request parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } @Override public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } public static Builder newBuilder(Request prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @Override public Builder toBuilder() { return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); } @Override protected Builder newBuilderForType( BuilderParent parent) { Builder builder = new Builder(parent); return builder; } /** * Protobuf type {@code com.mikey.grpc.Request} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements // @@protoc_insertion_point(builder_implements:com.mikey.grpc.Request) com.mikey.grpc.RequestOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { return com.mikey.grpc.StudentProto.internal_static_com_mikey_grpc_Request_descriptor; } @Override protected FieldAccessorTable internalGetFieldAccessorTable() { return com.mikey.grpc.StudentProto.internal_static_com_mikey_grpc_Request_fieldAccessorTable .ensureFieldAccessorsInitialized( Request.class, Builder.class); } // Construct using com.mikey.grpc.Request.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private Builder( BuilderParent parent) { super(parent); maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessageV3 .alwaysUseFieldBuilders) { } } @Override public Builder clear() { super.clear(); username_ = ""; return this; } @Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { return com.mikey.grpc.StudentProto.internal_static_com_mikey_grpc_Request_descriptor; } @Override public Request getDefaultInstanceForType() { return Request.getDefaultInstance(); } @Override public Request build() { Request result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } @Override public Request buildPartial() { Request result = new Request(this); result.username_ = username_; onBuilt(); return result; } @Override public Builder clone() { return super.clone(); } @Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, Object value) { return super.setField(field, value); } @Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { return super.clearField(field); } @Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { return super.clearOneof(oneof); } @Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, int index, Object value) { return super.setRepeatedField(field, index, value); } @Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, Object value) { return super.addRepeatedField(field, value); } @Override public Builder mergeFrom(com.google.protobuf.Message other) { if (other instanceof Request) { return mergeFrom((Request)other); } else { super.mergeFrom(other); return this; } } public Builder mergeFrom(Request other) { if (other == Request.getDefaultInstance()) return this; if (!other.getUsername().isEmpty()) { username_ = other.username_; onChanged(); } this.mergeUnknownFields(other.unknownFields); onChanged(); return this; } @Override public final boolean isInitialized() { return true; } @Override public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { Request parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (Request) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private Object username_ = ""; /** * <code>string username = 1;</code> */ public String getUsername() { Object ref = username_; if (!(ref instanceof String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; String s = bs.toStringUtf8(); username_ = s; return s; } else { return (String) ref; } } /** * <code>string username = 1;</code> */ public com.google.protobuf.ByteString getUsernameBytes() { Object ref = username_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( (String) ref); username_ = b; return b; } else { return (com.google.protobuf.ByteString) ref; } } /** * <code>string username = 1;</code> */ public Builder setUsername( String value) { if (value == null) { throw new NullPointerException(); } username_ = value; onChanged(); return this; } /** * <code>string username = 1;</code> */ public Builder clearUsername() { username_ = getDefaultInstance().getUsername(); onChanged(); return this; } /** * <code>string username = 1;</code> */ public Builder setUsernameBytes( com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } checkByteStringIsUtf8(value); username_ = value; onChanged(); return this; } @Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); } @Override public final Builder mergeUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.mergeUnknownFields(unknownFields); } // @@protoc_insertion_point(builder_scope:com.mikey.grpc.Request) } // @@protoc_insertion_point(class_scope:com.mikey.grpc.Request) private static final Request DEFAULT_INSTANCE; static { DEFAULT_INSTANCE = new Request(); } public static Request getDefaultInstance() { return DEFAULT_INSTANCE; } private static final com.google.protobuf.Parser<Request> PARSER = new com.google.protobuf.AbstractParser<Request>() { @Override public Request parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new Request(input, extensionRegistry); } }; public static com.google.protobuf.Parser<Request> parser() { return PARSER; } @Override public com.google.protobuf.Parser<Request> getParserForType() { return PARSER; } @Override public Request getDefaultInstanceForType() { return DEFAULT_INSTANCE; } }
// Generated by the protocol buffer compiler. DO NOT EDIT! // source: Student.proto package com.mikey.grpc; public interface RequestOrBuilder extends // @@protoc_insertion_point(interface_extends:com.mikey.grpc.Request) com.google.protobuf.MessageOrBuilder { /** * <code>string username = 1;</code> */ String getUsername(); /** * <code>string username = 1;</code> */ com.google.protobuf.ByteString getUsernameBytes(); }
// Generated by the protocol buffer compiler. DO NOT EDIT! // source: Student.proto package com.mikey.grpc; /** * Protobuf type {@code com.mikey.grpc.Response} */ public final class Response extends com.google.protobuf.GeneratedMessageV3 implements // @@protoc_insertion_point(message_implements:com.mikey.grpc.Response) ResponseOrBuilder { private static final long serialVersionUID = 0L; // Use Response.newBuilder() to construct. private Response(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) { super(builder); } private Response() { realname_ = ""; } @Override public final com.google.protobuf.UnknownFieldSet getUnknownFields() { return this.unknownFields; } private Response( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { this(); if (extensionRegistry == null) { throw new NullPointerException(); } int mutable_bitField0_ = 0; com.google.protobuf.UnknownFieldSet.Builder unknownFields = com.google.protobuf.UnknownFieldSet.newBuilder(); try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; case 18: { String s = input.readStringRequireUtf8(); realname_ = s; break; } default: { if (!parseUnknownField( input, unknownFields, extensionRegistry, tag)) { done = true; } break; } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(this); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); } } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { return com.mikey.grpc.StudentProto.internal_static_com_mikey_grpc_Response_descriptor; } @Override protected FieldAccessorTable internalGetFieldAccessorTable() { return com.mikey.grpc.StudentProto.internal_static_com_mikey_grpc_Response_fieldAccessorTable .ensureFieldAccessorsInitialized( Response.class, Builder.class); } public static final int REALNAME_FIELD_NUMBER = 2; private volatile Object realname_; /** * <code>string realname = 2;</code> */ public String getRealname() { Object ref = realname_; if (ref instanceof String) { return (String) ref; } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; String s = bs.toStringUtf8(); realname_ = s; return s; } } /** * <code>string realname = 2;</code> */ public com.google.protobuf.ByteString getRealnameBytes() { Object ref = realname_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( (String) ref); realname_ = b; return b; } else { return (com.google.protobuf.ByteString) ref; } } private byte memoizedIsInitialized = -1; @Override public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; memoizedIsInitialized = 1; return true; } @Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (!getRealnameBytes().isEmpty()) { com.google.protobuf.GeneratedMessageV3.writeString(output, 2, realname_); } unknownFields.writeTo(output); } @Override public int getSerializedSize() { int size = memoizedSize; if (size != -1) return size; size = 0; if (!getRealnameBytes().isEmpty()) { size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, realname_); } size += unknownFields.getSerializedSize(); memoizedSize = size; return size; } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof Response)) { return super.equals(obj); } Response other = (Response) obj; if (!getRealname() .equals(other.getRealname())) return false; if (!unknownFields.equals(other.unknownFields)) return false; return true; } @Override public int hashCode() { if (memoizedHashCode != 0) { return memoizedHashCode; } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); hash = (37 * hash) + REALNAME_FIELD_NUMBER; hash = (53 * hash) + getRealname().hashCode(); hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } public static Response parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static Response parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static Response parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static Response parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static Response parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static Response parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static Response parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } public static Response parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } public static Response parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } public static Response parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } public static Response parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } public static Response parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } @Override public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } public static Builder newBuilder(Response prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @Override public Builder toBuilder() { return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); } @Override protected Builder newBuilderForType( BuilderParent parent) { Builder builder = new Builder(parent); return builder; } /** * Protobuf type {@code com.mikey.grpc.Response} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements // @@protoc_insertion_point(builder_implements:com.mikey.grpc.Response) com.mikey.grpc.ResponseOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { return com.mikey.grpc.StudentProto.internal_static_com_mikey_grpc_Response_descriptor; } @Override protected FieldAccessorTable internalGetFieldAccessorTable() { return com.mikey.grpc.StudentProto.internal_static_com_mikey_grpc_Response_fieldAccessorTable .ensureFieldAccessorsInitialized( Response.class, Builder.class); } // Construct using com.mikey.grpc.Response.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private Builder( BuilderParent parent) { super(parent); maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessageV3 .alwaysUseFieldBuilders) { } } @Override public Builder clear() { super.clear(); realname_ = ""; return this; } @Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { return com.mikey.grpc.StudentProto.internal_static_com_mikey_grpc_Response_descriptor; } @Override public Response getDefaultInstanceForType() { return Response.getDefaultInstance(); } @Override public Response build() { Response result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } @Override public Response buildPartial() { Response result = new Response(this); result.realname_ = realname_; onBuilt(); return result; } @Override public Builder clone() { return super.clone(); } @Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, Object value) { return super.setField(field, value); } @Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { return super.clearField(field); } @Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { return super.clearOneof(oneof); } @Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, int index, Object value) { return super.setRepeatedField(field, index, value); } @Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, Object value) { return super.addRepeatedField(field, value); } @Override public Builder mergeFrom(com.google.protobuf.Message other) { if (other instanceof Response) { return mergeFrom((Response)other); } else { super.mergeFrom(other); return this; } } public Builder mergeFrom(Response other) { if (other == Response.getDefaultInstance()) return this; if (!other.getRealname().isEmpty()) { realname_ = other.realname_; onChanged(); } this.mergeUnknownFields(other.unknownFields); onChanged(); return this; } @Override public final boolean isInitialized() { return true; } @Override public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { Response parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { parsedMessage = (Response) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { mergeFrom(parsedMessage); } } return this; } private Object realname_ = ""; /** * <code>string realname = 2;</code> */ public String getRealname() { Object ref = realname_; if (!(ref instanceof String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; String s = bs.toStringUtf8(); realname_ = s; return s; } else { return (String) ref; } } /** * <code>string realname = 2;</code> */ public com.google.protobuf.ByteString getRealnameBytes() { Object ref = realname_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( (String) ref); realname_ = b; return b; } else { return (com.google.protobuf.ByteString) ref; } } /** * <code>string realname = 2;</code> */ public Builder setRealname( String value) { if (value == null) { throw new NullPointerException(); } realname_ = value; onChanged(); return this; } /** * <code>string realname = 2;</code> */ public Builder clearRealname() { realname_ = getDefaultInstance().getRealname(); onChanged(); return this; } /** * <code>string realname = 2;</code> */ public Builder setRealnameBytes( com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } checkByteStringIsUtf8(value); realname_ = value; onChanged(); return this; } @Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); } @Override public final Builder mergeUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.mergeUnknownFields(unknownFields); } // @@protoc_insertion_point(builder_scope:com.mikey.grpc.Response) } // @@protoc_insertion_point(class_scope:com.mikey.grpc.Response) private static final Response DEFAULT_INSTANCE; static { DEFAULT_INSTANCE = new Response(); } public static Response getDefaultInstance() { return DEFAULT_INSTANCE; } private static final com.google.protobuf.Parser<Response> PARSER = new com.google.protobuf.AbstractParser<Response>() { @Override public Response parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return new Response(input, extensionRegistry); } }; public static com.google.protobuf.Parser<Response> parser() { return PARSER; } @Override public com.google.protobuf.Parser<Response> getParserForType() { return PARSER; } @Override public Response getDefaultInstanceForType() { return DEFAULT_INSTANCE; } }
// Generated by the protocol buffer compiler. DO NOT EDIT! // source: Student.proto package com.mikey.grpc; public interface ResponseOrBuilder extends // @@protoc_insertion_point(interface_extends:com.mikey.grpc.Response) com.google.protobuf.MessageOrBuilder { /** * <code>string realname = 2;</code> */ String getRealname(); /** * <code>string realname = 2;</code> */ com.google.protobuf.ByteString getRealnameBytes(); }
// Generated by the protocol buffer compiler. DO NOT EDIT! // source: Student.proto package com.mikey.grpc; public final class StudentProto { private StudentProto() {} public static void registerAllExtensions( com.google.protobuf.ExtensionRegistryLite registry) { } public static void registerAllExtensions( com.google.protobuf.ExtensionRegistry registry) { registerAllExtensions( (com.google.protobuf.ExtensionRegistryLite) registry); } static final com.google.protobuf.Descriptors.Descriptor internal_static_com_mikey_grpc_Request_descriptor; static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_com_mikey_grpc_Request_fieldAccessorTable; static final com.google.protobuf.Descriptors.Descriptor internal_static_com_mikey_grpc_Response_descriptor; static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_com_mikey_grpc_Response_fieldAccessorTable; public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { return descriptor; } private static com.google.protobuf.Descriptors.FileDescriptor descriptor; static { String[] descriptorData = { "\n\rStudent.proto\022\016com.mikey.grpc\"\033\n\007Reque" + "st\022\020\n\010username\030\001 \001(\t\"\034\n\010Response\022\020\n\010real" + "name\030\002 \001(\t2^\n\016StudentService\022L\n\025GetRealN" + "ameByUserName\022\027.com.mikey.grpc.Request\032\030" + ".com.mikey.grpc.Response\"\000B \n\016com.mikey." + "grpcB\014StudentProtoP\001b\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_com_mikey_grpc_Request_descriptor = getDescriptor().getMessageTypes().get(0); internal_static_com_mikey_grpc_Request_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_com_mikey_grpc_Request_descriptor, new String[] { "Username", }); internal_static_com_mikey_grpc_Response_descriptor = getDescriptor().getMessageTypes().get(1); internal_static_com_mikey_grpc_Response_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_com_mikey_grpc_Response_descriptor, new String[] { "Realname", }); } // @@protoc_insertion_point(outer_class_scope) }
服務類:
package com.mikey.grpc; import static io.grpc.MethodDescriptor.generateFullMethodName; import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; import static io.grpc.stub.ClientCalls.asyncUnaryCall; import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; import static io.grpc.stub.ClientCalls.blockingUnaryCall; import static io.grpc.stub.ClientCalls.futureUnaryCall; import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; import static io.grpc.stub.ServerCalls.asyncUnaryCall; import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; /** */ //@javax.annotation.Generated( // value = "by gRPC proto compiler (version 1.20.0)", // comments = "Source: Student.proto") public final class StudentServiceGrpc { private StudentServiceGrpc() {} public static final String SERVICE_NAME = "com.mikey.grpc.StudentService"; // Static method descriptors that strictly reflect the proto. private static volatile io.grpc.MethodDescriptor<com.mikey.grpc.Request, com.mikey.grpc.Response> getGetRealNameByUserNameMethod; @io.grpc.stub.annotations.RpcMethod( fullMethodName = SERVICE_NAME + '/' + "GetRealNameByUserName", requestType = com.mikey.grpc.Request.class, responseType = com.mikey.grpc.Response.class, methodType = io.grpc.MethodDescriptor.MethodType.UNARY) public static io.grpc.MethodDescriptor<com.mikey.grpc.Request, com.mikey.grpc.Response> getGetRealNameByUserNameMethod() { io.grpc.MethodDescriptor<com.mikey.grpc.Request, com.mikey.grpc.Response> getGetRealNameByUserNameMethod; if ((getGetRealNameByUserNameMethod = StudentServiceGrpc.getGetRealNameByUserNameMethod) == null) { synchronized (StudentServiceGrpc.class) { if ((getGetRealNameByUserNameMethod = StudentServiceGrpc.getGetRealNameByUserNameMethod) == null) { StudentServiceGrpc.getGetRealNameByUserNameMethod = getGetRealNameByUserNameMethod = io.grpc.MethodDescriptor.<com.mikey.grpc.Request, com.mikey.grpc.Response>newBuilder() .setType(io.grpc.MethodDescriptor.MethodType.UNARY) .setFullMethodName(generateFullMethodName( "com.mikey.grpc.StudentService", "GetRealNameByUserName")) .setSampledToLocalTracing(true) .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( com.mikey.grpc.Request.getDefaultInstance())) .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( com.mikey.grpc.Response.getDefaultInstance())) .setSchemaDescriptor(new StudentServiceMethodDescriptorSupplier("GetRealNameByUserName")) .build(); } } } return getGetRealNameByUserNameMethod; } /** * Creates a new async stub that supports all call types for the service */ public static StudentServiceStub newStub(io.grpc.Channel channel) { return new StudentServiceStub(channel); } /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ public static StudentServiceBlockingStub newBlockingStub( io.grpc.Channel channel) { return new StudentServiceBlockingStub(channel); } /** * Creates a new ListenableFuture-style stub that supports unary calls on the service */ public static StudentServiceFutureStub newFutureStub( io.grpc.Channel channel) { return new StudentServiceFutureStub(channel); } /** */ public static abstract class StudentServiceImplBase implements io.grpc.BindableService { /** */ public void getRealNameByUserName(com.mikey.grpc.Request request, io.grpc.stub.StreamObserver<com.mikey.grpc.Response> responseObserver) { asyncUnimplementedUnaryCall(getGetRealNameByUserNameMethod(), responseObserver); } @Override public final io.grpc.ServerServiceDefinition bindService() { return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) .addMethod( getGetRealNameByUserNameMethod(), asyncUnaryCall( new MethodHandlers< com.mikey.grpc.Request, com.mikey.grpc.Response>( this, METHODID_GET_REAL_NAME_BY_USER_NAME))) .build(); } } /** */ public static final class StudentServiceStub extends io.grpc.stub.AbstractStub<StudentServiceStub> { private StudentServiceStub(io.grpc.Channel channel) { super(channel); } private StudentServiceStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @Override protected StudentServiceStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new StudentServiceStub(channel, callOptions); } /** */ public void getRealNameByUserName(com.mikey.grpc.Request request, io.grpc.stub.StreamObserver<com.mikey.grpc.Response> responseObserver) { asyncUnaryCall( getChannel().newCall(getGetRealNameByUserNameMethod(), getCallOptions()), request, responseObserver); } } /** */ public static final class StudentServiceBlockingStub extends io.grpc.stub.AbstractStub<StudentServiceBlockingStub> { private StudentServiceBlockingStub(io.grpc.Channel channel) { super(channel); } private StudentServiceBlockingStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @Override protected StudentServiceBlockingStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new StudentServiceBlockingStub(channel, callOptions); } /** */ public com.mikey.grpc.Response getRealNameByUserName(com.mikey.grpc.Request request) { return blockingUnaryCall( getChannel(), getGetRealNameByUserNameMethod(), getCallOptions(), request); } } /** */ public static final class StudentServiceFutureStub extends io.grpc.stub.AbstractStub<StudentServiceFutureStub> { private StudentServiceFutureStub(io.grpc.Channel channel) { super(channel); } private StudentServiceFutureStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @Override protected StudentServiceFutureStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new StudentServiceFutureStub(channel, callOptions); } /** */ public com.google.common.util.concurrent.ListenableFuture<com.mikey.grpc.Response> getRealNameByUserName( com.mikey.grpc.Request request) { return futureUnaryCall( getChannel().newCall(getGetRealNameByUserNameMethod(), getCallOptions()), request); } } private static final int METHODID_GET_REAL_NAME_BY_USER_NAME = 0; private static final class MethodHandlers<Req, Resp> implements io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>, io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>, io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>, io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> { private final StudentServiceImplBase serviceImpl; private final int methodId; MethodHandlers(StudentServiceImplBase serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @Override @SuppressWarnings("unchecked") public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) { switch (methodId) { case METHODID_GET_REAL_NAME_BY_USER_NAME: serviceImpl.getRealNameByUserName((com.mikey.grpc.Request) request, (io.grpc.stub.StreamObserver<com.mikey.grpc.Response>) responseObserver); break; default: throw new AssertionError(); } } @Override @SuppressWarnings("unchecked") public io.grpc.stub.StreamObserver<Req> invoke( io.grpc.stub.StreamObserver<Resp> responseObserver) { switch (methodId) { default: throw new AssertionError(); } } } private static abstract class StudentServiceBaseDescriptorSupplier implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier { StudentServiceBaseDescriptorSupplier() {} @Override public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() { return com.mikey.grpc.StudentProto.getDescriptor(); } @Override public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() { return getFileDescriptor().findServiceByName("StudentService"); } } private static final class StudentServiceFileDescriptorSupplier extends StudentServiceBaseDescriptorSupplier { StudentServiceFileDescriptorSupplier() {} } private static final class StudentServiceMethodDescriptorSupplier extends StudentServiceBaseDescriptorSupplier implements io.grpc.protobuf.ProtoMethodDescriptorSupplier { private final String methodName; StudentServiceMethodDescriptorSupplier(String methodName) { this.methodName = methodName; } @Override public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() { return getServiceDescriptor().findMethodByName(methodName); } } private static volatile io.grpc.ServiceDescriptor serviceDescriptor; public static io.grpc.ServiceDescriptor getServiceDescriptor() { io.grpc.ServiceDescriptor result = serviceDescriptor; if (result == null) { synchronized (StudentServiceGrpc.class) { result = serviceDescriptor; if (result == null) { serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) .setSchemaDescriptor(new StudentServiceFileDescriptorSupplier()) .addMethod(getGetRealNameByUserNameMethod()) .build(); } } } return result; } }
實現類:
package com.mikey.grpc; import io.grpc.stub.StreamObserver; /** * @ProjectName netty * @Author 麥奇 * @Email biaogejiushibiao@outlook.com * @Date 10/2/19 10:55 AM * @Version 1.0 * @Description: **/ public class StudentServiceImpl extends StudentServiceGrpc.StudentServiceImplBase{ @Override public void getRealNameByUserName(Request request, StreamObserver<Response> responseObserver) { System.out.println("接收到客戶端信息:"+request.getUsername()); responseObserver.onNext(Response.newBuilder().setRealname(request.getUsername()).build()); responseObserver.onCompleted(); } }
客戶端:
package com.mikey.grpc; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.stub.ClientCalls; import java.util.logging.Logger; /** * @ProjectName netty * @Author 麥奇 * @Email biaogejiushibiao@outlook.com * @Date 10/2/19 11:02 AM * @Version 1.0 * @Description: **/ public class GrpcClient { private static final Logger logger = Logger.getLogger(GrpcClient.class.getName()); public static final String HOST_ADDRESS = "localhost"; public static final Integer PORT = 8899; public static void main(String[] args) throws Exception{ //構建配置 ManagedChannelBuilder<?> builder = ManagedChannelBuilder.forAddress(HOST_ADDRESS, PORT).usePlaintext(true); //傳輸管道 ManagedChannel channel = builder.build(); //構建請求 Request request = Request.newBuilder().setUsername("麥奇").build(); //構建非阻塞服務調用 StudentServiceGrpc.StudentServiceBlockingStub blockingStub = StudentServiceGrpc.newBlockingStub(channel); //服務調用並接收返回參數 Response response = blockingStub.getRealNameByUserName(request); //打印信息 logger.info(response.getRealname()); //關閉資源 channel.shutdown(); } }
服務器:
package com.mikey.grpc; import io.grpc.Server; import io.grpc.ServerBuilder; import java.util.logging.Logger; /** * @ProjectName netty * @Author 麥奇 * @Email biaogejiushibiao@outlook.com * @Date 10/2/19 11:02 AM * @Version 1.0 * @Description: **/ public class GrpcServer { private static final Logger logger = Logger.getLogger(GrpcServer.class.getName()); public static void main(String[] args) throws Exception{ Server start = ServerBuilder.forPort(8899) .addService(new com.mikey.grpc.StudentServiceImpl()) .build() .start(); //阻塞 start.awaitTermination(); logger.info("Server started, listening on " + start.getPort()); 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"); start.shutdown(); System.err.println("*** server shut down"); } }); } }
gRPC lets you define four kinds of service method:
rpc SayHello(HelloRequest) returns (HelloResponse){}
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){}
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {}
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){}
We’ll look at the different types of RPC in more detail in the RPC life cycle section below.
package com.mikey.grpcstream; import io.grpc.stub.ServerCallStreamObserver; import io.grpc.stub.StreamObserver; import java.util.logging.Logger; /** * @ProjectName netty * @Author 麥奇 * @Email biaogejiushibiao@outlook.com * @Date 10/2/19 12:28 PM * @Version 1.0 * @Description: **/ public class StudentGrpcImpl extends com.mikey.grpcstream.StudentServiceGrpc.StudentServiceImplBase { private static final Logger logger = Logger.getLogger(StudentGrpcImpl.class.getName()); @Override public void getRealNameByUserName(Request request, StreamObserver<Response> responseObserver) { logger.info("參數:"+request.getUsername()); responseObserver.onNext(Response.newBuilder().setRealname("阿姆斯特朗").build()); responseObserver.onCompleted(); } @Override public void getStudentByAge(Request request, StreamObserver<StudentResponse> responseObserver) { logger.info("參數:"+request.getUsername()); responseObserver.onNext(StudentResponse.newBuilder().setName("里奧").setAge(20).setCity("北京").build()); responseObserver.onNext(StudentResponse.newBuilder().setName("麥奇").setAge(20).setCity("柳州").build()); responseObserver.onNext(StudentResponse.newBuilder().setName("達芬奇").setAge(20).setCity("深圳").build()); responseObserver.onCompleted(); } @Override public StreamObserver<StudentResponseList> getStudentByStream(StreamObserver<StudentResponse> responseObserver) { StudentResponse build1 = StudentResponse.newBuilder().setName("1111111111").setAge(111111111).setCity("11111111111").build(); StudentResponse build2 = StudentResponse.newBuilder().setName("1111111111").setAge(111111111).setCity("11111111111").build(); StudentResponse build3 = StudentResponse.newBuilder().setName("1111111111").setAge(111111111).setCity("11111111111").build(); return new StreamObserver<StudentResponseList>() { @Override public void onNext(StudentResponseList value) { } @Override public void onError(Throwable t) { } @Override public void onCompleted() { responseObserver.onNext(build1); responseObserver.onNext(build2); responseObserver.onNext(build3); responseObserver.onCompleted(); } }; } @Override public StreamObserver<StreamRequest> biTalk(StreamObserver<StreamResponse> responseObserver) { return new StreamObserver<StreamRequest>() { @Override public void onNext(StreamRequest value) { } @Override public void onError(Throwable t) { } @Override public void onCompleted() { } }; } }
node.js
syntax="proto3"; package com.mikey.grpc; option java_package = "com.mikey.grpcstream"; option java_outer_classname = "StudentProto"; option java_multiple_files = true; service StudentService { //message 2 message rpc GetRealNameByUserName(Request) returns (Response){} //message 2 stream message rpc GetStudentByAge(Request) returns (stream StudentResponse){} //stream message 2 message rpc GetStudentByStream(stream StudentResponseList) returns (StudentResponse){} //stream message 2 stream message rpc BiTalk(stream StreamRequest) returns (stream StreamResponse){} } message Request { string username = 1; } message Response { string realname = 2; } message StudentResponse { string name = 1; int32 age =2; string city = 3; } message StudentRequest { string key = 1; } message StudentResponseList { repeated StudentResponse studentResponse = 1; } message StreamRequest { string request_info = 1; } message StreamResponse { string response_info = 1; }
動態生成服務代碼
var PROTO_FILE_PATH = '/home/mikey/WebstormProjects/node-grpc/proto/Student.proto'; var grpc = require('grpc'); var grpcService = grpc.load(PROTO_FILE_PATH).com.mikey.grpc var client = new grpcService.StudentService('localhost:8899',grpc.credentials.createInsecure()) client.GetRealNameByUserName({username:'mikey'}, function(error,respData) { console.log(respData) });
var PROTO_FILE_PATH = '/home/mikey/WebstormProjects/node-grpc/proto/Student.proto'; var grpc = require('grpc'); var grpcService = grpc.load(PROTO_FILE_PATH).com.mikey.grpc; var server = new grpc.Server(); server.addService(grpcService.StudentService.service,{ GetRealNameByUserName: GetRealNameByUserName }) server.bind('localhost:8899',grpc.ServerCredentials.createInsecure()); server.start(); function GetRealNameByUserName(call,callback) { console.log("call : "+call.request.username) callback(null,{realname: '張三'}); } function getStudentByAge() {} function getStudentByStream() {} function biTalk() {}
靜態生成服務代碼
參考:https://github.com/grpc/grpc/tree/master/examples/node/static_codegen
// 進入proto文件目錄
cd ../../protos
// 全局安裝grpc工具 npm install -g grpc-tools // 生成靜態代碼
grpc_tools_node_protoc --js_out=import_style=commonjs,binary:../node/static_codegen/ --grpc_out=../node/static_codegen --plugin=protoc-gen-grpc=`which grpc_tools_node_protoc_plugin` helloworld.proto grpc_tools_node_protoc --js_out=import_style=commonjs,binary:../node/static_codegen/route_guide/ --grpc_out=../node/static_codegen/route_guide/ --plugin=protoc-gen-grpc=`which grpc_tools_node_protoc_plugin` route_guide.proto
上面方法我經過 npm install -g grpc-tools 並未安裝 grpc_tools_node_protoc 因此經過下面方法來生成
npm install grpc-tools --save-dev
../node_modules/grpc-tools/bin/protoc --js_out=import_style=commonjs,binary:../static_codegen/ --plugin=protoc-gen-grpc=../node_modules/grpc-tools/bin/grpc_node_plugin --grpc_out=../static_codegen/ Student.proto
生成兩個pb.js文件
// GENERATED CODE -- DO NOT EDIT! 'use strict'; var grpc = require('grpc'); var Student_pb = require('./Student_pb.js'); function serialize_com_mikey_grpc_Request(arg) { if (!(arg instanceof Student_pb.Request)) { throw new Error('Expected argument of type com.mikey.grpc.Request'); } return Buffer.from(arg.serializeBinary()); } function deserialize_com_mikey_grpc_Request(buffer_arg) { return Student_pb.Request.deserializeBinary(new Uint8Array(buffer_arg)); } function serialize_com_mikey_grpc_Response(arg) { if (!(arg instanceof Student_pb.Response)) { throw new Error('Expected argument of type com.mikey.grpc.Response'); } return Buffer.from(arg.serializeBinary()); } function deserialize_com_mikey_grpc_Response(buffer_arg) { return Student_pb.Response.deserializeBinary(new Uint8Array(buffer_arg)); } function serialize_com_mikey_grpc_StreamRequest(arg) { if (!(arg instanceof Student_pb.StreamRequest)) { throw new Error('Expected argument of type com.mikey.grpc.StreamRequest'); } return Buffer.from(arg.serializeBinary()); } function deserialize_com_mikey_grpc_StreamRequest(buffer_arg) { return Student_pb.StreamRequest.deserializeBinary(new Uint8Array(buffer_arg)); } function serialize_com_mikey_grpc_StreamResponse(arg) { if (!(arg instanceof Student_pb.StreamResponse)) { throw new Error('Expected argument of type com.mikey.grpc.StreamResponse'); } return Buffer.from(arg.serializeBinary()); } function deserialize_com_mikey_grpc_StreamResponse(buffer_arg) { return Student_pb.StreamResponse.deserializeBinary(new Uint8Array(buffer_arg)); } function serialize_com_mikey_grpc_StudentResponse(arg) { if (!(arg instanceof Student_pb.StudentResponse)) { throw new Error('Expected argument of type com.mikey.grpc.StudentResponse'); } return Buffer.from(arg.serializeBinary()); } function deserialize_com_mikey_grpc_StudentResponse(buffer_arg) { return Student_pb.StudentResponse.deserializeBinary(new Uint8Array(buffer_arg)); } function serialize_com_mikey_grpc_StudentResponseList(arg) { if (!(arg instanceof Student_pb.StudentResponseList)) { throw new Error('Expected argument of type com.mikey.grpc.StudentResponseList'); } return Buffer.from(arg.serializeBinary()); } function deserialize_com_mikey_grpc_StudentResponseList(buffer_arg) { return Student_pb.StudentResponseList.deserializeBinary(new Uint8Array(buffer_arg)); } var StudentServiceService = exports.StudentServiceService = { // message 2 message getRealNameByUserName: { path: '/com.mikey.grpc.StudentService/GetRealNameByUserName', requestStream: false, responseStream: false, requestType: Student_pb.Request, responseType: Student_pb.Response, requestSerialize: serialize_com_mikey_grpc_Request, requestDeserialize: deserialize_com_mikey_grpc_Request, responseSerialize: serialize_com_mikey_grpc_Response, responseDeserialize: deserialize_com_mikey_grpc_Response, }, // message 2 stream message getStudentByAge: { path: '/com.mikey.grpc.StudentService/GetStudentByAge', requestStream: false, responseStream: true, requestType: Student_pb.Request, responseType: Student_pb.StudentResponse, requestSerialize: serialize_com_mikey_grpc_Request, requestDeserialize: deserialize_com_mikey_grpc_Request, responseSerialize: serialize_com_mikey_grpc_StudentResponse, responseDeserialize: deserialize_com_mikey_grpc_StudentResponse, }, // stream message 2 message getStudentByStream: { path: '/com.mikey.grpc.StudentService/GetStudentByStream', requestStream: true, responseStream: false, requestType: Student_pb.StudentResponseList, responseType: Student_pb.StudentResponse, requestSerialize: serialize_com_mikey_grpc_StudentResponseList, requestDeserialize: deserialize_com_mikey_grpc_StudentResponseList, responseSerialize: serialize_com_mikey_grpc_StudentResponse, responseDeserialize: deserialize_com_mikey_grpc_StudentResponse, }, // stream message 2 stream message biTalk: { path: '/com.mikey.grpc.StudentService/BiTalk', requestStream: true, responseStream: true, requestType: Student_pb.StreamRequest, responseType: Student_pb.StreamResponse, requestSerialize: serialize_com_mikey_grpc_StreamRequest, requestDeserialize: deserialize_com_mikey_grpc_StreamRequest, responseSerialize: serialize_com_mikey_grpc_StreamResponse, responseDeserialize: deserialize_com_mikey_grpc_StreamResponse, }, }; exports.StudentServiceClient = grpc.makeGenericClientConstructor(StudentServiceService);
/** * @fileoverview * @enhanceable * @suppress {messageConventions} JS Compiler reports an error if a variable or * field starts with 'MSG_' and isn't a translatable message. * @public */ // GENERATED CODE -- DO NOT EDIT! var jspb = require('google-protobuf'); var goog = jspb; var global = Function('return this')(); goog.exportSymbol('proto.com.mikey.grpc.Request', null, global); goog.exportSymbol('proto.com.mikey.grpc.Response', null, global); goog.exportSymbol('proto.com.mikey.grpc.StreamRequest', null, global); goog.exportSymbol('proto.com.mikey.grpc.StreamResponse', null, global); goog.exportSymbol('proto.com.mikey.grpc.StudentRequest', null, global); goog.exportSymbol('proto.com.mikey.grpc.StudentResponse', null, global); goog.exportSymbol('proto.com.mikey.grpc.StudentResponseList', null, global); /** * Generated by JsPbCodeGenerator. * @param {Array=} opt_data Optional initial data array, typically from a * server response, or constructed directly in Javascript. The array is used * in place and becomes part of the constructed object. It is not cloned. * If no data is provided, the constructed object will be empty, but still * valid. * @extends {jspb.Message} * @constructor */ proto.com.mikey.grpc.Request = function(opt_data) { jspb.Message.initialize(this, opt_data, 0, -1, null, null); }; goog.inherits(proto.com.mikey.grpc.Request, jspb.Message); if (goog.DEBUG && !COMPILED) { proto.com.mikey.grpc.Request.displayName = 'proto.com.mikey.grpc.Request'; } if (jspb.Message.GENERATE_TO_OBJECT) { /** * Creates an object representation of this proto suitable for use in Soy templates. * Field names that are reserved in JavaScript and will be renamed to pb_name. * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. * For the list of reserved names please see: * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. * @param {boolean=} opt_includeInstance Whether to include the JSPB instance * for transitional soy proto support: http://goto/soy-param-migration * @return {!Object} */ proto.com.mikey.grpc.Request.prototype.toObject = function(opt_includeInstance) { return proto.com.mikey.grpc.Request.toObject(opt_includeInstance, this); }; /** * Static version of the {@see toObject} method. * @param {boolean|undefined} includeInstance Whether to include the JSPB * instance for transitional soy proto support: * http://goto/soy-param-migration * @param {!proto.com.mikey.grpc.Request} msg The msg instance to transform. * @return {!Object} * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.com.mikey.grpc.Request.toObject = function(includeInstance, msg) { var f, obj = { username: jspb.Message.getFieldWithDefault(msg, 1, "") }; if (includeInstance) { obj.$jspbMessageInstance = msg; } return obj; }; } /** * Deserializes binary data (in protobuf wire format). * @param {jspb.ByteSource} bytes The bytes to deserialize. * @return {!proto.com.mikey.grpc.Request} */ proto.com.mikey.grpc.Request.deserializeBinary = function(bytes) { var reader = new jspb.BinaryReader(bytes); var msg = new proto.com.mikey.grpc.Request; return proto.com.mikey.grpc.Request.deserializeBinaryFromReader(msg, reader); }; /** * Deserializes binary data (in protobuf wire format) from the * given reader into the given message object. * @param {!proto.com.mikey.grpc.Request} msg The message object to deserialize into. * @param {!jspb.BinaryReader} reader The BinaryReader to use. * @return {!proto.com.mikey.grpc.Request} */ proto.com.mikey.grpc.Request.deserializeBinaryFromReader = function(msg, reader) { while (reader.nextField()) { if (reader.isEndGroup()) { break; } var field = reader.getFieldNumber(); switch (field) { case 1: var value = /** @type {string} */ (reader.readString()); msg.setUsername(value); break; default: reader.skipField(); break; } } return msg; }; /** * Serializes the message to binary data (in protobuf wire format). * @return {!Uint8Array} */ proto.com.mikey.grpc.Request.prototype.serializeBinary = function() { var writer = new jspb.BinaryWriter(); proto.com.mikey.grpc.Request.serializeBinaryToWriter(this, writer); return writer.getResultBuffer(); }; /** * Serializes the given message to binary data (in protobuf wire * format), writing to the given BinaryWriter. * @param {!proto.com.mikey.grpc.Request} message * @param {!jspb.BinaryWriter} writer * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.com.mikey.grpc.Request.serializeBinaryToWriter = function(message, writer) { var f = undefined; f = message.getUsername(); if (f.length > 0) { writer.writeString( 1, f ); } }; /** * optional string username = 1; * @return {string} */ proto.com.mikey.grpc.Request.prototype.getUsername = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); }; /** @param {string} value */ proto.com.mikey.grpc.Request.prototype.setUsername = function(value) { jspb.Message.setProto3StringField(this, 1, value); }; /** * Generated by JsPbCodeGenerator. * @param {Array=} opt_data Optional initial data array, typically from a * server response, or constructed directly in Javascript. The array is used * in place and becomes part of the constructed object. It is not cloned. * If no data is provided, the constructed object will be empty, but still * valid. * @extends {jspb.Message} * @constructor */ proto.com.mikey.grpc.Response = function(opt_data) { jspb.Message.initialize(this, opt_data, 0, -1, null, null); }; goog.inherits(proto.com.mikey.grpc.Response, jspb.Message); if (goog.DEBUG && !COMPILED) { proto.com.mikey.grpc.Response.displayName = 'proto.com.mikey.grpc.Response'; } if (jspb.Message.GENERATE_TO_OBJECT) { /** * Creates an object representation of this proto suitable for use in Soy templates. * Field names that are reserved in JavaScript and will be renamed to pb_name. * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. * For the list of reserved names please see: * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. * @param {boolean=} opt_includeInstance Whether to include the JSPB instance * for transitional soy proto support: http://goto/soy-param-migration * @return {!Object} */ proto.com.mikey.grpc.Response.prototype.toObject = function(opt_includeInstance) { return proto.com.mikey.grpc.Response.toObject(opt_includeInstance, this); }; /** * Static version of the {@see toObject} method. * @param {boolean|undefined} includeInstance Whether to include the JSPB * instance for transitional soy proto support: * http://goto/soy-param-migration * @param {!proto.com.mikey.grpc.Response} msg The msg instance to transform. * @return {!Object} * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.com.mikey.grpc.Response.toObject = function(includeInstance, msg) { var f, obj = { realname: jspb.Message.getFieldWithDefault(msg, 2, "") }; if (includeInstance) { obj.$jspbMessageInstance = msg; } return obj; }; } /** * Deserializes binary data (in protobuf wire format). * @param {jspb.ByteSource} bytes The bytes to deserialize. * @return {!proto.com.mikey.grpc.Response} */ proto.com.mikey.grpc.Response.deserializeBinary = function(bytes) { var reader = new jspb.BinaryReader(bytes); var msg = new proto.com.mikey.grpc.Response; return proto.com.mikey.grpc.Response.deserializeBinaryFromReader(msg, reader); }; /** * Deserializes binary data (in protobuf wire format) from the * given reader into the given message object. * @param {!proto.com.mikey.grpc.Response} msg The message object to deserialize into. * @param {!jspb.BinaryReader} reader The BinaryReader to use. * @return {!proto.com.mikey.grpc.Response} */ proto.com.mikey.grpc.Response.deserializeBinaryFromReader = function(msg, reader) { while (reader.nextField()) { if (reader.isEndGroup()) { break; } var field = reader.getFieldNumber(); switch (field) { case 2: var value = /** @type {string} */ (reader.readString()); msg.setRealname(value); break; default: reader.skipField(); break; } } return msg; }; /** * Serializes the message to binary data (in protobuf wire format). * @return {!Uint8Array} */ proto.com.mikey.grpc.Response.prototype.serializeBinary = function() { var writer = new jspb.BinaryWriter(); proto.com.mikey.grpc.Response.serializeBinaryToWriter(this, writer); return writer.getResultBuffer(); }; /** * Serializes the given message to binary data (in protobuf wire * format), writing to the given BinaryWriter. * @param {!proto.com.mikey.grpc.Response} message * @param {!jspb.BinaryWriter} writer * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.com.mikey.grpc.Response.serializeBinaryToWriter = function(message, writer) { var f = undefined; f = message.getRealname(); if (f.length > 0) { writer.writeString( 2, f ); } }; /** * optional string realname = 2; * @return {string} */ proto.com.mikey.grpc.Response.prototype.getRealname = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); }; /** @param {string} value */ proto.com.mikey.grpc.Response.prototype.setRealname = function(value) { jspb.Message.setProto3StringField(this, 2, value); }; /** * Generated by JsPbCodeGenerator. * @param {Array=} opt_data Optional initial data array, typically from a * server response, or constructed directly in Javascript. The array is used * in place and becomes part of the constructed object. It is not cloned. * If no data is provided, the constructed object will be empty, but still * valid. * @extends {jspb.Message} * @constructor */ proto.com.mikey.grpc.StudentResponse = function(opt_data) { jspb.Message.initialize(this, opt_data, 0, -1, null, null); }; goog.inherits(proto.com.mikey.grpc.StudentResponse, jspb.Message); if (goog.DEBUG && !COMPILED) { proto.com.mikey.grpc.StudentResponse.displayName = 'proto.com.mikey.grpc.StudentResponse'; } if (jspb.Message.GENERATE_TO_OBJECT) { /** * Creates an object representation of this proto suitable for use in Soy templates. * Field names that are reserved in JavaScript and will be renamed to pb_name. * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. * For the list of reserved names please see: * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. * @param {boolean=} opt_includeInstance Whether to include the JSPB instance * for transitional soy proto support: http://goto/soy-param-migration * @return {!Object} */ proto.com.mikey.grpc.StudentResponse.prototype.toObject = function(opt_includeInstance) { return proto.com.mikey.grpc.StudentResponse.toObject(opt_includeInstance, this); }; /** * Static version of the {@see toObject} method. * @param {boolean|undefined} includeInstance Whether to include the JSPB * instance for transitional soy proto support: * http://goto/soy-param-migration * @param {!proto.com.mikey.grpc.StudentResponse} msg The msg instance to transform. * @return {!Object} * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.com.mikey.grpc.StudentResponse.toObject = function(includeInstance, msg) { var f, obj = { name: jspb.Message.getFieldWithDefault(msg, 1, ""), age: jspb.Message.getFieldWithDefault(msg, 2, 0), city: jspb.Message.getFieldWithDefault(msg, 3, "") }; if (includeInstance) { obj.$jspbMessageInstance = msg; } return obj; }; } /** * Deserializes binary data (in protobuf wire format). * @param {jspb.ByteSource} bytes The bytes to deserialize. * @return {!proto.com.mikey.grpc.StudentResponse} */ proto.com.mikey.grpc.StudentResponse.deserializeBinary = function(bytes) { var reader = new jspb.BinaryReader(bytes); var msg = new proto.com.mikey.grpc.StudentResponse; return proto.com.mikey.grpc.StudentResponse.deserializeBinaryFromReader(msg, reader); }; /** * Deserializes binary data (in protobuf wire format) from the * given reader into the given message object. * @param {!proto.com.mikey.grpc.StudentResponse} msg The message object to deserialize into. * @param {!jspb.BinaryReader} reader The BinaryReader to use. * @return {!proto.com.mikey.grpc.StudentResponse} */ proto.com.mikey.grpc.StudentResponse.deserializeBinaryFromReader = function(msg, reader) { while (reader.nextField()) { if (reader.isEndGroup()) { break; } var field = reader.getFieldNumber(); switch (field) { case 1: var value = /** @type {string} */ (reader.readString()); msg.setName(value); break; case 2: var value = /** @type {number} */ (reader.readInt32()); msg.setAge(value); break; case 3: var value = /** @type {string} */ (reader.readString()); msg.setCity(value); break; default: reader.skipField(); break; } } return msg; }; /** * Serializes the message to binary data (in protobuf wire format). * @return {!Uint8Array} */ proto.com.mikey.grpc.StudentResponse.prototype.serializeBinary = function() { var writer = new jspb.BinaryWriter(); proto.com.mikey.grpc.StudentResponse.serializeBinaryToWriter(this, writer); return writer.getResultBuffer(); }; /** * Serializes the given message to binary data (in protobuf wire * format), writing to the given BinaryWriter. * @param {!proto.com.mikey.grpc.StudentResponse} message * @param {!jspb.BinaryWriter} writer * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.com.mikey.grpc.StudentResponse.serializeBinaryToWriter = function(message, writer) { var f = undefined; f = message.getName(); if (f.length > 0) { writer.writeString( 1, f ); } f = message.getAge(); if (f !== 0) { writer.writeInt32( 2, f ); } f = message.getCity(); if (f.length > 0) { writer.writeString( 3, f ); } }; /** * optional string name = 1; * @return {string} */ proto.com.mikey.grpc.StudentResponse.prototype.getName = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); }; /** @param {string} value */ proto.com.mikey.grpc.StudentResponse.prototype.setName = function(value) { jspb.Message.setProto3StringField(this, 1, value); }; /** * optional int32 age = 2; * @return {number} */ proto.com.mikey.grpc.StudentResponse.prototype.getAge = function() { return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); }; /** @param {number} value */ proto.com.mikey.grpc.StudentResponse.prototype.setAge = function(value) { jspb.Message.setProto3IntField(this, 2, value); }; /** * optional string city = 3; * @return {string} */ proto.com.mikey.grpc.StudentResponse.prototype.getCity = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); }; /** @param {string} value */ proto.com.mikey.grpc.StudentResponse.prototype.setCity = function(value) { jspb.Message.setProto3StringField(this, 3, value); }; /** * Generated by JsPbCodeGenerator. * @param {Array=} opt_data Optional initial data array, typically from a * server response, or constructed directly in Javascript. The array is used * in place and becomes part of the constructed object. It is not cloned. * If no data is provided, the constructed object will be empty, but still * valid. * @extends {jspb.Message} * @constructor */ proto.com.mikey.grpc.StudentRequest = function(opt_data) { jspb.Message.initialize(this, opt_data, 0, -1, null, null); }; goog.inherits(proto.com.mikey.grpc.StudentRequest, jspb.Message); if (goog.DEBUG && !COMPILED) { proto.com.mikey.grpc.StudentRequest.displayName = 'proto.com.mikey.grpc.StudentRequest'; } if (jspb.Message.GENERATE_TO_OBJECT) { /** * Creates an object representation of this proto suitable for use in Soy templates. * Field names that are reserved in JavaScript and will be renamed to pb_name. * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. * For the list of reserved names please see: * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. * @param {boolean=} opt_includeInstance Whether to include the JSPB instance * for transitional soy proto support: http://goto/soy-param-migration * @return {!Object} */ proto.com.mikey.grpc.StudentRequest.prototype.toObject = function(opt_includeInstance) { return proto.com.mikey.grpc.StudentRequest.toObject(opt_includeInstance, this); }; /** * Static version of the {@see toObject} method. * @param {boolean|undefined} includeInstance Whether to include the JSPB * instance for transitional soy proto support: * http://goto/soy-param-migration * @param {!proto.com.mikey.grpc.StudentRequest} msg The msg instance to transform. * @return {!Object} * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.com.mikey.grpc.StudentRequest.toObject = function(includeInstance, msg) { var f, obj = { key: jspb.Message.getFieldWithDefault(msg, 1, "") }; if (includeInstance) { obj.$jspbMessageInstance = msg; } return obj; }; } /** * Deserializes binary data (in protobuf wire format). * @param {jspb.ByteSource} bytes The bytes to deserialize. * @return {!proto.com.mikey.grpc.StudentRequest} */ proto.com.mikey.grpc.StudentRequest.deserializeBinary = function(bytes) { var reader = new jspb.BinaryReader(bytes); var msg = new proto.com.mikey.grpc.StudentRequest; return proto.com.mikey.grpc.StudentRequest.deserializeBinaryFromReader(msg, reader); }; /** * Deserializes binary data (in protobuf wire format) from the * given reader into the given message object. * @param {!proto.com.mikey.grpc.StudentRequest} msg The message object to deserialize into. * @param {!jspb.BinaryReader} reader The BinaryReader to use. * @return {!proto.com.mikey.grpc.StudentRequest} */ proto.com.mikey.grpc.StudentRequest.deserializeBinaryFromReader = function(msg, reader) { while (reader.nextField()) { if (reader.isEndGroup()) { break; } var field = reader.getFieldNumber(); switch (field) { case 1: var value = /** @type {string} */ (reader.readString()); msg.setKey(value); break; default: reader.skipField(); break; } } return msg; }; /** * Serializes the message to binary data (in protobuf wire format). * @return {!Uint8Array} */ proto.com.mikey.grpc.StudentRequest.prototype.serializeBinary = function() { var writer = new jspb.BinaryWriter(); proto.com.mikey.grpc.StudentRequest.serializeBinaryToWriter(this, writer); return writer.getResultBuffer(); }; /** * Serializes the given message to binary data (in protobuf wire * format), writing to the given BinaryWriter. * @param {!proto.com.mikey.grpc.StudentRequest} message * @param {!jspb.BinaryWriter} writer * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.com.mikey.grpc.StudentRequest.serializeBinaryToWriter = function(message, writer) { var f = undefined; f = message.getKey(); if (f.length > 0) { writer.writeString( 1, f ); } }; /** * optional string key = 1; * @return {string} */ proto.com.mikey.grpc.StudentRequest.prototype.getKey = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); }; /** @param {string} value */ proto.com.mikey.grpc.StudentRequest.prototype.setKey = function(value) { jspb.Message.setProto3StringField(this, 1, value); }; /** * Generated by JsPbCodeGenerator. * @param {Array=} opt_data Optional initial data array, typically from a * server response, or constructed directly in Javascript. The array is used * in place and becomes part of the constructed object. It is not cloned. * If no data is provided, the constructed object will be empty, but still * valid. * @extends {jspb.Message} * @constructor */ proto.com.mikey.grpc.StudentResponseList = function(opt_data) { jspb.Message.initialize(this, opt_data, 0, -1, proto.com.mikey.grpc.StudentResponseList.repeatedFields_, null); }; goog.inherits(proto.com.mikey.grpc.StudentResponseList, jspb.Message); if (goog.DEBUG && !COMPILED) { proto.com.mikey.grpc.StudentResponseList.displayName = 'proto.com.mikey.grpc.StudentResponseList'; } /** * List of repeated fields within this message type. * @private {!Array<number>} * @const */ proto.com.mikey.grpc.StudentResponseList.repeatedFields_ = [1]; if (jspb.Message.GENERATE_TO_OBJECT) { /** * Creates an object representation of this proto suitable for use in Soy templates. * Field names that are reserved in JavaScript and will be renamed to pb_name. * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. * For the list of reserved names please see: * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. * @param {boolean=} opt_includeInstance Whether to include the JSPB instance * for transitional soy proto support: http://goto/soy-param-migration * @return {!Object} */ proto.com.mikey.grpc.StudentResponseList.prototype.toObject = function(opt_includeInstance) { return proto.com.mikey.grpc.StudentResponseList.toObject(opt_includeInstance, this); }; /** * Static version of the {@see toObject} method. * @param {boolean|undefined} includeInstance Whether to include the JSPB * instance for transitional soy proto support: * http://goto/soy-param-migration * @param {!proto.com.mikey.grpc.StudentResponseList} msg The msg instance to transform. * @return {!Object} * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.com.mikey.grpc.StudentResponseList.toObject = function(includeInstance, msg) { var f, obj = { studentresponseList: jspb.Message.toObjectList(msg.getStudentresponseList(), proto.com.mikey.grpc.StudentResponse.toObject, includeInstance) }; if (includeInstance) { obj.$jspbMessageInstance = msg; } return obj; }; } /** * Deserializes binary data (in protobuf wire format). * @param {jspb.ByteSource} bytes The bytes to deserialize. * @return {!proto.com.mikey.grpc.StudentResponseList} */ proto.com.mikey.grpc.StudentResponseList.deserializeBinary = function(bytes) { var reader = new jspb.BinaryReader(bytes); var msg = new proto.com.mikey.grpc.StudentResponseList; return proto.com.mikey.grpc.StudentResponseList.deserializeBinaryFromReader(msg, reader); }; /** * Deserializes binary data (in protobuf wire format) from the * given reader into the given message object. * @param {!proto.com.mikey.grpc.StudentResponseList} msg The message object to deserialize into. * @param {!jspb.BinaryReader} reader The BinaryReader to use. * @return {!proto.com.mikey.grpc.StudentResponseList} */ proto.com.mikey.grpc.StudentResponseList.deserializeBinaryFromReader = function(msg, reader) { while (reader.nextField()) { if (reader.isEndGroup()) { break; } var field = reader.getFieldNumber(); switch (field) { case 1: var value = new proto.com.mikey.grpc.StudentResponse; reader.readMessage(value,proto.com.mikey.grpc.StudentResponse.deserializeBinaryFromReader); msg.addStudentresponse(value); break; default: reader.skipField(); break; } } return msg; }; /** * Serializes the message to binary data (in protobuf wire format). * @return {!Uint8Array} */ proto.com.mikey.grpc.StudentResponseList.prototype.serializeBinary = function() { var writer = new jspb.BinaryWriter(); proto.com.mikey.grpc.StudentResponseList.serializeBinaryToWriter(this, writer); return writer.getResultBuffer(); }; /** * Serializes the given message to binary data (in protobuf wire * format), writing to the given BinaryWriter. * @param {!proto.com.mikey.grpc.StudentResponseList} message * @param {!jspb.BinaryWriter} writer * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.com.mikey.grpc.StudentResponseList.serializeBinaryToWriter = function(message, writer) { var f = undefined; f = message.getStudentresponseList(); if (f.length > 0) { writer.writeRepeatedMessage( 1, f, proto.com.mikey.grpc.StudentResponse.serializeBinaryToWriter ); } }; /** * repeated StudentResponse studentResponse = 1; * @return {!Array<!proto.com.mikey.grpc.StudentResponse>} */ proto.com.mikey.grpc.StudentResponseList.prototype.getStudentresponseList = function() { return /** @type{!Array<!proto.com.mikey.grpc.StudentResponse>} */ ( jspb.Message.getRepeatedWrapperField(this, proto.com.mikey.grpc.StudentResponse, 1)); }; /** @param {!Array<!proto.com.mikey.grpc.StudentResponse>} value */ proto.com.mikey.grpc.StudentResponseList.prototype.setStudentresponseList = function(value) { jspb.Message.setRepeatedWrapperField(this, 1, value); }; /** * @param {!proto.com.mikey.grpc.StudentResponse=} opt_value * @param {number=} opt_index * @return {!proto.com.mikey.grpc.StudentResponse} */ proto.com.mikey.grpc.StudentResponseList.prototype.addStudentresponse = function(opt_value, opt_index) { return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.com.mikey.grpc.StudentResponse, opt_index); }; proto.com.mikey.grpc.StudentResponseList.prototype.clearStudentresponseList = function() { this.setStudentresponseList([]); }; /** * Generated by JsPbCodeGenerator. * @param {Array=} opt_data Optional initial data array, typically from a * server response, or constructed directly in Javascript. The array is used * in place and becomes part of the constructed object. It is not cloned. * If no data is provided, the constructed object will be empty, but still * valid. * @extends {jspb.Message} * @constructor */ proto.com.mikey.grpc.StreamRequest = function(opt_data) { jspb.Message.initialize(this, opt_data, 0, -1, null, null); }; goog.inherits(proto.com.mikey.grpc.StreamRequest, jspb.Message); if (goog.DEBUG && !COMPILED) { proto.com.mikey.grpc.StreamRequest.displayName = 'proto.com.mikey.grpc.StreamRequest'; } if (jspb.Message.GENERATE_TO_OBJECT) { /** * Creates an object representation of this proto suitable for use in Soy templates. * Field names that are reserved in JavaScript and will be renamed to pb_name. * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. * For the list of reserved names please see: * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. * @param {boolean=} opt_includeInstance Whether to include the JSPB instance * for transitional soy proto support: http://goto/soy-param-migration * @return {!Object} */ proto.com.mikey.grpc.StreamRequest.prototype.toObject = function(opt_includeInstance) { return proto.com.mikey.grpc.StreamRequest.toObject(opt_includeInstance, this); }; /** * Static version of the {@see toObject} method. * @param {boolean|undefined} includeInstance Whether to include the JSPB * instance for transitional soy proto support: * http://goto/soy-param-migration * @param {!proto.com.mikey.grpc.StreamRequest} msg The msg instance to transform. * @return {!Object} * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.com.mikey.grpc.StreamRequest.toObject = function(includeInstance, msg) { var f, obj = { requestInfo: jspb.Message.getFieldWithDefault(msg, 1, "") }; if (includeInstance) { obj.$jspbMessageInstance = msg; } return obj; }; } /** * Deserializes binary data (in protobuf wire format). * @param {jspb.ByteSource} bytes The bytes to deserialize. * @return {!proto.com.mikey.grpc.StreamRequest} */ proto.com.mikey.grpc.StreamRequest.deserializeBinary = function(bytes) { var reader = new jspb.BinaryReader(bytes); var msg = new proto.com.mikey.grpc.StreamRequest; return proto.com.mikey.grpc.StreamRequest.deserializeBinaryFromReader(msg, reader); }; /** * Deserializes binary data (in protobuf wire format) from the * given reader into the given message object. * @param {!proto.com.mikey.grpc.StreamRequest} msg The message object to deserialize into. * @param {!jspb.BinaryReader} reader The BinaryReader to use. * @return {!proto.com.mikey.grpc.StreamRequest} */ proto.com.mikey.grpc.StreamRequest.deserializeBinaryFromReader = function(msg, reader) { while (reader.nextField()) { if (reader.isEndGroup()) { break; } var field = reader.getFieldNumber(); switch (field) { case 1: var value = /** @type {string} */ (reader.readString()); msg.setRequestInfo(value); break; default: reader.skipField(); break; } } return msg; }; /** * Serializes the message to binary data (in protobuf wire format). * @return {!Uint8Array} */ proto.com.mikey.grpc.StreamRequest.prototype.serializeBinary = function() { var writer = new jspb.BinaryWriter(); proto.com.mikey.grpc.StreamRequest.serializeBinaryToWriter(this, writer); return writer.getResultBuffer(); }; /** * Serializes the given message to binary data (in protobuf wire * format), writing to the given BinaryWriter. * @param {!proto.com.mikey.grpc.StreamRequest} message * @param {!jspb.BinaryWriter} writer * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.com.mikey.grpc.StreamRequest.serializeBinaryToWriter = function(message, writer) { var f = undefined; f = message.getRequestInfo(); if (f.length > 0) { writer.writeString( 1, f ); } }; /** * optional string request_info = 1; * @return {string} */ proto.com.mikey.grpc.StreamRequest.prototype.getRequestInfo = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); }; /** @param {string} value */ proto.com.mikey.grpc.StreamRequest.prototype.setRequestInfo = function(value) { jspb.Message.setProto3StringField(this, 1, value); }; /** * Generated by JsPbCodeGenerator. * @param {Array=} opt_data Optional initial data array, typically from a * server response, or constructed directly in Javascript. The array is used * in place and becomes part of the constructed object. It is not cloned. * If no data is provided, the constructed object will be empty, but still * valid. * @extends {jspb.Message} * @constructor */ proto.com.mikey.grpc.StreamResponse = function(opt_data) { jspb.Message.initialize(this, opt_data, 0, -1, null, null); }; goog.inherits(proto.com.mikey.grpc.StreamResponse, jspb.Message); if (goog.DEBUG && !COMPILED) { proto.com.mikey.grpc.StreamResponse.displayName = 'proto.com.mikey.grpc.StreamResponse'; } if (jspb.Message.GENERATE_TO_OBJECT) { /** * Creates an object representation of this proto suitable for use in Soy templates. * Field names that are reserved in JavaScript and will be renamed to pb_name. * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. * For the list of reserved names please see: * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. * @param {boolean=} opt_includeInstance Whether to include the JSPB instance * for transitional soy proto support: http://goto/soy-param-migration * @return {!Object} */ proto.com.mikey.grpc.StreamResponse.prototype.toObject = function(opt_includeInstance) { return proto.com.mikey.grpc.StreamResponse.toObject(opt_includeInstance, this); }; /** * Static version of the {@see toObject} method. * @param {boolean|undefined} includeInstance Whether to include the JSPB * instance for transitional soy proto support: * http://goto/soy-param-migration * @param {!proto.com.mikey.grpc.StreamResponse} msg The msg instance to transform. * @return {!Object} * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.com.mikey.grpc.StreamResponse.toObject = function(includeInstance, msg) { var f, obj = { responseInfo: jspb.Message.getFieldWithDefault(msg, 1, "") }; if (includeInstance) { obj.$jspbMessageInstance = msg; } return obj; }; } /** * Deserializes binary data (in protobuf wire format). * @param {jspb.ByteSource} bytes The bytes to deserialize. * @return {!proto.com.mikey.grpc.StreamResponse} */ proto.com.mikey.grpc.StreamResponse.deserializeBinary = function(bytes) { var reader = new jspb.BinaryReader(bytes); var msg = new proto.com.mikey.grpc.StreamResponse; return proto.com.mikey.grpc.StreamResponse.deserializeBinaryFromReader(msg, reader); }; /** * Deserializes binary data (in protobuf wire format) from the * given reader into the given message object. * @param {!proto.com.mikey.grpc.StreamResponse} msg The message object to deserialize into. * @param {!jspb.BinaryReader} reader The BinaryReader to use. * @return {!proto.com.mikey.grpc.StreamResponse} */ proto.com.mikey.grpc.StreamResponse.deserializeBinaryFromReader = function(msg, reader) { while (reader.nextField()) { if (reader.isEndGroup()) { break; } var field = reader.getFieldNumber(); switch (field) { case 1: var value = /** @type {string} */ (reader.readString()); msg.setResponseInfo(value); break; default: reader.skipField(); break; } } return msg; }; /** * Serializes the message to binary data (in protobuf wire format). * @return {!Uint8Array} */ proto.com.mikey.grpc.StreamResponse.prototype.serializeBinary = function() { var writer = new jspb.BinaryWriter(); proto.com.mikey.grpc.StreamResponse.serializeBinaryToWriter(this, writer); return writer.getResultBuffer(); }; /** * Serializes the given message to binary data (in protobuf wire * format), writing to the given BinaryWriter. * @param {!proto.com.mikey.grpc.StreamResponse} message * @param {!jspb.BinaryWriter} writer * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.com.mikey.grpc.StreamResponse.serializeBinaryToWriter = function(message, writer) { var f = undefined; f = message.getResponseInfo(); if (f.length > 0) { writer.writeString( 1, f ); } }; /** * optional string response_info = 1; * @return {string} */ proto.com.mikey.grpc.StreamResponse.prototype.getResponseInfo = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); }; /** @param {string} value */ proto.com.mikey.grpc.StreamResponse.prototype.setResponseInfo = function(value) { jspb.Message.setProto3StringField(this, 1, value); }; goog.object.extend(exports, proto.com.mikey.grpc);
客戶端
var service = require('../static_codegen/Student_grpc_pb'); var message = require('../static_codegen/Student_pb'); var grpc = require('grpc'); var client = new service.StudentServiceClient('localhost:8899', grpc.credentials.createInsecure()); var request = new message.Request(); request.setUsername('麥奇'); client.getRealNameByUserName(request, function(error, respData) { console.log(respData.getRealname()); })
服務器
var service = require('../static_codegen/Student_grpc_pb'); var message = require('../static_codegen/Student_pb'); var grpc = require('grpc'); var server = new grpc.Server(); server.addService( service.StudentServiceService, { getRealNameByUserName:getRealNameByUserName, getStudentByAge:getStudentByAge(), getStudentByStream:getStudentByStream(), biTalk:biTalk() } ) server.bind('localhost:8899', grpc.ServerCredentials.createInsecure()); server.start(); function getRealNameByUserName(call,callback) { console.log('request:'+call.request.getUsername()); var response = new message.Response(); response.setRealname('麥奇蜀素'); callback(null, response); } function getStudentByAge() {} function getStudentByStream() {} function biTalk() {}