我有一个客户端 - 服务器应用程序,它使用WCF进行通信,并使用NetDataContractSerializer序列化对象图。
由于在服务器和客户端之间传输了大量数据,我试图通过微调数据成员的大小来减小其大小(例如,将int更改为short,将long更改为int等)。
完成调整后,我发现传输的数据量没有变化!
问题是,NetDataContractSerializer将对象图序列化为XML,因此无论数据成员的大小如何,唯一重要的是它的值的大小。例如,Int16数据成员的值10023将序列化为字符串“10023”(0x3130303233),而不是仅仅10023(0x2727)。
我记得在Remoting中我可以使用BinaryFormatter根据数据成员的类型序列化值,但我不知道是否可以将它与WCF一起使用。
有人有解决方案吗?
答案 0 :(得分:35)
WCF使用SOAP消息,但使用何种消息编码完全取决于您。
基本上,开箱即用,你有两个:文本编码(XML消息的文本表示)或二进制编码。如果你真的必须这样做,你可以编写自己的消息编码。
开箱即用,basicHttp和wsHttp绑定使用文本编码 - 但如果你愿意,你可以改变它。 netTcp绑定(这是公司防火墙背后的明确首选)将默认使用二进制文件。
如果您愿意,也可以定义(仅在配置中)您自己的“二进制http”协议:
<bindings>
<customBinding>
<binding name="BinaryHttpBinding">
<binaryMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>
然后在您的服务和客户端配置中使用它:
<services>
<service name="YourService">
<endpoint
address="http://localhost:8888/YourService/"
binding="customBinding"
bindingConfiguration="BinaryHttpBinding"
contract="IYourService"
name="YourService" />
</service>
</services>
现在你有一个基于http的传输协议,它将以紧凑的二进制编码你的消息,供你使用和享受!
无需额外编码或乱码或大量手动XML序列化代码 - 只需将其插入并使用即可!啊,WCF灵活性的快乐!
答案 1 :(得分:6)
首先想到;你启用了传输压缩吗?
数据有多复杂?如果它适用于常规DataContractSerializer
(即简单的对象树),那么protobuf-net可能是有用的。它是一个非常有效的二进制序列化库,通过服务契约上的附加属性支持WCF - 例如:
[ServiceContract]
public interface IFoo
{
[OperationContract, ProtoBehavior]
Test3 Bar(Test1 value);
}
([ProtoBehaviour]
是此方法的不同序列化程序中的交换)
然而:
Order
属性上的[DataMember(Order = x)]
很好,它也适用于MTOM,降低了较大消息的基本成本64。
答案 2 :(得分:1)
二进制编码器不会以二进制形式序列化您的对象,因为它与序列化完全没有关系!它是在较低层工作的东西,决定如何在服务器和客户端之间传输消息。
换句话说,该对象将首先被序列化(例如,通过DataContractSerializer),然后进行编码(通过BinaryEncoder)。因此,只要涉及DataContractSerializer,您的对象将始终采用XML格式。
如果您想要更紧凑的数据和更好的性能,请阅读此博客:
https://blogs.msdn.microsoft.com/dmetzgar/2011/03/29/protocol-buffers-and-wcf/