消息编码
随着时间的流逝,也许我们会条件反射式地认为XML(SOAP)是一个结构文本。毕竟,文本是人可读的,每个计算机系统也可以处理文本。基于文本的XML的普遍共性与我们的与其它系统交互的想法产生了共鸣。可以容易的解释的基于文本的XML本质上会体积变大。可以理解使用XML会带来性能损失。就像要花费点精力把信装到信封里一样,它需要一些处理时间与XML交互。某些情况下,基于文本的XML数据大小限制了它的应用,特别是当我们要通过网络发送一个XML消息的时候。
此外,如果我们限制自己使用基于文本的XML,那么我们怎么才能在XML文档里发送二进制数据(像音乐或者视频)?如果你已经阅读了标准的XMLSchema数据类型,你会发现2个二进制数据类型:: xs:base64Binary 和xs:hexBinary。本质上说,两个数据类型都代表一组有序的8位字节。使用这些XML数据类型或许可以解决一些嵌入二进制数据到文档中的问题,但是事实上,这已经使得性能问题更加糟糕。众所周知的问题就是,base64编码会增加数据30%的大小。这个情况对于xs:hexBinary更坏,因为它会增加位原来的2倍大小。两个数据都是基于UTF-8编码的假设。如果我们采用UTF-16编码,这些倍数因子都会翻倍增加。
XML 信息集( XML Infoset)
为了找到性能的瓶颈的答案,我们详细来看一下XML文档的结构。如果我们看一下规范,XML是一个精确的撰写结构化数据的语法(定义在 http://www.w3.org/TR/REC-xml/)。它要求定义格式良好的XML文档必须包涵一个开始和结束元素、一个根节点等等。奇怪的是,XML规范发布以后,激起了抽象定义XML文档的需求。XML信息集(定义在http://www.w3.org/TR/xml-infoset/)提供了这个抽象定义。
实际上,XML信息集定义是项目之间的关系,不定义任何具体的语法,我们能够解释许多不同的消息编码,包括一些比文本更高校的编码格式,而不需要修改我们的程序。
SOAP和XML信息集
记得SOAP是建立在XML之上的。这个产生一个问题:到底SOAP消息是建立在早期的XML语法上还是XML信息集上呢?答案是2者都有。2个SOAP规范并存:SOAP 1.1 和SOAP 1.2。SOAP1.1建立在旧的XML语法上,SOAP1.2建立在XML 信息集上。有这么一个事实,就可以猜想SOAP1.2建立的消息SOAP1.1的解析器可能无法阅读。WCF是建立在SOAP1.2(XML信息集上),但是它可以同时处理SOAP 1.1 和SOAP 1.2的消息。
WCF可以用来和定制与其它实际的消息编码一起工作,只要消息是遵照SOAP1.1或者SOAP1.2的(它可以和不是SOAP消息一起工作)。如你将会在接下来的章节里看到的一样,WCF是一个可灵活接入和组合的架构。所以自定义编码器可以轻易地安装到WCF的管道上。当一个新的编码器开发完毕,微软或者第三方都可以在消息堆栈里创建和插入它。我将会在第6章:《通道》里详细介绍消息编码器。现在我们来看一下WCF里的编码器。在写本书的时候,WCF提供了三个编码器:文本(text)、(二进制)binary、 消息传输优化机制(Message Transmission Optimization Mechanism ,MTOM)。
文本编码器
和你从它的名字里猜到的一样,文本编辑器的输出结果是基于文本编码的消息。每个明白Unicode文本的系统都可以阅读和处理这个编码器传递来的消息,在与别的非WCF系统互操作时,这个是一个很帮的选择。二进制数据通过xs:base64Binary扩展样式定义(XSD)数据类型可以包涵到基于文本的消息里。这是一个使用WCF文本编码器编码过的消息(为了清晰,移除了一部分元素)。
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header></s:Header>
<s:Body>
<SubmitOrder xmlns="http://wintellect.com/OrderProcess">