Protobuf 不是一个自描述的协议,序列化后的二进制消息中应该没有必要的类型信息。所以采取往消息体中增加额外信息的方式来辅助确定消息类型。
- 使用枚举MsgType定义消息类型,每种消息对应一种消息类型
- 所有的消息都有一个消息类型字段,注意此字段的编号保持确定
- 定义辅助消息BaseMsg,只包含一个消息类型字段,用于辅助反序列化
消息定义 xxx.proto文件内容如下:
syntax = "proto3"; // 消息类型,和BaseMsg配合 // 用于客户端在不知道确切消息类型的情况下解析消息 enum MsgType { BaseMsgType = 0; DepthDataType = 1; KLineDataType = 2; } message BaseMsg{ MsgType msg_type = 1; } // 编号范围 100 - 199 message DepthData{ MsgType msg_type = 1; string symbol = 101; // 合约代码,例如IF1612, string symbol_id = 102; // 合约唯一ID … } |
序列化部分:
depth_data = xxx_pb2.DepthData()
depth_data.msg_type = xxx_pb2.DepthDataType # 必须明确设置
depth_data.symbol = "xxx"
binary_msg = depth.SerializeToString()
反序列部分:
base_msg = xxx_pb2.BaseMsg()
base_msg.ParseFromString(binary_msg)
if base_msg.msg_type == xxx_pb2.DepthDataType:
depth_msg = xxx_pb2.DepthData()
depth_msg.ParseFromString(binary_msg)