c# - Protobuf-net:更改消息名称
问题描述
我必须遵循以下场景:今天,相同的消息用于两个不同的操作。操作开始时非常相似,但现在变得不同,因此应该区分消息。
那么,我如何“拆分”消息并保持复古兼容性?可能吗?我的意思是,今天我有
[ProtoContract]
class Foo{ ... }
明天我想拥有
[ProtoContract]
class Foo{ ... }
[ProtoContract]
class Bar{ /* Identical fields and ProtoMemeber as Foo, at least for now */ }
并将它们序列化为 Foo 和 Bar,但仍然让旧客户端仅反序列化 Foo:
var x = Serialize<Bar>(someBar);
//... send x to old client who does not know about Bar
var foo = Deserialize<Foo>(x); // deserialize correctly because fields are identical
可能吗?我需要添加一些属性,还是做其他事情?
编辑:它似乎“只是工作”:
static void Main(string[] args)
{
using (var stream = new MemoryStream())
{
var x = new Foo();
x.AcquireTimeInLocalTime = DateTime.Now;
x.Chans[23] = new SomeItem() { SomeString = "Ciao" };
Serializer.SerializeWithLengthPrefix(stream, x, PrefixStyle.Base128);
stream.Seek(0, SeekOrigin.Begin);
var y = Serializer.DeserializeWithLengthPrefix<Bar>(stream, PrefixStyle.Base128);
Console.WriteLine($"{y.AcquireTimeInLocalTime}, {y.Chans[23].SomeString}, {y.GetType().Name}");
}
}
印刷
01/12/20 10:43:17, Ciao, Bar
这是我所期望的。但我会留下这个问题,因为我不确定这只是偶然的还是预期(和支持)的行为。我正在寻找比实验更权威的答案。
解决方案
除非您使用类似的东西google.protobuf.Any
(其中包括数据中的消息名称),否则应该没问题。消息的名称通常不是协议缓冲区中序列化的数据的一部分。(并且它可能在不同的语言之间有所不同,或者在不同的包中等等。)
我不知道 protobuf-net 对未知字段做了什么,但在 Google.Protobuf 中,即使存在生成时不知道标签号的字段,反序列化过程也会成功。(根据使用的版本,未知字段值可能会或可能不会保留以供以后序列化。当这些只是普通用户类时,我不希望 protobuf-net 保留值。)这是您可能想要测试的东西,因此,如果您确实添加任何新字段Bar
并使用这些字段序列化数据,则Foo
-only 客户端仍然能够反序列化。(不过,您需要考虑数据丢失的影响。)
推荐阅读
- node.js - Angular 6 + NodeJS + MongoDB
- python - 通过部分 href 查找元素(Python Selenium)
- c# - 使用 .NET 类库显示表单以响应 COM 事件会冻结表单
- mysql - 获取activejdbc中表的列顺序
- tornadofx - Tornadofx Tableview 行数
- sql - WHERE 子句中的 SQL IF 语句
- spring - Spring stomp over websocket SubscribeMapping 不起作用
- react-native - 带有反应原生导航的优步应用导航
- c# - 以 c# 形式创建 Windows 10 透明效果
- google-app-engine - 如何使用 gcloud 推送最新版本的 Web 应用程序以使其上线