gRPC初試

本文參照官網文檔https://grpc.io/docs/tutorials/basic/java/,主要介紹gRPC的demo搭建。

我從https://github.com/grpc/grpc-java.git拷貝了grpc-java項目到本地,參考了examples文件夾下的代碼,由於這個項目是gradle構建,不太熟悉gradle的我新建了一個項目並將examples下的部分代碼複製到了新的項目中。

首先將examples文件夾下的pom.xml的dependencies和build拷貝到新項目中:


  <properties>
    <grpc.version>1.25.0</grpc.version><!-- CURRENT_GRPC_VERSION -->
  </properties>
  <dependencies>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-netty</artifactId>
      <version>${grpc.version}</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-protobuf</artifactId>
      <version>${grpc.version}</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-stub</artifactId>
      <version>${grpc.version}</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-core</artifactId>
      <version>1.9.5</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <extensions>
      <extension>
        <groupId>kr.motd.maven</groupId>
        <artifactId>os-maven-plugin</artifactId>
        <version>1.4.1.Final</version>
      </extension>
    </extensions>
    <plugins>
      <plugin>
        <groupId>org.xolstice.maven.plugins</groupId>
        <artifactId>protobuf-maven-plugin</artifactId>
        <version>0.5.0</version>
        <configuration>
          <protocArtifact>com.google.protobuf:protoc:3.2.0:exe:${os.detected.classifier}</protocArtifact>
          <pluginId>grpc-java</pluginId>
          <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
        </configuration>
        <executions>
          <execution>
            <goals>
              <goal>compile</goal>
              <goal>compile-custom</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

然後再新項目src/main目錄下新建一個proto目錄,拷貝examples/src/main/proto文件夾下的helloworld.proto到新建的proto目錄下,在項目中建一個helloword包,將helloworld.proto中的java_package改成自己項目中helloworld包的路徑,然後執行mvn install命令。執行完成後,target目錄下就會生成gRPC代碼。

這個時候將examples/src/main/java/io/grpc/examples/helloworld中的類拷貝到新項目的helloworld包下。重新導入一下類,然後依次啓動HelloworldServer和HelloworldClient,HelloworldClient運行 如下:

這個例子就是HelloworldClient發送一個name('world')給HelloworldServer,HelloworldServer返回給HelloworldClient消息'Hello' + name。這樣,官網的Helloworld demo就運行成功了。

下面嘗試仿照這個Helloworld自己寫一個demo。

首先在proto目錄下新建一個student.proto文件:

syntax = "proto3";

option java_multiple_files = true;
option java_package = "zhangc.grpc.student";
option java_outer_classname = "StudentProto";
option objc_class_prefix = "STU";

service StudentOperation{
    rpc Get(StudentRequest) returns (stream Student) {}
}

//定義StudentRequest類型,裏面包含一個String類型的msg字段
//後面的數字是標識號 不必連續,1-15佔1字節 16-2047佔2字節 通常將1-15保留給常用字段
message StudentRequest{
    string msg = 1;
}
message Student{
    int32 id = 1;
    string name = 2;
}

然後執行mvn install生成gRPC代買,編寫StudentServer服務端:

package zhangc.grpc.student;

import io.grpc.Server;
import io.grpc.ServerBuilder;

import java.io.IOException;

/**
 * @author zhangc
 * @version 1.0
 * @date 2019/11/28
 */
public class StudentServer {

    private final int port;
    private final Server server;

    public StudentServer(int port) throws IOException {
        this.port = port;
        this.server = ServerBuilder.forPort(port)
                .addService(new StudentService())
                .build()
                .start();
        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");
                StudentServer.this.stop();
                System.err.println("*** server shut down");
            }
        });
    }

    public void stop(){
        if (server != null){
            server.shutdown();
        }
    }

    /**
     * Await termination on the main thread since the grpc library uses daemon threads.
     */
    private void blockUntilShutdown() throws InterruptedException {
        if (server != null) {
            server.awaitTermination();
        }
    }

    public static void main(String[] args) throws InterruptedException, IOException {
        StudentServer studentServer = new StudentServer(1214);
        studentServer.blockUntilShutdown();
    }
}

StudentClient客戶端:

package zhangc.grpc.student;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;

import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

/**
 * @author zhangc
 * @version 1.0
 * @date 2019/11/28
 */
public class StudentClient {
    private static final Logger logger = Logger.getLogger(StudentClient.class.getName());

    private final ManagedChannel channel;
    private final StudentOperationGrpc.StudentOperationBlockingStub blockingStub;
    public StudentClient(String host, int port) {
        this(ManagedChannelBuilder.forAddress(host, port).usePlaintext(true));
    }

    public StudentClient(ManagedChannelBuilder<?> builder) {
        channel = builder.build();
        blockingStub = StudentOperationGrpc.newBlockingStub(channel);
    }

    public void get(String msg){
        StudentRequest request = StudentRequest.newBuilder().setMsg(msg).build();
        Student student = blockingStub.get(request);
        logger.info("id:" + student.getId());
        logger.info("name:" + student.getName());
    }
    public static void main(String[] args) throws Exception {
        StudentClient client = new StudentClient("localhost", 1214);
        try {
            /* Access a service running on the local machine on port 50051 */
            String msg = "helloworld";
            if (args.length > 0) {
                msg = args[0]; /* Use the arg as the name to greet if provided */
            }
            client.get(msg);
        } finally {
            client.shutdown();
        }
    }
    public void shutdown() throws InterruptedException {
        channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
    }
}

客戶端發送一個msg給服務端,然後服務端將msg打印並響應一個Student對象給客戶端,然後客戶端將這個對象打印,運行結果如下:

server:

client:

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章