.proto
rpc methodRequestStream(stream HelloRequest) returns (HelloReply){}
服务端
@Component
public class Greeter extends GreeterGrpc.GreeterImplBase implements InitializingBean {
/**
* StreamObserver的泛型是Result,我们就叫返回流观察者,如果是request就叫请求流观察者
* 这个和普通的不一样直接返回了一个请求流观察者的接口实现,而且方法的参数还是一个返回流观察者,好像搞反了一样
*
* @param responseObserver
* @return
*/
@Override
public StreamObserver<Helloworld.HelloRequest> methodRequestStream(
StreamObserver<Helloworld.HelloReply> responseObserver) {
return new StreamObserver<Helloworld.HelloRequest>() {
@Override
public void onNext(Helloworld.HelloRequest helloRequest) {
System.out.println("收到请求 \n");
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onCompleted() {
Helloworld.HelloReply helloRequest= Helloworld.HelloReply.newBuilder().setMessage("hello world").build();
responseObserver.onNext(helloRequest);
responseObserver.onCompleted();
}
};
}
}
客户端
@RunWith(SpringRunner.class)
@SpringBootTest
public class GrpcApplicationTests {
/**
* 客户端流
*/
@Test
public void contextLoads2(){
Helloworld.HelloRequest helloRequest = Helloworld.HelloRequest.newBuilder().setName("lwh").build();
StreamObserver<Helloworld.HelloReply> responseObserver = new StreamObserver<Helloworld.HelloReply>() {
@Override
public void onNext(Helloworld.HelloReply helloReply) {
System.out.println("返回结果");
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onCompleted() {
}
};
Channel channel = ManagedChannelBuilder
.forAddress("127.0.0.1", 9098)//服务端
.usePlaintext(true)//usePlaintext的意思是使用明文不加密(应该可以加密)
.build();
//创建异步的存根
GreeterGrpc.GreeterStub greeterStub = GreeterGrpc.newStub(channel);
StreamObserver<Helloworld.HelloRequest> result = greeterStub.methodRequestStream(responseObserver);
//这里我们发送了三次请求过去 相当于服务端那边返回的请求流观察者被调用了三次,所以就打印了三句话 收到请求
result.onNext(helloRequest);
result.onNext(helloRequest);
result.onNext(helloRequest);
result.onCompleted();
//服务端那边结束请求中调用了一次我们传给他的返回流观察者中的onNext方法,所以客户端就打印了一次收到请求
/**
* 这里会有人问,这里不能返回多个吗?
* 不能,虽然这两个观察者看上去一样,都是StreamObserver接口,但是,这个方法只是请求流调用,
* 在grpc内部 最后返回的时候,只返回第一个指定的返回值,不管返回了多少个,在客户端那边只会收到第一个返回的结果
*/
try {
Thread.sleep(10000);
}
catch (Exception ex){}
}
}
响应结果