从零开始学WCF(11)大型数据和流

本文详细介绍了WCF中处理大型数据和流的方法,包括编码数据的文本和二进制形式,重点讨论了二进制内容和大型数据内容的处理。MTOM作为一种优化机制,用于减少大型二进制数据的传输开销。文章还探讨了不同编码器的使用场景,如TextMessageEncodingBindingElement、MtomMessageEncodingBindingElement和BinaryMessageEncodingBindingElement,并提供了启用MTOM的编程模型及示例。
摘要由CSDN通过智能技术生成

基本考虑事项

WCF是基于XML的通信基础结构。

编码数据:文本和二进制

最常有的顾虑包括:认为与二进制格式相比XML的开销比较大一些(因为其开始标记和结束标记的重复性),数值的编码可能要大得多(因为他们是以文本值来表示的),并且无法有效的表示二进制数据(因为它们必须进行特殊的编码才能嵌入到文本格式中)。

尽管上述以及其他许多类似的问题是存在的,但是XML Web Services环境中的XML文本编码消息与旧样式的远程过程调用(RPC)环境中的二进制编码消息之间的实际差异,通常远远小于最初的考虑中所预想的程度。

虽然XML文本编码消息是透明的并且是"可读的"(也许难以理解),但比较而言,二进制消息则通常相当晦涩,在无工具的情况下很难解码。

要在文本与二进制之间进行选择,不能简单地认为二进制消息总是小于XML文本消息。

XML文本消息的一个明确而无可争议的优点是它们基于标准的,并且提供最为广泛的互操作性选项和平台支持选择范围。


二进制内容

从最终的消息大小这一角度而言,二进制编码优于基于文本编码的一个方面就在于大型二进制数据项,例如,图片、视频、音效剪辑或者必须在服务与其使用者之间交换的任何其他形式的非透明二进制数据。为了使这些类型的数据也适合XML文本,常用的方法就是使用Base64编码对其进行编码。

在Base64编码字符串中,每个字符都表示原始8位数据的6位,这导致Base64的编码开销比率是4:3,且未计算额外的格式字符(回车符/换行符),而按照惯例这些字符通常是会添加的。虽然XML编码与二进制编码之间的差异显著与否通常取决于具体情况,但是当传送500MB负载时大小增加超过33%通常是不受欢迎的。

为避免这种编码开销,消息传输优化机制(MTOM:Message Transmission Optimization Mechanism)标准允许将消息中包含的大型数据元素外部化,并将其作为无任何特殊编码的二进制数据随消息一起传送。利用MTOM,消息将以一种与带附件或嵌入式内容(图片和其他嵌入式内容)的简单邮件传输协议(SMTP)电子邮件类似的方式交换;MTOM消息会打包成多部分/相关MIME(多用途因特网邮件扩展(Multipurpose Internet Mail Extensions))序列,其中根部分是实际的SOAP消息。

但是,与Base64一样,对于MIME格式,MTOM也有一些必要的开销,这样仅在二进制数据元素的大小超过大约1KB时,才能体现出使用MTOM的好处。由于这一开销,如果二进制负载在该阈值之下,则MTOM编码的消息可能会大于对二进制数据使用Base54编码的消息。


大型数据内容

即使不考虑线路需求量,前面提及的500MB负载也对服务和客户端本身提出了很大的考验。默认情况下,WCF会以缓冲模式处理消息。这意味着消息的整个内容在发送前或接收后都存在于内存中。尽管对于大多数情形来说这是个很好的策略,并且是消息传递功能(如数字签名)和可靠传递所必须的,但是大型消息可能很容易最终耗尽系统资源。

处理大型负载的策略是流。尽管消息(尤其是以XML表示的消息)通常会被认为是相对紧凑的数据包,但消息大小也可能达到GB数量级,从而与连续的数据流很相似,而不是易于处理的数据包。当以流模式而不是缓冲模式传输数据时,发送方会议流的形式将消息正文的内容提供给接收方,并且消息基础结果会不断地将就绪的数据从发送发转发给接收方。

传输此类大型数据内容的最常见情形是传输具有以下特点的二进制数据对象:

1) 无法方便地分成消息序列。

2) 必须以及时方式传递。

3) 当开始传输时,还不是已全部就绪。

对于不具有上述限制条件的数据,通常最好在一个会话的范围内发送消息序列,而不是一次性地发送一个大消息。


编码

编码定义了一组规则,规定消息在线路中的存在形式。把我们的消息如何编码,然后在传输。

编码器实现此类编码,并负责将Message内存中消息转变为可以通过网络发送的字节流或字节缓冲区(对于发送方而言)。在接收方,编码器会将一系列字节转变为内存中的消息。

WCF包括三个编码器:

1) TextMessageEncodingBindingElement: 

文本消息编码器是所有基于HTTP的绑定的默认编码器,并且是最关注互操作性的所有自定义绑定的正确选择。此编码器读取和编码标准SOAP 1.1/SOAP 1.2文本消息,而不会对二进制数据进行任何特殊处理。如果消息的MessageVersion设置为None,则SOAP信封包装会从输出中省略,只有消息正文内容会进行序列化。

2) MtomMessageEncodingBindingElement:

MTOM消息编码器是一个文本编码器,实现对二进制数据的特殊处理,默认情况下在任何的标准绑定中都不会使用,因为它是一个严格按具体情况进行优化的实用工具。只有当二进制数据的量不超过某个阀值时,MTOM编码才具有优势,如果消息包含的二进制数据超过了这个阀值,则这些数据会外部化到消息信封之后的MIME部分。

3) BinaryMessageEncodingBindingElement:

二进制消息编码器是Net*(以.NET打头的,例如.NET.TCP,.NET.TCP,NET.Pipe)绑定的默认编码器,当通信双方都基于WCF时,此编码器始终是正确的选择。二进制消息编码器使用.NET 二进制XML格式,此格式是XML信息集(Information Sets,Infosets)的Microsoft特定二进制表示法,与等效的XML 1.0表示法相比产生的需求量通常较小,并将二进制数据编码为字节流。

每个标准绑定都包括一个预配置编码器,因此默认情况下带Net*前缀的绑定使用二进制编码器(通过包括BinaryMessageEncodingBindingElement类),而BasicHttpBinding和WSHttpBinding类则使用文本消息编码器(通过TextMessageEncodingBindingElement类)。


通常,文本消息编码是要求互操作性的任意通信路径的最佳选择,而二进制消息编码则是其他任意通信路径的最佳选择。通常,对于单个消息而言,二进制消息编码生成的消息大小要小于文本编码,并且在通信会话期间消息大小会逐渐变得更小。与文本编码不同的是,二进制编码不需要对二进制数据使用特殊处理(例如,使用Base64),但会将字节表示为字节。


启用MTOM

当要求互操作性,并且必须发送大型二进制数据时,MTOM消息编码是一个备选的编码策略,可以在标准BasicHttpBinding或WSHttpBinding绑定上启用它,方法是:将该绑定的MessageEncoding属性设置为Mtom,或者将MtomMessageEncodingBindingElement编写为CustomBinding。


因为MTOM是在绑定级别启用的,所以启用MTOM会影响给定终结点上的所有操作,通常情况下,只有在终结点交换超过1KB二进制数据的消息时,才应该对它启用MTOM。


编程模型

无论在应用程序中使用三个内置编码器中的哪一个,在传输二进制数据方面的编程体验都是相同的。区别在于WCF如何基于数据类型来处理数据。


当使用MTOM时,将根据以下规则序列化上面的数据协定:

1) 如果binaryBuffer不是null,并且有个别包含足够的数据,使得需要Base64编码所没有的MTOM外部化开销(MIME头等等),则这些数据将外部化并作为二进制MIME部分随消息一起传送。如果未超过阀值,则数据会编码为Base64.

2) 字符串(和其他所有非二进制的类型)无论多大,始终表示为消息正文内的字符


MTOM_DEMO

1) 新建一个WCF Application Service,然后添加“UploadService”WCF服务。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.IO;

namespace Video11.Demo1.Mtom
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IUploadService" in both code and config file together.
    [ServiceContract(Namespace = "http://Video11.Demo1.Mtom")]
    public interface IUploadService
    {
        [OperationContract]
        int Upload(Stream da
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值