选择消息编码器

本文讨论在 Windows Communication Foundation(WCF):二进制、文本和消息传输优化机制(MTOM)中包含的消息编码器之间进行选择的条件。

在 WCF 中,指定如何通过 绑定(由 绑定元素序列构成)在终结点之间传输数据。 消息编码器由绑定堆栈中的消息编码绑定元素表示。 绑定包括可选的协议绑定元素,例如安全绑定元素或可靠的消息绑定元素、所需的消息编码绑定元素和所需的传输绑定元素。

消息编码绑定元素位于可选的协议绑定元素和所需的传输绑定元素上方。 在传出端,消息编码器将传出的Message序列化,并将其传递给传输层。 在传入端,消息编码器接收传输中的序列化形式 Message ,并将其传递给更高的协议层(如果有)或应用程序(如果不存在)。

连接到预先存在的客户端或服务器时,你可能没有选择使用特定消息编码,因为你需要以对方预期的方式对消息进行编码。 但是,如果要编写 WCF 服务,则可以通过多个终结点公开服务,每个终结点使用不同的消息编码。 这样,客户端可以选择通过最适合它们的终结点与您的服务通信的最佳编码,同时也可以灵活地选择对它们来说最合适的编码。 使用多个终结点还可以将不同消息编码的优势与其他绑定元素相结合。

系统提供的编码器

WCF 包括三个消息编码器,这些编码器由以下三个类表示:

  • TextMessageEncodingBindingElement,文本消息编码器支持纯 XML 编码和 SOAP 编码。 文本消息编码器的纯 XML 编码模式称为“纯旧 XML”(POX),以将其与基于文本的 SOAP 编码区分开来。 若要启用 POX,请将 MessageVersion 属性设置为 None. 使用文本消息编码器与非 WCF 终结点进行互作。

  • BinaryMessageEncodingBindingElement(二进制消息编码器)使用压缩的二进制格式,并针对 WCF 到 WCF 通信进行优化,因此不可互作。 这也是 WCF 提供的所有编码器中最高性能的编码器。

  • MtomMessageEncodingBindingElement,绑定元素,指定使用 MTOM 编码的消息的字符编码和消息版本控制。 MTOM 是一种高效技术,用于在 WCF 消息中传输二进制数据。 MTOM 编码器尝试在效率和互作性之间创造平衡。 MTOM 编码以文本形式传输大多数 XML,但通过传输 as-is来优化大型二进制数据块,无需将二进制数据转换为文本。 就效率而言,在 WCF 提供的编码器中,MTOM 在文本(最慢)和二进制之间(最快)。

如何选择消息编码器

下表描述了用于选择消息编码器的常见因素。 确定对应用程序很重要的因素的优先级,然后选择最适合这些因素的消息编码器。 请务必考虑此表中未列出的任何其他因素以及应用程序中可能需要的任何自定义消息编码器。

因子 DESCRIPTION 支持此因素的编码器
支持的字符集 TextMessageEncodingBindingElementMtomMessageEncodingBindingElement 仅支持 UTF8 和 UTF16 Unicode(big-endianlittle-endian)编码。 如果需要其他编码(如 UTF7 或 ASCII),则必须使用自定义编码器。 有关示例自定义编码器,请参阅 自定义消息编码器 文本
检查 检验是能够在传输期间检查消息的能力。 使用或不使用 SOAP 的文本编码允许许多应用程序检查和分析消息,而无需使用专用工具。 在消息或传输级别使用安全传输机制会对检查消息的能力产生影响。 机密性可保护邮件不被检查,完整性可防止邮件被修改。 文本
可靠性 可靠性是编码器传输错误的复原能力。 还可以在消息、传输或应用程序层提供可靠性。 所有标准 WCF 编码器都假定另一层提供可靠性。 编码器无法从传输错误中恢复。 没有
简易性 简单性表示可以轻松为编码规范创建编码器和解码器。 为简单起见,文本编码特别有利,POX 文本编码具有不需要对处理 SOAP 的支持的额外优势。 文本 (POX)
尺寸 编码决定对内容施加的额外负担的程度。 编码消息的大小与服务作的最大吞吐量直接相关。 二进制编码通常比文本编码更紧凑。 当消息大小受到严格限制时,请考虑在编码期间压缩消息内容。 但是,压缩会增加消息发送方和接收方的处理成本。 二进制
流媒体 流式处理允许应用程序在到达整个消息之前开始处理消息。 有效使用流式处理要求消息的重要信息在消息开头可用,以便不需要接收应用程序等待它到达。 此外,使用流式传输的应用程序必须以增量方式组织消息中的数据,以便内容不具有转发依赖项。 在许多情况下,您必须在流式传输内容与尽可能减少该内容的传输大小之间进行权衡。 没有
第三方工具支持 支持编码的区域包括开发和诊断。 第三方开发人员对库和工具包进行了大量投资,用于处理以 POX 格式编码的消息。 文本 (POX)
互操作性 此因素是指 WCF 编码器能够与非 WCF 服务进行互作。 文本

MTOM (部分)

注意:使用 Binary Encoder 时,在创建 XMLReader 时使用 IgnoreWhitespace 设置将不起作用。 例如,如果在服务操作中执行以下操作:

public void OperationContract(XElement input)
{
    Console.WriteLine("{0}", input.Value);
    int counter = 0;
    var xreader = input.CreateReader();
    var reader = XmlReader.Create(xreader, new XmlReaderSettings() { IgnoreWhitespace = true });
    while (reader.Read())
    {
        counter++;
    }

    Console.WriteLine("Read {0} lines with reader", counter);
}

IgnoreWhitespace 设置已被忽略。

压缩和二进制编码器

从 WCF 4.5 开始,WCF 二进制编码器增加了对压缩的支持。 这样,便可以使用 gzip/deflate 算法从 WCF 客户端发送压缩消息,并使用自承载 WCF 服务中的压缩消息进行响应。 此功能支持对 HTTP 和 TCP 传输进行压缩。 始终可以通过配置 IIS 主机服务器来启用 IIS 托管 WCF 服务来发送压缩响应。 使用 BinaryMessageEncodingBindingElement.CompressionFormat 属性配置压缩类型。 此属性设置为枚举值之一 System.ServiceModel.Channels.CompressionFormat

由于此属性仅在 binaryMessageEncodingBindingElement 上公开,因此需要创建自定义绑定,如下所示才能使用此功能:

<customBinding>
  <binding name="BinaryCompressionBinding">
    <binaryMessageEncoding compressionFormat ="GZip" />
    <httpTransport />
 </binding>
</customBinding>

客户端和服务都需要同意发送和接收压缩的消息,因此必须在客户端和服务上的 binaryMessageEncoding 元素上配置 compressionFormat 属性。 如果服务或客户端的任一端未配置压缩,而另一端已配置,则会引发 ProtocolException。 应该仔细考虑如何启用压缩。 如果网络带宽是瓶颈,则压缩非常有用。 如果 CPU 是瓶颈,压缩将降低吞吐量。 必须在模拟环境中执行适当的测试,以确定这是否有利于应用程序

另请参阅