使用protobuf进行部分反序列化

时间:2012-06-15 19:10:04

标签: design-patterns serialization architecture protobuf-net

对于marc或任何有过protobuf-net经验的人:

我有一个架构,服务器与客户端(通过TCP)保持终身持久连接。由于连接层/服务器应具有较长的正常运行时间,因此它仅对消息进行反序列化并将其传递到应用服务器/层。它本身不包含任何商业逻辑。

 clients -> connection layer (deserialization) -> app layer (business logic)

问题是,虽然我现在可以更改biz逻辑,但我无法更改应用层和客户端共享的模型,因为连接层依赖于模型进行反序列化。

有没有办法让连接层仅将消息反序列化为基类,以用于转发/路由?

否则,我想我必须在基类中创建一个二进制字段,该字段按原样传递并由应用层进行反序列化。一阶段序列化,两阶段反序列化。

编辑:充实

class Message
{
  User user;
  // not much else in here, potentially routing information
}

class RequestType1: Message
{
 // lots of fields 
 // which are specific to this type of request/reply 
}

class RequestType2: Message
{

}

连接层不应该关心特定请求类型的结构。这样我就可以随意更改它们,只要客​​户端和应用层同意即可。但是目前连接层进行反序列化,所以它需要知道模型,任何更改都会迫使我重新启动连接服务器。

我只需要将其反序列化到路由,这意味着“用户信息”+“子类型名称/号码”。

1 个答案:

答案 0 :(得分:3)

首先:由于TCP是基于流的,因此不应直接通过线路发送protobuf序列化消息。你永远不知道什么时候收到了完整的信息。

WithLengthPrefix仅用于此。使用二进制长度为所有消息添加前缀,以便您可以判断完整消息何时到达。

如果我是你,我会创建一个包含足够信息的标题。长度是必需的,但您也可以包括传输的消息的类型等。这意味着您只需要检查每条消息的标头,而不是调用昂贵的反序列化。

请求标头示例:

  • 标题版本(byte
  • 内容类型(byte)(您需要在某处创建映射)
  • 内容长度(int

我正在为我的Griffin.Networking(http://github.com/jgauffin/griffin.networking)写一个小插件,它将有一个小标题并使用protobuf作为消息。观察项目是否在提交时获得更新。