gRPC Learning Notes

簡介

更多內容參考: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 是什麼?

在 gRPC 裏客戶端應用能夠像調用本地對象同樣直接調用另外一臺不一樣的機器上服務端應用的方法 ,使得您可以更容易地建立分佈式應用和服務。與許多 RPC 系統相似,git

gRPC 也是基於如下理念 :

定義一個服務,指定其可以被遠程調用的方法(包含參數和返回類型)。在服務端實現這個接口 ,並運行一個 gRPC 服務器來處理客戶端調用。在客戶端擁有一個存根可以像服務端同樣的方法。github

 

gRPC 客戶端和服務端能夠在多種環境中運行和交互 - 從 google 內部的服務器到你本身的筆記本 ,而且能夠用任何 gRPC 支持的語言(#quickstart)來編寫。因此,你能夠很容易地用 Java 建立一 個 gRPC 服務端,用 Go、Python、Ruby 來建立客戶端。此外,Google 最新 API 將有 gRPC 版 本的接口,使你很容易地將 Google 的功能集成到你的應用裏。golang

使用 protocol buffers

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 版本

儘管 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 服務端交互時出現的兼容性問題,反之亦然。

安裝gRPC

Java 例子代碼在 GitHub 源碼庫裏。你能夠運行以下命令克隆源碼到本地:

git clone -b v1.24.0 https://github.com/grpc/grpc-java

切換當前目錄到grpc-java/examples

cd grpc-java/examples

Run a gRPC application

From the examples directory:

  1. Compile the client and server
./gradlew installDist
  1. Run the server
 ./build/install/examples/bin/hello-world-server
  1. In another terminal, run the client
 ./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或測試/使用gRPC-Java庫的未發行版本(例如主HEAD)時,才須要構建。

構建須要JDK 8,由於咱們的測試使用TLS。

grpc-java有一個用於protoc的C ++代碼生成插件。因爲許多Java開發人員沒有安裝C編譯器,也不須要運行或修改代碼生成,所以該構建能夠跳過它。要跳過,請建立文件 <project-root>/gradle.properties並添加skipCodegen=true

而後,要構建,運行:

$ ./gradlew build

要將工件安裝到您的Maven本地存儲庫中以在您本身的項目中使用,請運行:

$ ./gradlew publishToMavenLocal

IntelliJ的注意事項

當您將項目做爲Gradle項目導入並將IDE生成/運行操做委託給Gradle時,以IntelliJ進行構建的效果最佳。

您能夠在如下位置找到此設置:

      -> Build Tools -> Gradle -> Runner
      -> Delegate IDE build/run actions to gradle.

如何構建代碼生成插件

僅當您要更改代碼生成時,才須要此部分。大多數用戶只須要skipCodegen=true如上所述使用便可。

創建Protobuf

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和使用-ICXXFLAGS-L在 LDFLAGS引用它。在構建grpc-java時將使用環境變量。

Protobuf /usr/local默認安裝到

對於Visual C ++,請參閱Protobuf自述文件, 以瞭解如何編譯Protobuf。gRPC-java假定爲Release版本。

Linux和MinGW

若是/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"

Visual C ++的注意事項

在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的注意事項

若是您在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'
            }
        }
    }
}
build.gradle

 

簡單Demo

參考: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;
  }

}
Request.java
// 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();
}
RequesOrBuildert.java
// 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;
  }

}
Response.java
// 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();
}
ResponseOrBuilder.java
// 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)
}
StudentProto.java 

服務類:

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;
  }
}
StudentServiceGrpc.java

實現類:

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();

    }
}
StudentServiceImpl.java

客戶端:

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();

    }
}
GrpcClient.java

服務器:

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");
            }
        });
    }
}
GrpcServer.java

定義不一樣的服務方法

gRPC lets you define four kinds of service method:

  • Unary RPCs where the client sends a single request to the server and gets a single response back, just like a normal function call.
rpc SayHello(HelloRequest) returns (HelloResponse){}

 

  • Server streaming RPCs where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. gRPC guarantees message ordering within an individual RPC call.
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){}

 

  • Client streaming RPCs where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them and return its response. Again gRPC guarantees message ordering within an individual RPC call.
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {}
  • Bidirectional streaming RPCs where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved.
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() {

            }
        };
    }
}
StudentGrpcImpl.java

 跨語言調用服務

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;
}
Student.proto

動態生成服務代碼

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)
    });
grpcClient.js
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() {}
grpcServer.js

靜態生成服務代碼
參考: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);
Student_grpc_pb.js
/**
 * @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);
Student_pb.js

 

 客戶端

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());
})
grpcStaticClient.js

 

服務器

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() {}
grpcStaticServer.js
相關文章
相關標籤/搜索