在 protobuf-net 中,是否可以根据基本类型部分反序列化消息
在 protobuf-net 中是否可以根据基本类型部分反序列化消息?
在我的系统中,我有一个继承层次结构,其中每条消息都继承自 MessageBase。 MessageBase 有一个 uint MessageType。理想情况下,我只想反序列化 MessageBase 并检查它是否是我感兴趣的 MessageType,然后我可以丢弃该消息或决定反序列化实际消息。这是为了节省反序列化的成本(我有一个CPU周期预算和大量的消息要处理)。
用法示例如下所示。
多谢。
MessageBase msgBase = ..deserialize;
if(msgBase.MessageType = 1)//1 is the Tick msg type
{
Tick tick = ..deserialize actual msg;
//do something with tick
}
//throw away msgBase
[ProtoContract,ProtoInclude(1, typeof(Tick))]
public class MessageBase
{
protected uint _messageType;
[ProtoMember(1)]
public uint MessageType
{
get { return _messageType; }
set{ _messageType = value;}
}
}
[ProtoContract]
public public class Tick : MessageBase
{
private int _tickId;
private double _value;
public Tick()
{
_messageType = 1;
}
[ProtoMember(1)]
public int TickID
{
get { return _tickId; }
set { _tickId = value; }
}
[ProtoMember(2)]
public double Value
{
get { return _value; }
set { _value = value; }
}
}
in protobuf-net is it possible to partially deserialize a message based on a base type?
In my system I have an inheritance hierarchy where every message inherits from a MessageBase. The MessageBase has a uint MessageType. Ideally I only want to deserialize the MessageBase and check if it’s a MessageType I’m interested in then I can either throw away the message or make the decision to deserialize the actual message. This is to save the cost of deserialize ( I have a cpu cycle budget and lots of messages to process).
Example usage shown below.
Thanks a lot.
MessageBase msgBase = ..deserialize;
if(msgBase.MessageType = 1)//1 is the Tick msg type
{
Tick tick = ..deserialize actual msg;
//do something with tick
}
//throw away msgBase
[ProtoContract,ProtoInclude(1, typeof(Tick))]
public class MessageBase
{
protected uint _messageType;
[ProtoMember(1)]
public uint MessageType
{
get { return _messageType; }
set{ _messageType = value;}
}
}
[ProtoContract]
public public class Tick : MessageBase
{
private int _tickId;
private double _value;
public Tick()
{
_messageType = 1;
}
[ProtoMember(1)]
public int TickID
{
get { return _tickId; }
set { _tickId = value; }
}
[ProtoMember(2)]
public double Value
{
get { return _value; }
set { _value = value; }
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果它是消息的一部分,那么目前:否。因为它是字段 1,所以我可能预先筛选它们,但即使这样也是一种黑客行为(不能保证字段 1 是第一个 - 规范明确规定您必须允许任何排序) )。
然而!
如果您愿意进行一些重构,那么可能有一个选择。如果这是消息的线性异构序列,那么对其进行编码的另一种方法是使用
SerializeWithLengthPrefix
实现,为每种消息类型传递不同的标记 - 那么您将得到一个类似的序列(有点自由与表示)当然,这有点取决于另一端的匹配,但除非我弄错了,否则这与类似 SAX 的处理有很好的联系 此处讨论(作为提案),顺便说一句,它也与 NonGeneric 反序列化的工作方式完全兼容。下面是一个示例,仅反序列化
Bar
对象,在控制台上显示“2”和“4”:在线上,这实际上与父对象兼容:
如果建议的选项generate_visitors得到实现,您应该能够从任何客户端使用相同类型的异构数据流。明显的映射类似于
[ProtoContract]
上的可选属性来帮助解决此问题 - 但在新的 protobuf 功能明确之前我不想添加它,因为到目前为止它看起来像与我的实现完全匹配。这很好。If it is part of the message, then at the moment: no. Since it is field 1, I could potentially pre-screen them, but even that is a hack (there is no guarantee that field 1 is first - the spec makes it clear that you must allow for any ordering).
However!
there may be an option, if you are open to a little refactoring. If this is a linear heterogenous sequence of messages, then another way to encode it is to use the
SerializeWithLengthPrefix
implementation, passing a different tag for each message type - then you have a sequence like (being a bit liberal with the representation)of course it depends a bit on the other end matching, but unless I am mistaken this ties in pretty well with the SAX-like processing discussed here (as a proposal), which incidentally is also entirely compatible with how the NonGeneric deserialize works. Here's an example, that only deserializes the
Bar
objects, showing "2" and "4" on the console:On the wire, this is actually compatible with a parent object:
If the proposed
option generate_visitors
gets implemented you should be able to consume the same type of heterogenous data stream from any client. The obvious mapping would be something like an optional property on[ProtoContract]
to help with this - but I don't want to add that until the new protobuf feature is clear, as so far it looks like an exact match to my implementation. Which is nice.