#include <string>#include <iostream>#include <assert.h>#include <stdint.h>#include "person.pb.h"#include "test.pb.h"using namespace std;class ProtoMsgHandle{public: /* 注册消息处理函数 */ void initHandles() { registerHandle(&ProtoMsgHandle::handleProtoPerson); registerHandle(&ProtoMsgHandle::handleProtoTest); } /* 处理网络消息 */ void handle(const char* data) { bool ret = false; const char* current = data; int32_t* p_packetlen = (int32_t*)current; current += sizeof(*p_packetlen); int32_t* p_namelen = (int32_t*)current; current += sizeof(*p_namelen); const char* p_name = current; string name(p_name, *p_namelen); current += *p_namelen; do { msg_handle callback = m_callbacks[name]; assert(callback != NULL); if(callback == NULL) { break; } const ::google::protobuf::Descriptor* descriptor = m_descriptors[name]; assert(descriptor != NULL); if(descriptor == NULL) { break; } const google::protobuf::Message* prototype = google::protobuf::MessageFactory::generated_factory()->GetPrototype(descriptor); assert(prototype != NULL); if(prototype == NULL) { break; } google::protobuf::Message* msg = prototype->New(); ret = msg->ParseFromArray(current, (*p_packetlen)-sizeof(*p_packetlen)-sizeof(*p_namelen)-*p_namelen); if(ret) { (this->*callback)(msg); } }while(0); }private: void handleProtoTest(test* test) { cout << test->price() << endl; cout << test->userid() << endl; cout << test->time() << endl; } void handleProtoPerson(person* person) { cout << person->age() << endl; cout << person->userid() << endl; cout << person->name() << endl; }private: typedef void (ProtoMsgHandle::*msg_handle)(::google::protobuf::Message*);private: template<typename MSGTYPE> void registerHandle(void (ProtoMsgHandle::*callback)(MSGTYPE*)) { const ::google::protobuf::Descriptor* des = MSGTYPE::descriptor(); assert(des != NULL); if(des != NULL) { m_callbacks[des->full_name()] = (msg_handle)callback; m_descriptors[des->full_name()] = des; } }private: map<string, msg_handle> m_callbacks; map<string, const ::google::protobuf::Descriptor*> m_descriptors;};class ProtoMsgSender{public: /* 发送proto msg到指定缓冲区 */ /* int32_t - packet_len int32_t name_len char[] name char[] proto_data */ template<typename MSGTYPE> void sentProtoMsg(MSGTYPE& msg, char* buffer, int max_len) { char* current = buffer; int32_t* p_packetlen = (int32_t*)current; current += sizeof(*p_packetlen); int32_t* p_namelen = (int32_t*)current; current += sizeof(*p_namelen); string msg_name = MSGTYPE::descriptor()->full_name(); *p_namelen = msg_name.size(); strcpy(current, msg_name.c_str()); current += msg_name.size(); /* 判断是否成功 */ msg.SerializeToArray(current, max_len - (current-buffer)); current += msg.GetCachedSize(); *p_packetlen = (current-buffer); }};int main(){ ProtoMsgSender msgsender; ProtoMsgHandle msghandle; msghandle.initHandles(); test t; t.set_price(100.0); t.set_userid(110); t.set_time(123); person person; person.set_age(18); person.set_userid(200508); person.set_name("irons"); char tmp[10*1024]; msgsender.sentProtoMsg(t, tmp, sizeof(tmp)); msghandle.handle(tmp); msgsender.sentProtoMsg(person, tmp, sizeof(tmp)); msghandle.handle(tmp); cin.get(); return 0;}/*message test{required int32 time = 1;required int32 userid = 2;required float price = 3;optional string desc = 4;}message person{required int32 age = 1;required int32 userid = 2;optional string name = 3;}*/
联系客服