C# clrmq上的序列化和反序列化
我目前正在使用ZeroMQ的clrmq绑定在C#中设计一个网络包装器 我的问题是,我正试图想出一种反序列化和序列化的方法 透明的;也就是说,网络包装器可以以字节形式传输任何对象,而不知道或关心其类型,并且可以反序列化到另一端的正确类型 我有如下类别的继承人C# clrmq上的序列化和反序列化,c#,serialization,zeromq,C#,Serialization,Zeromq,我目前正在使用ZeroMQ的clrmq绑定在C#中设计一个网络包装器 我的问题是,我正试图想出一种反序列化和序列化的方法 透明的;也就是说,网络包装器可以以字节形式传输任何对象,而不知道或关心其类型,并且可以反序列化到另一端的正确类型 我有如下类别的继承人 public interface ITransmission { Type Type { get; } } public abstract class Transmission<T> : ITransmission {
public interface ITransmission
{
Type Type { get; }
}
public abstract class Transmission<T> : ITransmission
{
public Type Type { get { return typeof(T); } }
}
公共接口ITTransmission
{
类型{get;}
}
公共抽象类传输:ITTransmission
{
公共类型类型{get{return typeof(T);}
}
其思想是序列化已实现传输类型的对象;传输
它们在clrmq上以字节形式存储,并在另一端反序列化
我的理想解决方案是
感谢您的阅读。我在一个在线多人游戏中成功地做到了这一点,使用的反射可能会根据您的需求满足您的需求 这里有一个链接描述了我是如何做到这一点的: 简而言之,我是如何序列化/反序列化数据的:我创建了一个名为“GameMessage”的类,它使用反射来序列化/反序列化自己。然后,每个消息类型都将简单地从该类继承,并神奇地拥有一个ToByte()函数和接受byte[]的构造函数:
public class GameMessage
{
private static int SortFieldInfo(FieldInfo left, FieldInfo right)
{
if (left.Equals(right))
{
return 0;
}
if (right.Name == "ID")
return 1;
else if (right.FieldType.Name == "String")
return -1;
else
return 0;
}
public GameMessage(){}
public GameMessage(byte[] data)
{
List<byte> bytes = new List<byte>();
List<FieldInfo> info = new List<FieldInfo>(this.GetType().GetFields());
info.Sort(SortFieldInfo);
int idx = 0;
for (int i = 0; i < info.Count; i++)
{
if (info[i].FieldType.Name == "String")// is string)
{
string value;
UInt16 size;
if (i != info.Count - 1)
{
size = BitConverter.ToUInt16(data, idx);
idx += 2;
value = ASCIIEncoding.ASCII.GetString(data, idx, size);
idx += size;
}
else
{
value = ASCIIEncoding.ASCII.GetString(data, idx, data.Length - idx);
idx += data.Length - idx;
}
info[i].SetValue(this,value);
}
else
{
if (info[i].Name != "ID")
{
Type[] types = new Type[2] { data.GetType(), idx.GetType() };
object[] values = new object[2] { data, idx };
info[i].SetValue(this, typeof(BitConverter).GetMethod("To" + info[i].FieldType.Name, types).Invoke(null, values));
idx += Marshal.SizeOf(info[i].FieldType);
}
else
{
idx += sizeof(ID);
}
}
}
}
public byte[] ToByte()
{
List<byte> bytes = new List<byte>();
List<FieldInfo> info = new List<FieldInfo>(this.GetType().GetFields());
info.Sort(SortFieldInfo);
for(int i=0;i<info.Count;i++)
{
if (info[i].FieldType.Name == "String")
{
if (i != info.Count - 1)
{
bytes.AddRange(BitConverter.GetBytes(((UInt16)((string)info[i].GetValue(this)).Length)));
}
bytes.AddRange(ASCIIEncoding.ASCII.GetBytes((string)info[i].GetValue(this)));
}
else
{
bytes.AddRange((byte[])typeof(BitConverter).GetMethod("GetBytes", new Type[] { info[i].FieldType }).Invoke(null, new object[] { info[i].GetValue(this) }));
}
}
return bytes.ToArray();
}
}
公共类游戏消息
{
私有静态int-SortFieldInfo(FieldInfo左,FieldInfo右)
{
如果(左。等于(右))
{
返回0;
}
如果(right.Name==“ID”)
返回1;
else if(right.FieldType.Name==“String”)
返回-1;
其他的
返回0;
}
公共游戏消息(){}
公共游戏消息(字节[]数据)
{
列表字节=新列表();
列表信息=新列表(this.GetType().GetFields());
信息排序(SortFieldInfo);
int-idx=0;
对于(int i=0;i 对于(int i=0;i用户dferraro的解决方案是一个很好的解决方案。但我认为现在人们可以用C#中的序列化做得更好。我强烈建议您将ZeroMQ与Google的Protobuf框架作为序列化和消息传递组件的传输配对
请看一下的.NET实现。我不会详细介绍它的实现方面,因为它的文档非常丰富,关于它的StackOverflow这里已经有很多很好的问题。事实上,Protobuf的C#implementation的作者经常无所事事,并且会用标签回答任何问题。速度是一个关键因素吗?我在过去对反射做过类似的事情。那是几年前的事了,但简而言之,我做的是有一些代码,可以使用反射迭代对象中的每个成员,然后将其打包到一个字节数组中。接收端也做了同样的事情。它非常灵活,而且我非常灵活您好,速度在某个时候会是一个因素,但现在我只是收集一些想法。您的解决方案有多快/慢?我可以使用界面中的类型信息使其更快吗?它足够快,满足我的需要,这是相当高的性能要求(实际上是一个2D在线多人游戏)那是6或7年前我提出的;)。我想它已经过时了。我从来没有听说过protobuf这个东西,但它看起来很棒。谢谢你给出了非常详尽的答案,而且