如何以二进制方式序列化WCF消息,而不是SOAP消息?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (20)

我有一个客户端 - 服务器应用程序,它使用WCF进行通信,并使用NetDataContractSerializer来序列化对象图。

由于大量数据在服务器和客户端之间传输,我试图通过调整数据成员的大小来缩小其大小(例如,将int更改为short,long更改为int等)。

调整完成后,我发现传输的数据量没有变化! 问题是,NetDataContractSerializer将对象图序列化为XML,因此无论数据成员的大小如何,唯一重要的是它的值的大小。例如,Int16数据成员的值10023将被串行化为字符串“10023”(0x3130303233),而不是10023(0x2727)。

我记得在Remoting中,我可以使用BinaryFormatter根据数据成员的类型对值进行序列化,但我不知道是否可以将它与WCF结合使用。

有人有解决方案吗?

提问于
用户回答回答于

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序列化代码 - 只需将它们连接在一起使用即可!

用户回答回答于

首先想到的; 你有没有启用传输压缩?

数据有多复杂?如果它能与常规DataContractSerializer(即简单的对象树)一起工作,那么protobuf-net可能是有用的。这是一个非常有效的二进制序列化库,通过服务合同上的附加属性支持WCF,例如:

[ServiceContract]
public interface IFoo
{
    [OperationContract, ProtoBehavior]
    Test3 Bar(Test1 value);
}

[ProtoBehaviour]这个方法是在不同的串行器中交换的)

然而:

  • 它需要能够为每个属性标识一个数字标签 - 要么通过额外的属性,要么可以使用Orderon [DataMember(Order = x)]属性
  • 继承(如果正在使用它)需要额外的属性
  • 如果使用程序集共享(“mex”不喜欢它),它的效果最好......)

很好,它也可以与MTOM一起使用,从而降低较大消息的基本64成本。

扫码关注云+社区