hello world 2014. 1. 13. 17:16

Google Protocol Buffer 사용해보기

참고 : https://developers.google.com/protocol-buffers/?hl=ko


구조화된 데이터의 직렬화( Serializing )를 도와줌


  • 장점 : 익숙한 포멧으로 사용하기 편하고, 다양한 플랫폼을 지원함
  • 단점 : cpp 의 경우 proto 파일이 변경되면 컴파일 해야하고, 그로인한 .h파일의 변경으로 전체 빌드가 될 가능성이 높음

프로토콜의 정의 ( .proto 파일 )

message Person {
    required string name = 1;
    required int32	id = 2;
    optional string	email = 3;

    enum PhoneType {
	MOBILE = 0;
	HOME = 1;
	WORK = 2;
    } 
    message PhoneNumber { 
        required string number = 1;
        optional PhoneType type = 2 [ default = HOME ];
    }
    repeated PhoneNumber phone = 4
}


Cpp 에서 사용 - 쓰기 


proto 에서 정의한 내용을 class 로 사용할 수 있고, 각 멤버 함수를 사용할 수 있다

멤버함수는 알아서 찾아보시고...

Person person;
person.set_name(“John Doe”);
person.set_id(1234);
person.set_email(“123@redduck.com”)
fstream input(“myfile”, ios::in | ios::binary);
person.SirializeToOstream( );

Cpp 에서 사용 - 읽기 


네트워크에서 읽어온 버퍼를 읽던지, 파일에서 읽던지, outstream 에서 읽던지... 

읽으면 클래스에 값이 채워짐

fstream input(“mysql”, ios::in | ios::binary );
Person person;
person.ParseFromIstream(&input)
cout << “Name: “ << person.name() << endl 
     << “Email : “ << person.email() << endl;


Memory DB 와 사용 예 : 

  1. 프로토 버퍼의 SerializeToString 함수를 사용하여 보내는 패킷자체의 String 을 Key-value DB ( 난 couchbase 사용 ) 에 저장 
    1. key='user_id:record' value='......' 이딴식
  2. 다른 유저의 전적을 확인할때, memory-db에 없으면 oracle 에서 찾아서 데이터를 가공한후 memory-db에 저장
  3. 다른 유저 or 같은 데이터를 요청 할때 memory-db 에서 찾아서 클라이언트에 보내줌
  4. memory-db 에 data를 변경할 필요가 있는 경우 그냥 지워버림 ( 그럼 다시 2번 과정 )
tip : 
  • int (int32, uint32, int64, uin64)의 필드를 repeated 로 선언하는 경우 뒤에 [ packed=true ] 옵션을 를 사용하면 패킷이 더 컴팩트 해진다고 합니다. 무조건 붙이세욧

ps : C#에서는 더럽게 편하다고 상욱이가 그랬음