对于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
{
}
连接层不应该关心特定请求类型的结构。这样我就可以随意更改它们,只要客户端和应用层同意即可。但是目前连接层进行反序列化,所以它需要知道模型,任何更改都会迫使我重新启动连接服务器。
我只需要将其反序列化到路由,这意味着“用户信息”+“子类型名称/号码”。
答案 0 :(得分:3)
首先:由于TCP是基于流的,因此不应直接通过线路发送protobuf序列化消息。你永远不知道什么时候收到了完整的信息。
WithLengthPrefix
仅用于此。使用二进制长度为所有消息添加前缀,以便您可以判断完整消息何时到达。
如果我是你,我会创建一个包含足够信息的标题。长度是必需的,但您也可以包括传输的消息的类型等。这意味着您只需要检查每条消息的标头,而不是调用昂贵的反序列化。
请求标头示例:
byte
)byte
)(您需要在某处创建映射)int
)我正在为我的Griffin.Networking(http://github.com/jgauffin/griffin.networking)写一个小插件,它将有一个小标题并使用protobuf作为消息。观察项目是否在提交时获得更新。