一、定义自己的protobuf
这里我定义一个简单的protobuf,用于实现通过http中的protobuf上传一个人的个人信息,以及通过http请求获取服务器上的个人信息。由于本例只是说明protobuf的使用,所以没有涉及到服务器对数据库的存储和查询
my_protobuf.proto
/*请求返回枚举*/
enum return_code {
EVERETHING_OK=0; /*操作成功--所有未失败信息都可用这个*/
UNKONW_ERR =1; /*未知错误*/
AUTH_ERR =2; /*认证失败*/
}
/*元素类型枚举*/
enum request_type{
POST_PERSON_INFO = 1; /*上报个人信息*/
GET_PERSON_INFO = 2; /*获取个人信息*/
}
/*男女枚举类型*/
enum sex_flag {
MAN = 0; /*男*/
WOMAN = 1; /*女*/
}
/*个人信息*/
message person_info {
required string name = 1; /*姓名*/
required sex_flag sex = 2; /*性别*/
required uint32 age = 3; /*年龄*/
required uint32 heigth = 4 /*身高*/
}
message pb_person_info {
repeated person_info p_info = 1; /*个人信息*/
}
/*protobuf里面的req*/
message request{
required request_type ele_type =1; /*请求的类型*/
optional pb_person_info p_person_info =2; /*上报个人信息*/
}
/*http请求*/
message http_req {
required int64 id =2; /*id号*/
required string auth =3; /*自认证值*/
repeated request req =5; /*请求*/
}
message response {
required uint32 ele_type = 1; /*元素类型*/
optional pb_person_info g_person_info = 2; /*个人信息*/
}
/*http回复*/
message http_resp {
repeated response resp =1;
}
二、处理protobuf的请求
1、主函数
def protobuf_handle(request):
'''
处理http中的protobuf请求
'''
data = request.body
obj = pb_parse_buf(data)
if obj == AUTH_ERR:
pkt = pb_gen_packet_error(obj)
return HttpResponse(pkt.SerializeToString())
pkt = pb_process_packet(obj)
if pkt is None:
pkt = pb_gen_packet_error(UNKONW_ERR)
return HttpResponse(pkt.SerializeToString())
return HttpResponse(pkt.SerializeToString())
2、函数pb_parse_buf(),解析protobuf
def pb_parse_buf(data):
'''
解析protobuf
'''
obj = http_req()
obj.ParseFromString(data) #使用ParseFromString进行解包
if obj is None:
return UNKONW_ERR
if obj.auth != 0x12345: #认证错误,这是认证值简单写为0x12345
return AUTH_ERR
return obj
3、函数pb_gen_packet_error(), 生成一个错误报文,以指定的错误代码返回
def pb_gen_packet_error(error_code):
'''
生成一个错误报文,以指定的错误代码返回
'''
try:
hdr = http_resp()
resp = hdr.resp.add()
resp.return_code = error_code
resp.ele_type = 0
return hdr
except Exception, e:
EXCEPTION(e)
return None
4、pb_process_packet(),处理请求
def pb_process_packet(pb_req):
'''
处理请求
'''
try:
hdr = http_resp()
for req in pb_req:
if req.ele_type == POST_PERSON_INFO:
resp = hdr.resp.add()
pb_post_person_info(pb_req, req, resp):
elif req.ele_type == GET_PERSON_INFO:
resp = hdr.resp.add()
pb_get_person_info(pb_req, req, resp):
return hdr
except Exception,e:
return None
5、函数pb_post_person_info(),上报个人信息
def pb_post_person_info(pb_req, req, resp):
'''
上报个人信息
'''
try:
list = [man,woman]
resp.ele_type = POST_PERSON_INFO
resp.return_code = EVERETHING_OK
print 'request id:%d' % pb_req.id
person_info = req.p_person_info.p_info
for info in person_info:
print 'name:%s' % info.name
print 'sex:%s' % str(list[info.sex])
print 'age:%d' % info.age
print 'heigth:%d' % info.heigth
return resp
except Exception,e:
return None
6、函数pb_get_person_info(),获取个人信息
def pb_get_person_info(pb_req, req, resp):
'''
获取个人信息
'''
try:
person_info = [{'name':'xiaoming', 'sex':MAN, 'age’:20,'heigth':170},\
{'name':'xiaoping','sex':WOMAN, 'age’:19, 'heigth':160}]
resp.ele_type = GET_PERSON_INFO
resp.return_code = EVERETHING_OK
for list in person_info:
person = resp.g_person_info.p_info.add()
person.name = list['name']
person.sex = list['sex']
person.age = list['age']
person.heigth = list['heigth']
retun resp
except Exception, e:
return None