tree: 5934f18c73e2cd769ac11e7dc95fe0e6ec0991d8 [path history] [tgz]
  1. BUILD.gn
  2. grpc_async_executor.cc
  3. grpc_async_executor.h
  4. grpc_async_executor_unittest.cc
  5. grpc_async_request.cc
  6. grpc_async_request.h
  7. grpc_async_server_streaming_request.cc
  8. grpc_async_server_streaming_request.h
  9. grpc_async_test_server.cc
  10. grpc_async_test_server.h
  11. grpc_async_unary_request.h
  12. grpc_authenticated_executor.cc
  13. grpc_authenticated_executor.h
  14. grpc_authenticated_executor_unittest.cc
  15. grpc_channel.cc
  16. grpc_channel.h
  17. grpc_executor.h
  18. grpc_support_test_services.proto
  19. grpc_test_util.cc
  20. grpc_test_util.h
  21. README.md
  22. root_certs_prod.inc
  23. scoped_grpc_server_stream.cc
  24. scoped_grpc_server_stream.h
  25. using_grpc_channel_shared_ptr.inc
remoting/base/grpc_support/README.md

Using GrpcAsyncExecutor

gRPC++ uses completion queue to handle async operations. It doesn‘t fit well with Chromium’s callback-based async handling paradigm, and it is technically still a blocking API unless you create a new thread to run the queue. gRPC is working on adding callback-based APIs but it won‘t be ready to use in the near future, so we created a GrpcAsyncExecutor class to help adapting gRPC’s completion queue logic into Chromium's callback paradigm.

Basic usage

class MyClass {
  public:
  MyClass() = default;
  ~MyClass() = default;

  void SayHello() {
    HelloRequest request;
    // Requests will be silently dropped once the executor is destroyed, so it's
    // safe to bind with raw pointers.
    auto grpc_request = CreateGrpcAsyncUnaryRequest(
        base::BindOnce(&HelloService::Stub::AsyncSayHello,
                       base::Unretained(stub_.get())),
        std::make_unique<grpc::ClientContext>(), request,
        base::BindOnce(&MyClass::OnHelloResult,
                       base::Unretained(this)));
    executor_->ExecuteRpc(std::move(grpc_request));
  }

  void StartHelloStream() {
    StreamHelloRequest request;
    auto grpc_Request = CreateGrpcAsyncServerStreamingRequest(
        base::BindOnce(&HelloService::Stub::AsyncStreamHello,
                       base::Unretained(stub_.get())),
        std::make_unique<grpc::ClientContext>(), request,
        base::BindRepeating(&MyClass::OnHelloStreamMessage,
                            base::Unretained(this)),
        base::BindOnce(&MyClass::OnHelloStreamClosed,
                       base::Unretained(this)),
        &scoped_hello_stream_);
    executor_->ExecuteRpc(std::move(grpc_request));
  }

  void CloseHelloStream() {
    scoped_hello_stream_.reset();
  }

  private:
  void OnHelloResult(const grpc::Status& status,
                     const HelloResponse& response) {
    if (!status.ok()) {
      // Handle error here.
      return;
    }

    // Response is received. Use the result here.
  }

  void OnHelloStreamMessage(const HelloStreamResponse& response) {
    // This will be called every time the server sends back messages
    // through the stream.
  }

  void OnHelloStreamClosed(const grpc::Status& status) {
    if (!status.ok()) {
      // Handle error here.
      return;
    }

    // Stream is closed by the server.
  }

  std::unique_ptr<HelloService::Stub> stub_;
  GrpcAsyncExecutor executor_;
  std::unique_ptr<ScopedGrpcServerStream> scoped_hello_stream_;
};

Using GrpcAuthenticatedExecutor

GrpcAuthenticatedExecutor allows you to execute RPCs and authenticate them with remoting::OAuthTokenGetter. The usage is basically the same as GrpcAsyncExecutor.