前言
由于需要传送200M的压缩包文件,之前的同步存根Stub无法满足需求。再经过调研后,发现客户端流能够很好的解决这个问题。
注:流服务本质上就是通过异步存根Stub来实现的,具体到服务端和客户端只需实现观察者的接口来处理业务逻辑即可
一、grpc是什么?
在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。
二、简单的grpc接口
一个grpc接口包括以下几个部分
注:由于不需要流,所以此处使用的为同步阻塞存根
1.定义proto文件
service RouteGuide {
// 一个简单的rpc接口
rpc GetFeature(Point) returns (Feature) {
}
}
// 消息定义
message Point {
int32 latitude = 1;
int32 longitude = 2;
}
message Feature {
string name = 1;
Point location = 2;
}
2.服务端代码
public void getFeature(Point request, StreamObserver<Feature> responseObserver) {
responseObserver.onNext(checkFeature(request));
responseObserver.onCompleted();
}
3.客户端代码
public void getFeature(int lat, int lon) {
Point request = Point.newBuilder().setLatitude(lat).setLongitude(lon).build();
Feature feature = blockingStub.getFeature(request);
// 对返回数据进行校验
if (RouteGuideUtil.exists(feature)) {
info("Found feature called \"{0}\" at {1}, {2}",
feature.getName(),
RouteGuideUtil.getLatitude(feature.getLocation()),
RouteGuideUtil.getLongitude(feature.getLocation()));
} else {
info("Found no feature at {0}, {1}",
RouteGuideUtil.getLatitude(feature.getLocation()),
RouteGuideUtil.getLongitude(feature.getLocation()));
}
}
三、流服务接口
此处使用为客户端流来实现文件传输的
1.proto文件
service RouteGuide {
// 客户端文件流例子
rpc sendFile(stream FileInfo) returns (Info) {
}
}
message FileInfo {
int32 index = 1;
bytes arrs = 2;
}
message Info {
string msg = 1;
}
2.服务端代码
// 测试文件流
@Override
public StreamObserver<FileInfo> sendFile(StreamObserver<Info> responseObserver) {
try {
return new StreamObserver