protocol buffer rpc

2019-12-13 16:14:45  

  Because of its recent project requirements, the need to achieve to achieve rpc remote calls based on the protocol buffer google. This article explains how to use the .proto file generation .pb.cc and .pb.h code, and how to use the code generated by the user to achieve their rpc call.

1, the preparation of proto file

  proto concrete syntax can see Google's official documents, basic grammar are not explained. Links: https://developers.google.com/protocol-buffers/docs/cpptutorial 

  Let's look at how to implement proto file written rpc service.

syntax = " proto3 " ; / * Statement version protocol buffer is less than 3.0 * / 

Option cc_generic_services = to true ; / * generating services C ++ code * / 

/ * No Parameters Request * / 
Message NoParametersRequest {/ * in a message request ends are denotes an input parameter, NoParameterRequest indicates that the parameter is not variable (void type) * / 

} 

/ * the CurrentStatus * / Message SwPackageStateTypeResponse {/ * in a message response ending represents the return value output type parameters or functions * / enum SwPackageStateType { kTransferring = 0 ; kTransferred = . 1 ; kProcessing = 2 ; kProcessed = . 3 ; } SwPackageStateType state_type = . 1 ; / * definition of an enumerated type * / } / * an array of vector parameters to achieve the following functions * /
/ * GetSwClusterInfo * / Message SwClusterInfo {/ * message has three field name, version, state_type, the latter number represents a unique representation for each field in the message definition, each field has a unique numeric identifier * / String name = . 1 ; String Version = 2 ; enum SwClusterStateType { kPresent = 0 ; kAdded = . 1 ; kupdated = 2 ; kRemoved = . 3 ; } SwClusterStateType state_type = . 3 ; } Message GetSwClusterInfoResponse { REPEATED SwClusterInfo swcluster_info = . 1 ; / * REPEATED keyword indicates that variable is an array or * Vector / }

/*GetHistory*/
  message GetHistoryRequest {
    uint64 timestamp_ge = 1;
    uint64 timestamp_lt = 2;
  }

 
 

  message ActionType{
    enum KActionType{
      kUpdate = 0;
      kInstall =1;
      kRemove = 2;
    }
  }
  message ResultType{
    enum KResultType{
      kSuccessfull = 0;
      kFailed =1;
    }
  }
  message GetHistoryVectorType{
    uint64 time = 1;
    string name = 2;
    string version = 3;
    ActionType action = 4;
    ResultType resolution = 5;
  }
  message GetHistoryResponse{
    repeated GetHistoryVectorType history = 1;
  }

/ * Main Service rpc look at the implementation * / 
-Service PackageManagementService {/ * service name * /   / * invoke achieve rpc 3, a first rpc, the CurrentStatus name representation, NoParametersRequest input parameters, SwPackageStateTypeResponse output parameters or function return type value * / 
    RPC the CurrentStatus (NoParametersRequest) Returns (SwPackageStateTypeResponse); 
    RPC GetSwClusterInfo (NoParametersRequest) Returns (GetSwClusterInfoResponse);    RPC getHistory (GetHistoryRequest) Returns (GetHistoryResponse); 
}


 

2, proto analysis code file generation and .pb.h of .pb.cc

  Installation and use code generator can go to Google's official view.

  Through this command: protoc package_management.proto --cpp_out = following analysis of the generated code:

  1, part of the code class SwPackageStateTypeResponse

1    / * value by enumeration, get the name of the enumerated * /
 2    static inline const STD :: String & SwPackageStateType_Name (T enum_t_value) {
 . 3      The static_assert (STD :: :: is_same <T, SwPackageStateType> :: value ||
 . 4        :: :: is_integral STD <T> :: value,
 . 5        " here Incorrect type SwPackageStateType_Name passed to function. " );
 . 6      return SwPackageStateTypeResponse_SwPackageStateType_Name (enum_t_value);
 . 7    } 
   / * enumeration by name, acquired enumerated value * /
8 static inline BOOL SwPackageStateType_Parse ( const std::string& name, 9 SwPackageStateType* value) { 10 return SwPackageStateTypeResponse_SwPackageStateType_Parse(name, value); 11 } 12 13 // accessors ------------------------------------------------------- 14 15 enum : int { 16 kStateTypeFieldNumber = 1, 17 }; 18 // .SwPackageStateTypeResponse.SwPackageStateType state_type = 1;
   /*清空state_type*/ 19 void clear_state_type();
   /*获取state_type的值*/
20 ::SwPackageStateTypeResponse_SwPackageStateType state_type() const;
   /*设置state_type的值*/
21 void set_state_type(::SwPackageStateTypeResponse_SwPackageStateType value); 22 private: 23 ::SwPackageStateTypeResponse_SwPackageStateType _internal_state_type() const; 24 void _internal_set_state_type(::SwPackageStateTypeResponse_SwPackageStateType value); 25 public:

  2, GetSwClusterInfoResponse class code part of the code vector array operation

 1   enum : int {
 2     kSwclusterInfoFieldNumber = 1,
 3   };
 4   // repeated .SwClusterInfo swcluster_info = 1;
 5   int swcluster_info_size() const;
 6   private:
 7   int _internal_swcluster_info_size() const;
 8   public:
 9   void clear_swcluster_info();
   /*获取vector的值*/
10 ::SwClusterInfo* mutable_swcluster_info(int index); 11 ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::SwClusterInfo >* 12 mutable_swcluster_info(); 13 private: 14 const ::SwClusterInfo& _internal_swcluster_info(int index) const; 15 ::SwClusterInfo* _internal_add_swcluster_info(); 16 public: 17 const ::SwClusterInfo& swcluster_info(int index) const;
   /*增加vector的值*/
18 ::SwClusterInfo* add_swcluster_info(); 19 const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::SwClusterInfo >& 20 swcluster_info() const; 21 22 // @@protoc_insertion_point(class_scope:GetSwClusterInfoResponse) 23 private: 24 class _Internal; 25 26 ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; 27 ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::SwClusterInfo > swcluster_info_; 28 mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; 29 friend struct ::TableStruct_package_5fmanagement_2eproto; 30 };

3, the generated code using the service users to achieve rpc

  Specific protocol internal buffer rpc mechanism is not described herein, a user code is described herein to be achieved.

  1, service terminal, the user needs to inherit PackageManagementService, the achievement of specific rpc calling code

 1 class PackageManagementServiceImpl : public PackageManagementService {
 2 
 3     public:
 4     PackageManagementServiceImpl(){
 5 
 6         std::cout <<"PackageManagementServiceImpl structure "<<std::endl;
 7     }
 8     ~PackageManagementServiceImpl(){
 9 
10         std::cout <<"PackageManagementServiceImpl desstructure "<<std::endl;
11     }
12 
13     virtual void CurrentStatus(::google::protobuf::RpcController* controller,
14                        const ::NoParametersRequest* request,
15                        ::SwPackageStateTypeResponse* response,
16                        ::google::protobuf::Closure* done);
17 
18     virtual void GetSwClusterInfo(::google::protobuf::RpcController* controller,
19                        const ::NoParametersRequest* request,
20                        ::GetSwClusterInfoResponse* response,
21                        ::google::protobuf::Closure* done);
22 
23 };
 1 void PackageManagementServiceImpl :: CurrentStatus(::google::protobuf::RpcController* controller,
 2                    const ::NoParametersRequest* request,
 3                    ::SwPackageStateTypeResponse* response,
 4                    ::google::protobuf::Closure* done){
 5 
 6     std::cout << "CurrentStatus" <<std::endl;
 7     const std::string enum_name = "kTransferring";
 8     
 9     SwPackageStateTypeResponse_SwPackageStateType  value;
10     response->SwPackageStateType_Parse(enum_name, &value);
11     /*做具体的数据赋值*/
12     response->set_state_type(value);
13 }
14 
15 void PackageManagementServiceImpl::GetSwClusterInfo(::google::protobuf::RpcController* controller,
16                    const ::NoParametersRequest* request,
17                    ::GetSwClusterInfoResponse* response,
18                    ::google::protobuf::Closure* done){
19 
20 
21     std::cout << "GetSwClusterInfo" <<std::endl;
22 
23     SwClusterInfo *swcluster_info ;
24    /*向vector里添加数据*/
25     swcluster_info = response->add_swcluster_info();
26 
27     swcluster_info->set_name("ICC");
28     swcluster_info->set_version("1.1");
29 
30     swcluster_info = response->add_swcluster_info();
31     swcluster_info->set_name("ICM");
32     swcluster_info->set_version("1.2");
33 
34 
35     swcluster_info= response->add_swcluster_info();
36 
37     swcluster_info->set_name("SOTA");
38     swcluster_info->set_version("1.3");
39 
40                  
41 }

  2, client code

 1 TEST(CurrentStatus, PackageManagement) {
 2     
 3     RpcChannel channel;
 4     PackageManagementService::Stub package_manage_client(&channel);
 5 
 6     NoParametersRequest request;
 7     SwPackageStateTypeResponse response;
 8 
 9     package_manage_client.CurrentStatus(nullptr, &request, &response, nullptr);
10   /*解析rpc调用返回的数据*/
11     SwPackageStateTypeResponse_SwPackageStateType  value;
12     value = response.state_type();
13 
14     ASSERT_EQ(value, 0);
15 
16 }
17 
18 TEST(GetSwClusterInfo, PackageManagement) {
19     
20     RpcChannel channel;
21     PackageManagementService::Stub package_manage_client(&channel);
22 
23     NoParametersRequest request;
24     GetSwClusterInfoResponse  response;
25     
26     std::cout <<"GetSwClusterInfo RPC "<<std::endl;
27     package_manage_client.GetSwClusterInfo(nullptr, &request, &response, nullptr);
28 
29     int vector_num = response.swcluster_info_size();
30     ASSERT_EQ(vector_num, 3);
31   /*遍历和解析vector数据*/
32     ::google::protobuf::RepeatedPtrField< ::SwClusterInfo > *swcluster_info_parse = response.mutable_swcluster_info();
33 
34     ::google::protobuf::RepeatedPtrField< ::SwClusterInfo >::iterator it = swcluster_info_parse->begin();
35 
36     std::string name;
37     std::string version;
38     
39     name = swcluster_info_parse->at(0).name();
40     ASSERT_STREQ(name.c_str(), "ICC");
41     
42     version = swcluster_info_parse->at(0).version();
43     ASSERT_STREQ(version.c_str(), "1.1");
44     
45 
46     name = swcluster_info_parse->at(1).name();
47     ASSERT_STREQ(name.c_str(), "ICM");
48     
49     version = swcluster_info_parse->at(1).version();
50     ASSERT_STREQ(version.c_str(), "1.2");
51 
52     name = swcluster_info_parse->at(2).name();
53     ASSERT_STREQ(name.c_str(), "SOTA");
54     
55     version = swcluster_info_parse->at(2).version();
56     ASSERT_STREQ(version.c_str(), "1.3");
57 
58     
59     /*遍历数据*/
60     for( ; it != swcluster_info_parse->end(); ++it ){
61 
62         std::cout << "name = " << it->name() <<std::endl;
63         std::cout << "version = " << it->version() <<std::endl;
64 
65     }
66 }

Guess you like

Origin www.cnblogs.com/show-hand/p/12033836.html