What exactly is the bidirectional flow of grpc? 2 pieces of code tell you

Summary: Why do you need grpc bidirectional streaming?

This article is shared from HUAWEI CLOUD Community " What is the bidirectional flow of grpc? 2 pieces of code to tell you ", author: breakDawn.

Why do you need grpc bidirectional streaming?

Sometimes the request call and return process is not a simple question and answer form. It may involve sending once, returning in batches multiple times, or sending each other at will.

Therefore, the simple restful model cannot meet the above common requirements, and the two-way flow of grpc emerges as the times require, realizing two-way asynchronous IO communication through a tpc link.

grpc bidirectional flow

A bidirectional streaming RPC is one where two parties send a sequence of messages using read and write streams.

The two streams operate independently, so the client and server can read and write in any order they like: for example, the server can wait to receive all client messages before writing a response, or it can read and write messages alternately, or other A combination of read and write.

  • It can be understood as the use of asynchronous IO in common IO models

The order of messages in each stream is reserved. You can specify the type of the method by prefixing the request and response with the stream keyword.

//AcceptsastreamofRouteNotessentwhilearouteisbeingtraversed,
//whilereceivingotherRouteNotes(e.g.fromotherusers).
rpcRouteChat(streamRouteNote)returns(streamRouteNote){}

Client-side bidirectional streaming calls

  1. Define a responseOberserver, that is, a response observer, which is used to define how to process the message returned by the server. Generally, messages are put into a certain blocking queue or a single-capacity queue SettableFuture.
  2. Calling stub.sendMessage(reponseOberserver) tells the grpc framework that I will use this reponseOberserver to process the response of the sendMessage message.
    Note that the name of the sendMesage method depends on how it is defined in our proto.
  3. Then the stub.sendMessage() method returns us a requestObserver, and let us use this observer.onNext() to send the request, which can be sent as many times as you like, and it will be returned immediately.
  4. When you don't need to send any more, you can call onCompleted to tell the other party that you can end it.
    The following is a code example excerpted from the official website:
publicvoidrouteChat()throwsException{
info("***RoutChat");
finalSettableFuture<Void>finishFuture=SettableFuture.create();
//定义了如何处理收到的返回消息观察者
	StreamObserverreponseObserver=newStreamObserver<RouteNote>(){
@Override
publicvoidonNext(RouteNotenote){
info("Gotmessage\"{0}\"at{1},{2}",note.getMessage(),note.getLocation()
.getLatitude(),note.getLocation().getLongitude());
}

@Override
publicvoidonError(Throwablet){
finishFuture.setException(t);
}

@Override
publicvoidonCompleted(){
			//往finishFuture设置空时,说明完成了消息流关闭了
finishFuture.set(null);
}
};

//框架返回给我一个请求流观察者,让我用这个观察者.onNext(message)去发请求,返回结果和我传给他的responseServer绑定了。
StreamObserver<RouteNote>requestObserver=
asyncStub.routeChat();

try{
RouteNote[]requests=
{newNote("Firstmessage",0,0),newNote("Secondmessage",0,1),
newNote("Thirdmessage",1,0),newNote("Fourthmessage",1,1)};

for(RouteNoterequest:requests){
info("Sendingmessage\"{0}\"at{1},{2}",request.getMessage(),request.getLocation()
.getLatitude(),request.getLocation().getLongitude());
requestObserver.onNext(request);
}
requestObserver.onCompleted();

finishFuture.get();
info("FinishedRouteChat");
}catch(Exceptiont){
requestObserver.onError(t);
logger.log(Level.WARNING,"RouteChatFailed",t);
throwt;
}
}

Server-side processing:

  1. When we build the server, we need to call nettyServer, establish the netty service, and bind a xxxServiceImpl abstract class. This xxxServiceImpl is the server structure we defined in proto, which supports processing the messages we define.
  2. In xxxServiceImpl, there are many methods that need to be overridden, and you need to define how to process the received request and how to send the response to the client. The action of sending a response is requestObserver.onNext (response message) in the parameter
  3. The returned xxxService class will be provided to the netty and grpc frameworks in the first step. When a message is received, it will separate the network thread and the business thread through its asynchronous mechanism and go to the place where it is executed.
    The following is a code example excerpted from the official website:
class	xxxServiceextendxxxServiceImpl{
@Override
publicvoidlistFeatures(Rectanglerequest,StreamObserver<Feature>responseObserver){
intleft=min(request.getLo().getLongitude(),request.getHi().getLongitude());
intright=max(request.getLo().getLongitude(),request.getHi().getLongitude());
inttop=max(request.getLo().getLatitude(),request.getHi().getLatitude());
intbottom=min(request.getLo().getLatitude(),request.getHi().getLatitude());

for(Featurefeature:features){
if(!RouteGuideUtil.exists(feature)){
continue;
}

intlat=feature.getLocation().getLatitude();
intlon=feature.getLocation().getLongitude();
if(lon>=left&&lon<=right&&lat>=bottom&&lat<=top){
responseObserver.onNext(feature);
}
}
responseObserver.onCompleted();
}
}

 

Click Follow to learn about HUAWEI CLOUD's new technologies for the first time~

{{o.name}}
{{m.name}}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324125861&siteId=291194637