Search code examples
c++protocol-buffers

How to generate BlockingStub in C++ in Protobuf?


I have the following .proto for Protobuf 2.6.1:

service InstallService {
    rpc getWifiNetworks (WifiRequest) returns (WifiResponse);
}

I've generated Java files and I'm having BlockingStub:

TestInstallService.BlockingInterface service = TestInstallService.newBlockingStub(channel);

and I can use it in a blocking way (works well):

Wifi.WifiResponse response = service.getWifiNetworks(controller, request);

Now I'm creating a C++ client which should work in a blocking way too but I can't see any Blocking interfaces either in proto or in generated C++ code. How to generate BlockingStub in C++ in Protobuf? How can I pass closure if working in an async way?

Generated C++ service file (.cpp):

class InstallService_Stub;

class InstallService : public ::google::protobuf::Service {
 protected:
  // This class should be treated as an abstract interface.
  inline InstallService() {};
 public:
  virtual ~InstallService();

  typedef InstallService_Stub Stub;

  static const ::google::protobuf::ServiceDescriptor* descriptor();

  virtual void getWifiNetworks(::google::protobuf::RpcController* controller,
                       const ::WifiRequest* request,
                       ::WifiResponse* response,
                       ::google::protobuf::Closure* done);

  // implements Service ----------------------------------------------

  const ::google::protobuf::ServiceDescriptor* GetDescriptor();
  void CallMethod(const ::google::protobuf::MethodDescriptor* method,
                  ::google::protobuf::RpcController* controller,
                  const ::google::protobuf::Message* request,
                  ::google::protobuf::Message* response,
                  ::google::protobuf::Closure* done);
  const ::google::protobuf::Message& GetRequestPrototype(
    const ::google::protobuf::MethodDescriptor* method) const;
  const ::google::protobuf::Message& GetResponsePrototype(
    const ::google::protobuf::MethodDescriptor* method) const;

 private:
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(InstallService);
};

class InstallService_Stub : public InstallService {
 public:
  InstallService_Stub(::google::protobuf::RpcChannel* channel);
  InstallService_Stub(::google::protobuf::RpcChannel* channel,
                   ::google::protobuf::Service::ChannelOwnership ownership);
  ~InstallService_Stub();

  inline ::google::protobuf::RpcChannel* channel() { return channel_; }

  // implements InstallService ------------------------------------------

  void getWifiNetworks(::google::protobuf::RpcController* controller,
                       const ::WifiRequest* request,
                       ::WifiResponse* response,
                       ::google::protobuf::Closure* done);
 private:
  ::google::protobuf::RpcChannel* channel_;
  bool owns_channel_;
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(InstallService_Stub);
};

Solution

  • It seems that no blocking code is generated by protoc so i had to use self-made blocking:

    bool callbackFired = false;
    
    void myCallback() {
        // ...
        callbackFired = true;
    }
    
    // run service method
    service->myMethod(rpcController, request, response, NewCallback(&myCallback));
    
    // block the thread until callback is invoked
    while (!callbackFired);
    
    ...
    

    C++ client usage example: https://github.com/4ntoine/protobuf-socket-rpc