在erlang项目中使用protobuf

在erlang项目中使用protobuf

http://blog.csdn.net/mycwq/article/details/21864191

protobuf是google的一个序列化框架,类似XML,JSON,其特点是基于二进制,比XML表示同样一段内容要短小得多,还可以定义一些可选字段,广泛用于服务端与客户端通信。文章将着重介绍在erlang中如何使用protobuf。

首先google没有提供对erlang语言的直接支持,所以这里使用到的第三方的protobuf库(erlang_protobuffs

https://github.com/basho/erlang_protobuffs

 

 

定义一个protobuf结构,保存为test.proto,如下:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. enum PhoneType {

  2.    PhoneType_Home = 1;
  3.        PhoneType_Company = 2;
  4. }
  5. message Person {  
  6.   required int32 age = 1;  
  7.   required string name = 2;  
  8. }  
  9. message Other {
  10.   required PhoneType type = 1;
  11.   required string phone = 2;
  12. }
  13.   
  14. message Family {  
  15.   required int32 mainid = 1;
  16.   optional Other other = 2;
  17.   repeated Person person = 3;  
  18. }  

 

 

编译这个protobuf结构,生成相应的erlang代码:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. % 生成相应的erl和hrl文件  
  2. protobuffs_compile:generate_source("test.proto").  
  3.   
  4. % 生成相应的beam和hrl文件  
  5. protobuffs_compile:scan_file("test.proto").  

 

 

下面我们以例子简单说明如何使用:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. -module(test).  
  2.   
  3. -compile([export_all]).  
  4.   
  5. -include("test_pb.hrl").  
  6.   
  7. encode() ->  
  8.     Person = #person{age=25, name="John"},  
  9.     test_pb:encode_person(Person).  
  10.   
  11. decode() ->  
  12.     Data = erlang:iolist_to_binary(encode()),  
  13.     io:format("Data is ~p~n", [Data]),
  14.     test_pb:decode_person(Data).  
  15.   
  16. encode_repeat() ->  
  17.     OtherData = #other{type='PhoneType_Company', phone="028-12345678"},
  18.     RepeatData =  
  19.     [  
  20.         #person{age=25, name="John"},  
  21.         #person{age=23, name="Lucy"},  
  22.         #person{age=2, name="Tony"}  
  23.     ],  
  24.     Family = #family{mainid=111, other=OtherData, person=RepeatData},  
  25.     test_pb:encode_family(Family).  
  26.       
  27. decode_repeat() ->  
  28.     Data = erlang:iolist_to_binary(encode_repeat()),  
  29.     io:format("Data is ~p~n", [Data]),
  30.     %test_pb:decode_family(Data).
  31.     FamilyData = test_pb:decode_family(Data),
  32.     {family, _, _, PersonData} = FamilyData,
  33.     io:format("~p~n", [FamilyData]),
  34.     io:format("Per Len is ~w~n~n", [length(PersonData)]),
  35.     parse_repeat(PersonData).  
  36.   
  37.    
  38. parse_repeat([]) ->
  39.     ok;
  40. parse_repeat([H|T]) ->
  41.     if is_record(H, person) ->
  42.             io:format("age[~p],name[~p]~n", [H#person.age, H#person.name])
  43.     end,
  44.     parse_repeat(T).

 

 

运行代码,如下:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. 5> c(test_pb).  
  2. {ok,test_pb} 
  3. 6> c(test).
  4. {ok,test}  
  5.   
  6. 7> test:encode().  
  7. [[["\b",[25]],[[18],[4],<<"John">>]]]
  8.   
  9. 8> test:decode().  
  10. Data is <<8,25,18,4,74,111,104,110>>
    {person,25,"John"}

  11.   
  12. 9> test:encode_repeat().  
  13. [[["\b","o"],
    [[18],[16],[[["\b",[2]],[[18],"\f",<<"028-12345678">>]]]],
    [[[26],"\b",[[["\b",[25]],[[18],[4],<<"John">>]]]],
    [[26],"\b",[[["\b",[23]],[[18],[4],<<"Lucy">>]]]],
    [[26],"\b",[[["\b",[2]],[[18],[4],<<"Tony">>]]]]]]]

  14.   
  15. 10> test:decode_repeat().

    Data is <<8,111,18,16,8,2,18,12,48,50,56,45,49,50,51,52,53,54,55,56,26,8,8,25,
    18,4,74,111,104,110,26,8,8,23,18,4,76,117,99,121,26,8,8,2,18,4,84,
    111,110,121>>
    {family,111,
    {other,'PhoneType_Company',"028-12345678"},
    [{person,25,"John"},{person,23,"Lucy"},{person,2,"Tony"}]}
    Per Len is 3

    age[25],name["John"]
    age[23],name["Lucy"]
    age[2],name["Tony"]
    ok

文章完整例子下载:http://download.csdn.net/detail/cwqcwk1/7087293

posted @ 2014-12-12 18:38  die  阅读(745)  评论(0编辑  收藏  举报