一架梯子,一头程序猿,仰望星空!

grpc java入门教程


本章主要介绍在java中grpc的基本用法。

前置知识点:

1.环境要求

  • JDK 7 或者更高的版本

2.下载例子代码

我们直接从grpc的github地址下载演示代码。

$ # 下载v1.23.0版本的代码,你也可以直接下载最新的版本
$ git clone -b v1.23.0 https://github.com/grpc/grpc-java

$ # 切换到Java的演示代码目录
$ cd grpc-java/examples

3.运行grpc应用

首先编译服务端和客户端代码

$ ./gradlew installDist

运行grpc服务端

$ ./build/install/examples/bin/hello-world-server

另外打开一个命令行创建,运行客户端

$ ./build/install/examples/bin/hello-world-client

ok, 这个时候你就看到客户端请求服务端的输出结果,后面我们演示下怎么添加一个新的rpc方法。

4.更新rpc服务

grpc的接口是通过protocol buffers定义的,通常都保存在.proto文件中。

如果你打开,前面例子的服务端和客户端代码看,你会发现有一个SayHello的方法,这个方法接受HelloRequest参数,并返回HelloReply参数,下面看看对应的.proto文件,是如何定义rpc接口的。

打开:src/main/proto/helloworld.proto 协议文件。

// 定义Greeter,你可以当成类
service Greeter {
  // 定义一个rpc方法SayHello,接受HelloRequest消息,返回HelloReply消息
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// 定义请求参数,HelloRequest消息
message HelloRequest {
  string name = 1;
}

// 定义响应参数,HelloReply消息
message HelloReply {
  string message = 1;
}

现在我们添加一个新的rpc方法,现在.proto定义变成这样。

// 定义Greeter,你可以当成类
service Greeter {
  // SayHello方法
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  // 定义一个SayHelloAgain方法,接受HelloRequest消息,返回HelloReply消息
  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}

// 定义请求参数,HelloRequest消息
message HelloRequest {
  string name = 1;
}

// 定义响应参数,HelloReply消息
message HelloReply {
  string message = 1;
}

5.生成grpc代码

重新编译客户端和服务端代码。

$ ./gradlew installDist

这个时候会生成GreeterGrpc.java源码文件,包含了我们在.proto定义的服务和方法。

6.更新并运行应用程序

6.1. 更新服务端代码

打开源码:src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java,下面是关键代码。

// 定义GreeterImpl类型,实现我们在.proto定义的服务
private class GreeterImpl extends GreeterGrpc.GreeterImplBase {

  // 实现sayHello方法
  @Override
  public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
    // 初始化HelloReply消息
    HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
    // 返回消息
    responseObserver.onNext(reply);
    responseObserver.onCompleted();
  }

  // 实现sayHelloAgain方法
  @Override
  public void sayHelloAgain(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
    HelloReply reply = HelloReply.newBuilder().setMessage("Hello again " + req.getName()).build();
    responseObserver.onNext(reply);
    responseObserver.onCompleted();
  }
}
...

6.2. 更新客户端代码

打开src/main/java/io/grpc/examples/helloworld/HelloWorldClient.java文件,调用rpc方法的关键代码如下:

public void greet(String name) {
  logger.info("Will try to greet " + name + " ...");
  // 创建请求消息
  HelloRequest request = HelloRequest.newBuilder().setName(name).build();
  // 定义响应消息
  HelloReply response;
  try {
    // 调用服务端的sayHello方法
    response = blockingStub.sayHello(request);
  } catch (StatusRuntimeException e) {
    logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
    return;
  }
  logger.info("Greeting: " + response.getMessage());
  try {
    // 调用服务端的sayHelloAgain方法
    response = blockingStub.sayHelloAgain(request);
  } catch (StatusRuntimeException e) {
    logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
    return;
  }
  logger.info("Greeting: " + response.getMessage());
}

完整的代码,请参考源码文件的内容。

需要重新编译在运行程序即可。