本章主要介绍在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());
}
完整的代码,请参考源码文件的内容。
需要重新编译在运行程序即可。