Transmitir chamadas nas bibliotecas de cliente do Cloud para Java

As chamadas de streaming permitem padrões de interação mais complexos do que uma simples solicitação/resposta, permitindo que várias mensagens sejam enviadas ou recebidas em uma única conexão.

As bibliotecas de cliente do Cloud para Java oferecem suporte a três tipos de chamadas de streaming:

  • Streaming do servidor:o servidor envia um stream de respostas para você.
  • Streaming do cliente:você envia um stream de solicitações para o servidor.
  • Streaming bidirecional:você pode enviar um stream de solicitações para o servidor, e o servidor pode enviar um stream de respostas para você.

As implementações de streaming são modeladas após implementações gRPC-Java para streaming de servidor, cliente e bidirecional.

Suporte a streaming em transportes

O streaming tem suporte total ao usar o gRPC, mas apenas parcial para HttpJson. Consulte a tabela a seguir para conferir o suporte a streaming.

Tipo de streaming gRPC HttpJson
Streaming do servidor Com suporte Com suporte
Streaming do cliente Com suporte Incompatível
Streaming bidirecional Com suporte Incompatível

As chamadas unárias (sem streaming) têm suporte para gRPC e HttpJson.

Como determinar o tipo de streaming

Para determinar o tipo de streaming da chamada, verifique o tipo Callable retornado:

  • ServerStreamingCallable:streaming do servidor.
  • ClientStreamingCallable:streaming do cliente.
  • BidiStreamingCallable:streaming bidirecional.

Por exemplo, usando Java-Aiplatform e Java-Speech:

// Server Streaming
ServerStreamingCallable<ReadTensorboardBlobDataRequest, ReadTensorboardBlobDataResponse> callable = aiplatformClient.readTensorboardBlobDataCallable();

// Bidirectional Streaming
BidiStreamingCallable<StreamingRecognizeRequest, StreamingRecognizeResponse> callable = speechClient.streamingRecognizeCallable();

Como fazer chamadas de streaming

A maneira de fazer uma chamada de streaming varia dependendo se você está usando o streaming do servidor ou o streaming bidirecional.

Streaming do servidor

O streaming do servidor não exige implementação adicional. A classe ServerStream permite iterar o stream de respostas. Usando Java-Maps-Routing como exemplo, o código a seguir mostra como chamar a API Server Streaming:

try (RoutesClient routesClient = RoutesClient.create()) {
  ServerStreamingCallable<ComputeRouteMatrixRequest, RouteMatrixElement> computeRouteMatrix =
    routesClient.computeRouteMatrixCallable();  
  ServerStream<RouteMatrixElement> stream = computeRouteMatrix.call(
    ComputeRouteMatrixRequest.newBuilder().build());
  for (RouteMatrixElement element : stream) {
    // Do something with response
  }
}

Neste exemplo, o cliente envia um único ComputeRouteMatrixRequest e recebe um stream de respostas.

Streaming bidirecional

O streaming bidirecional exige implementação adicional para fazer a chamada. Usando Java-Speech como exemplo, as etapas a seguir fornecem uma implementação de exemplo para fazer uma chamada de streaming bidirecional.

Primeiro, implemente a interface ResponseObserver usando o código a seguir como diretriz:

class BidiResponseObserver<T> implements ResponseObserver<T> {
  private final List<T> responses = new ArrayList<>();
  private final SettableApiFuture<List<T>> future = SettableApiFuture.create();

  @Override
  public void onStart(StreamController controller) {
    // no-op
  }

  @Override
  public void onResponse(T response) {
    responses.add(response);
  }

  @Override
  public void onError(Throwable t) {
    future.setException(t);
  }

  @Override
  public void onComplete() {
    future.set(responses);
  }

  public SettableApiFuture<List<T>> getFuture() {
    return future;
  }
}

Em seguida, siga estas etapas:

  1. Crie uma instância do observador:

    BidiResponseObserver<StreamingRecognizeResponse> responseObserver = new BidiResponseObserver<>();
    
  2. Transmita o observador para o chamável:

    ClientStream<EchoRequest> clientStream = speechClient.streamingRecognizeCallable().splitCall(responseObserver);
    
  3. Envie as solicitações para o servidor e feche o stream quando terminar:

    clientStream.send(StreamingRecognizeRequest.newBuilder().build());
    clientStream.send(StreamingRecognizeRequest.newBuilder().build());
    // ... other requests ...
    clientStream.send(StreamingRecognizeRequest.newBuilder().build());
    clientStream.closeSend();
    
  4. Itere as respostas:

    List<StreamingRecognizeResponse> responses = responseObserver.getFuture().get();
    
    for (StreamingRecognizeResponse response : responses) {
      // Do something with response
    }
    

Erros de streaming não compatíveis

Para bibliotecas de cliente que oferecem suporte a transportes gRPC e HTTP/JSON, é possível configurar acidentalmente a biblioteca de cliente para invocar uma chamada de streaming não compatível. Por exemplo, a configuração a seguir mostra o cliente HttpJson do Java-Speech fazendo uma chamada de streaming bidirecional:

// SpeechClient is configured to use HttpJson
try (SpeechClient speechClient = SpeechClient.create(SpeechSettings.newHttpJsonBuilder().build())) {
  // Bidi Callable is not supported in HttpJson
  BidiStreamingCallable<StreamingRecognizeRequest, StreamingRecognizeResponse> callable = speechClient.streamingRecognizeCallable();
  ...
}

Isso não resulta em um erro de compilação, mas aparece como um erro de execução:

Not implemented: streamingRecognizeCallable(). REST transport is not implemented for this method yet.
Important: The client library MUST be configured with gRPC to use client or bidirectional streaming.