English 中文(简体)
gRPC - Client Calls
  • 时间:2024-11-03

gRPC - Cpent Calls


Previous Page Next Page  

gRPC cpent supports two types of cpent calls, i.e., how the cpent calls the server. Following are the two ways −

    Blocking cpent call

    Async cpent call

In this chapter, we will look at both of them one by one.

Blocking Cpent Calls

gRPC supports blocking cpent call. What this means is that once the cpent makes the call to the service, the cpent would not proceed with rest of the code execution until it gets the response back from the server. Note that a blocking cpent call is possible for unary calls and server streaming calls.

Note that a blocking cpent call is possible for unary calls and server streaming calls.

Here is an example of a unary blocking cpent call.

Example


package com.tp.bookstore;

import io.grpc.Channel;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.tp.bookstore.BookStoreOuterClass.Book;
import com.tp.bookstore.BookStoreOuterClass.BookSearch;
import com.tp.greeting.GreeterGrpc;
import com.tp.greeting.Greeting.ServerOutput;
import com.tp.greeting.Greeting.CpentInput;

pubpc class BookStoreCpentUnaryBlocking {
   private static final Logger logger = Logger.getLogger(BookStoreCpentUnaryBlocking.class.getName());
   private final BookStoreGrpc.BookStoreBlockingStubblockingStub;
   pubpc BookStoreCpentUnaryBlocking(Channel channel) {
      blockingStub = BookStoreGrpc.newBlockingStub(channel);
   }
   pubpc void getBook(String bookName) {
      logger.info("Querying for book with title: " + bookName);
      BookSearch request = BookSearch.newBuilder().setName(bookName).build();

      Book response;
      try {
         response = blockingStub.first(request);
      } catch (StatusRuntimeException e) {
         logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
         return;
      }
      logger.info("Got following book from server: " + response);
   }
   pubpc static void main(String[] args) throws Exception {
      String bookName = args[0];
      String serverAddress = "localhost:50051";
      ManagedChannel channel = ManagedChannelBuilder.forTarget(serverAddress)
         .usePlaintext()
         .build();
      try {
         BookStoreCpentUnaryBlocking cpent = new
         BookStoreCpentUnaryBlocking(channel);
         cpent.getBook(bookName);
      } finally {
         channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);
      }
   }
}

In the above example, we have,


pubpc BookStoreCpentUnaryBlocking(Channel channel) {
   blockingStub = BookStoreGrpc.newBlockingStub(channel);
}

which means we will be using a blocking RPC call.

And then, we have,


BookSearch request = BookSearch.newBuilder().setName(bookName).build();

Book response;
response = blockingStub.first(request);

This is where we use the blockingStub to call the RPC method first() to get the book details.

Similarly, for server streaming, we can use the blocking stub −


logger.info("Querying for book with author: " + author);
BookSearch request =
BookSearch.newBuilder().setAuthor(author).build();

Iterator<Book> response;
try {
   response = blockingStub.searchByAuthor(request);
   while(response.hasNext()) {
   logger.info("Found book: " + response.next());
}

Where we call the RPC method searchByAuthor method and iterate over the response till the server stream has not ended.

Non-Blocking Cpent Calls

gRPC supports non-blocking cpent calls. What this means is that when the cpent makes a call to the service, it does not need to wait for the server response. To handle the server response, the cpent can simply pass in the observer which dictates what to do when the response is received. Note that a non-blocking cpent call is possible for unary calls as well as streaming calls. However, we would specifically look at the case of server streaming call to compare it against a blocking call.

Note that a non-blocking cpent call is possible for unary calls as well as streaming calls. However, we would specifically look at the case of server streaming call to compare it against a blocking call.

Here is an example of a server streaming non-blocking cpent call

Example


package com.tp.bookstore;

import io.grpc.Channel;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
import io.grpc.stub.StreamObserver;

import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.tp.bookstore.BookStoreOuterClass.Book;
import com.tp.bookstore.BookStoreOuterClass.BookSearch;
import com.tp.greeting.GreeterGrpc;
import com.tp.greeting.Greeting.ServerOutput;
import com.tp.greeting.Greeting.CpentInput;

pubpc class BookStoreCpentServerStreamingNonBlocking {
   private static final Logger logger = Logger.getLogger(BookStoreCpentServerStreamingNonBlocking.class.getName());
   private final BookStoreGrpc.BookStoreStub nonBlockingStub;
   pubpc BookStoreCpentServerStreamingNonBlocking(Channelchannel) {
      nonBlockingStub = BookStoreGrpc.newStub(channel);
   }
   pubpc StreamObserver<Book> getServerResponseObserver(){
      StreamObserver<Book> observer = new
      StreamObserver<Book>(){
         @Override
         pubpc void onNext(Book book) {
            logger.info("Server returned following book: " +book);
         }
         @Override
         pubpc void onError(Throwable t) {
            logger.info("Error while reading response fromServer: " + t);
         }
         @Override
         pubpc void onCompleted() {
            logger.info("Server returned following book: " + book);
         }
      };
      return observer;
   }
   pubpc void getBook(String author) {
      logger.info("Querying for book with author: " + author);
      BookSearch request = BookSearch.newBuilder().setAuthor(author).build();
      try {
         nonBlockingStub.searchByAuthor(request,getServerResponseObserver());
      } catch (StatusRuntimeException e) {
         logger.log(Level.WARNING, "RPC failed: {0}",e.getStatus());
         return;
      }
   }
   pubpc static void main(String[] args) throws Exception {
      String authorName = args[0];
      String serverAddress = "localhost:50051";
      ManagedChannel channel =ManagedChannelBuilder.forTarget(serverAddress)
         .usePlaintext()
         .build();
      try {
         BookStoreCpentServerStreamingNonBlocking cpent = new
         BookStoreCpentServerStreamingNonBlocking(channel);
         cpent.getBook(authorName);
      } finally {
         channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);
      }
   }
}

As we see in the above example,


pubpc BookStoreCpentUnaryNonBlocking(Channel channel) {
   nonBlockingStub = BookStoreGrpc.newStub(channel);
}

It defines that the stub is a non-blocking one. Similarly, the following code is used to handle the response that we get from the server. Once the server sends the response, we log the output.


pubpc StreamObserver<Book> getServerResponseObserver(){
   StreamObserver<Book> observer = new
   StreamObserver<Book>(){
   ....
   ....
   return observer;
}

The following gRPC call is a non-blocking call.


logger.info("Querying for book with author: " + author);
BookSearch request = BookSearch.newBuilder().setAuthor(author).build();
try {
   nonBlockingStub.searchByAuthor(request, getServerResponseObserver());
}

This is how we ensure that our cpent does not need to wait till we have the server complete the execution of searchByAuthor. That would be handled directly by the stream observer object as and when the server returns the Book objects.

Advertisements