GRPC的简介
(1)在gRPC中客户端可以直接调用运行在不同机器上服务器端的方法,与其它RPC(远程方法调用)一样,定义一个方法,可以被远程使用参数调用,然后通过返回值进行响应。
(2)服务器端运行gRPC服务来处理客户端的调用,客户端保存着服务器端的存根——提供服务器端的方法,来决定调用哪个方法。
(3)服务器端与客户端通过protocol buffers进行通信,谷歌自己的开源的数据序列化结构。 如图:

简单的demo(源代码地址)
目的:客户端向服务器端发送请求计算两个字符串相加,服务器端返回结果
工具:IDEA+maven
(1)编写 proto文件
syntax="proto3";//使用的版本
option java_package="nwpu.cn.grpc.api";//生成class文件所在的包
option java_outer_classname="GrpcAddApi";//class文件的名称
option java_multiple_files=true;//如果是false 每个message和service都会是java_outer_classname的内部类,相反则单独生成类文件,防止生成类文件过大
package nwpu.cn.grpc.api;
//服务接口定义,服务端和客户端都要遵循该接口进行通信
service RPCAddService{
//接收请求,返回响应
rpc getAdd(RPCAddRequest) returns(RPCAddResponse){}
}
//定义请求消息
message RPCAddRequest{
string first=1;
string second=2;
}
//定义响应消息
message RPCAddResponse{
string result=1;
}
(2)添加maven依赖(参考grpc-java)
kr.motd.maven
os-maven-plugin
1.5.0.Final
org.xolstice.maven.plugins
protobuf-maven-plugin
0.5.1
com.google.protobuf:protoc:3.5.1-1:exe:${os.detected.classifier}
grpc-java
io.grpc:protoc-gen-grpc-java:1.17.1:exe:${os.detected.classifier}
compile
compile-custom
jar
UTF-8
UTF-8
1.8
io.grpc
grpc-netty-shaded
1.17.1
io.grpc
grpc-protobuf
1.17.1
io.grpc
grpc-stub
1.17.1
(3)服务器端实现
/*
public static abstract class RPCAddServiceImplBase implements io.grpc.BindableService
注意这里是一个 BindableService类,服务器端发布服务的使用就是使用io.grpc.Server中的addService()方法将BindableService服务添加进去
参考GPCServer.java的实验与API
*/
RPCAddServiceImpl.java
public class RPCAddServiceImpl extends RPCAddServiceGrpc.RPCAddServiceImplBase{
@Override
public void getAdd(RPCAddRequest request, StreamObserver responseObserver) {
RPCAddResponse rpcAddResponse=null;
String result=request.getFirst()+request.getSecond();
try{
rpcAddResponse=RPCAddResponse.newBuilder().setResult(result).build();
}catch (Exception e){
responseObserver.onError(e);
}finally {
responseObserver.onNext(rpcAddResponse);
}
responseObserver.onCompleted();
}
}
public class GRPCServer {
private static final int port=9999;
public static void main(String argc[]) throws IOException, InterruptedException {
//添加服务
Server server= ServerBuilder.forPort(port).addService(new RPCAddServiceImpl())
.build().start();
System.out.println("Grpc服务器启动,端口="+port);
//等待客户端的连接
server.awaitTermination();
}
}
(3)客户端的实现
public class GRPCClient {
private static final String host="localhost";
private static final int serverport=9999;
public static void main(String[] args) throws Exception{
/*
ManagedChannel 提供生命周期管理的通道
ManagedChannelBuilder 创建 ManagedChannel实例
forAddress() 使用目标地址和端口创建channel
usePlaintext() 使用服务器的明文连接
与其相对应的 useTransportSecuriry() 使用TLS加密
*/
ManagedChannel managedChannel = ManagedChannelBuilder.forAddress(host, serverport).usePlaintext().build();
try {
RPCAddServiceGrpc.RPCAddServiceBlockingStub rpcAddService = RPCAddServiceGrpc.newBlockingStub(managedChannel);
RPCAddRequest rpcAddRequest = RPCAddRequest.newBuilder().setFirst("1").setSecond("2").build();
RPCAddResponse rpcAddResponse = rpcAddService.getAdd(rpcAddRequest);
System.out.println(rpcAddResponse.getResult());
}finally {
managedChannel.shutdown();
}
}
}
参考资料