zoukankan      html  css  js  c++  java
  • [MSDN]WCF(11)大型数据和流

    说明:本内容来自微软的webcast,讲师为徐长龙。为了用手机阅读方便点,抄录存为txt。

    本次课程内容包括
    - 基本考虑事项
    - 编码
    - 数据的流模式

    基本考虑事项
    - WCF 是基于 XML 的通信基础结构
    - 编码数据:文本和二进制
      - 最常有的顾虑包括:认为与二进制格式相比 XML 的开销非常可观(因为其开始标记和结束标记的重复性),数值的编码肯能要大得多(因为它们是以文本值来表示的),并且无法有效地表示二进制(因为它们必须进行特殊的编码才能嵌入到文本格式中)。
      - 尽管上述以及其他许多类似的问题是存在的,但是 XML Web services 环境中的 XML 文本编码消息与旧式的远程过程调用(RPC)环境中的二进制编码消息之间的实际差异,通常远远小于最初的考虑中所预想的程度。
      - 虽然 XML 文本编码消息是透明的并且是”可读的“(也许难以理解),但比较而言,二进制消息则通常相当晦涩,在无工具的情况下很难解码。这种易读性方面的差异很容易使人忽视这样一点:二进制消息的负载中通常还携带内联元数据,这样会和 XML 文本消息一样增加开销。对于旨在提供松散耦合和动态调用功能的二进制格式,这种情况尤为突出。
      - 要在文本与二进制之间进行选择,不能简单地认为二进制消息总是小于 XML 文本消息。
      - XML 文本消息的一个明确而无可争议的优点是它们是基于标准的,并且提供最为广泛的互操作性选项和平台支持选择范围。
    - 二进制内容
      - 从最终的消息大小这一角度二样,二进制编码优于基于文本编码的一个方面就在于大型二进制数据项,例如,图片、视频、音效剪辑或者必须在服务语气使用者之间交换的任何其他形式的非透明二进制数据。为了使这些类型的数据也适合 XML 文本,常用的方法就是使用 Base64 编码对其进行编码
      - 在 Base64 编码字符串中,每个字符都表示原始8位数据的6位,这导致 Base64 的编码开销比率是 4:3 ,且未计算额外的格式字符(回车符/换行符),而按惯例这些字符通常是会添加的。虽然 XML 编码与二进制编码之间的差异显著与否,通常取决于具体情况,但是当传送500MB 负载时大小增加超过 33% 通常是不受欢迎的。
      - 为了避免这种编码开销,消息传输优化机制(MTOM) 标准允许将消息中包含的大型数据元素外部化,并将其作为无任何特殊编码的二进制数据随消息一起传送。利用 MTOM ,消息将以一种与带附件或嵌入式内容(图片和其他嵌入式内容)的简单邮件传输协议(SMTP)电子邮件类似的方式交换;MTOM 消息会打包为多部分/相关 MIME 序列,其中根部分是实际的 SOAP 消息。
      - 但是,与 Base64 一样,对于 MIME 格式,MTOM 也有一些必要的开销,这样仅在二进制数据元素的大小超过大约 1KB 时,才能体现出使用 MTOM 的好处。由于这一开销,如果二进制负载在改阀值之下,则 MTOM 编码的消息可能会大于对二进制数据使用 Base64 编码的消息。
    - 大型数据内容
      - 即使不考虑线路需求量,签名提及的500MB 负载也对服务和客户端本身提出了很到的考验。默认情况下,WCF 会以缓冲模式处理消息。这意味着消息的整个内容在发送前或接收后都存在于内存中。尽管对于大多数情形来说这是个很好的策略,并且是消息传递功能(如数字签名)和可靠传递所必需的,但是大型消息可能很容易最终耗尽系统资源。
      - 处理大型负载的策略是流。尽管消息(尤其是以 XML 表示的消息)通常会被认为是相对紧凑的数据包,但消息大小也可能达到GB数量级,从而与联系的数据流很相似,而不是易于处理的数据包。当以流模式而不是缓冲模式传输数据时,发送方会以流的形式将消息正文的内容提供给接收方,并且消息基础结构会不断地将就绪的数据从发送方转发给接收方。
      - 传输此类大型数据内容的最常见情形是传输具有以下特点的二进制数据对象:
        - 无法方便地分成消息序列。
        - 必须以及时方式传递。
        - 当开始传输时,还不是已全部就绪。
      - 对于不具有上述限制条件的数据,通常最好在一个会话的范围内发送消息序列,而不是一次性地发送一个到消息。


    编码
    - 编码定义了一组规则,规定消息在线路中的存在形式。
    - 编码器实现此类编码,并负责将 Message 内存中消息转变为可以通过网络发送的字节流或字节缓冲区(对于发送方而言)。在接收方,编码器会将一系列字节转变为内存中的消息。
    - WCF 包括三个编码器
      - TextMessageEncodeingBindingElement
        - 文本消息编码器是所有基于 HTTP 的绑定的默认编码器,并且是最关注互操作性所有自定义绑定的正确选择。此编码器读取和编写标准 SOAP 1.1/SOAP 1.2 文本消息,而不会对二进制数据进行任何特殊处理。如果消息的 MessageVersion 设置为 None , 则 SOAP 信封包装会从输出中省略,只有消息正文内容会进行序列化。
      - MtomMessageEncodeingBindingElement
        - MTOM 消息编码器是一个文本编码器,实现对二进制数据的特殊处理,默认情况下载任何标准绑定中都不会使用,因为它是一个严格按具体情况进行优化的实用工具。只有当二进制数据的量不超过某个阀值时, MTOM 编码才具有优势,如果消息包含的二进制数据超过了这个阀值,则这些数据会外部化到消息信封之后的 MIME 部分。
      - BinaryMessageEncodeingBindingElement
        - 二进制消息编码器是 Net* 绑定的默认编码器,当通信双方都基于 WCF 时,此编码器始终是正确的选择。二进制消息编码器使用 .NET 二进制 XML 格式,该格式时 XML 信息集 () 的 Microsoft 特定二进制表示法,与等效的 XML 1.0 表示法相比产生的需求量通常较小,并将二进制数据编码为字节流。
        - 每个标准绑定都包括一个预配置编码器,因此默认情况下带 Net* 前缀的绑定使用二进制编码器(通过包括 BinaryMessageEncodeingBindingElement 类),而 BasicHttpBinding 和 WSHttpBinding 类则使用文本消息编码器(通过 TextMessageEncodeingBindingElement 类)。
        - 通常,文本消息编码是要求互操作性的任意通信路径的最佳选择,而二进制消息编码则是其他任意通信路径的最佳选择。通常,对于单个消息而言,二进制消息编码生成的消息大小要小于文本编码,并且在通信会话期间消息大小会逐渐表的更小。与文本编码不同的是,二进制编码不需要对二进制数据使用特殊处理(例如,使用 Base64 ),但会将字节表示为字节。
    - 启用 MTOM
      - 当要求互操作性,并且必须发生大型二进制数据时, MTOM 消息编码是一个备选的编码策略,可以在标准 BasicHttpBinding 或 WSHttpBinding 绑定上启用它,方法是: 将该绑定的 MessageEncoding 属性设置为 Mtom, 或者将 MtomMessageEncodingBindingElement 编写为 CustomBinding 。
        <system.serviceModel>
          <bindings>
            <wsHttpBinding>
      <binding name="ExampleBinding" messageEncodeing="Mtom"/>
     </wsHttpBinding>
          </bindings>
        </system.serviceMode>
        因为 MTOM 是在绑定级别启用的,所有启用 MTOM 会影响给定终结点上的所有操作。通常情况下,只有在终结点交换超过 1KB 二进制数据的消息是,才应对它启用 MTOM
    - 编程模型
      - 不论在应用程序中使用三个内置编码器中的哪一个,在传输二进制数据方面的编程体验都是相同的。区别在于 WCF 如何基于数据类型来处理数据
      [DataContract]
      class MyData
      {
        [DataMember]
        byte[] binaryBuffer;
        [DataMember]
        string someStringData;
      }
      - 当使用 MTOM 是,将根据以下规则序列化上面的数据协定:
        - 如果 binaryBuffer 不是 null,并且有个别包含足够的数据,使得需要 Base64 编码所没有的 MTOM 外部化开销 ( MIME 头等等),则这些数据将外部化并作为二进制 MIME 部分随消息一起传送。如果未超过阀值,则数据会编码为 Base64 。
        - 字符串(和其他所有非二进制的类型)无论多大,始终表示为消息正文内的字符。


    数据的流模式
    - 当有大量的数据要传输时, WCF 中的流传输模式是整体缓冲和处理内存中消息的默认行为的一个可行的替代方法。
    - 如果数据无法分段、消息必须以及时的方式传递或者当传输启动时数据尚未完全就绪,则应考虑启用流模式,且只能对大型消息(带文本或二进制内容)启用流模式。
    - 当启用了流模式时,很多 WCF 功能都不能使用:
        - 无法执行消息正文的数字签名,因为它们需要对整个消息内容进行哈希运算。采用流模式的情况下,当构造和发送消息头是,内容尚未完全就绪,因此无法计算数字签名。
        - 加密依赖于数字签名来验证是否已正确地重新构造数据。
        - 如果消息在传输过程中丢失,可靠的会话必须在客户端上缓冲已发送的消息以便可以重新传递,并且在将消息传递给服务实现之前必须在服务上保留消息以保存消息顺序,一杯在未按顺序接受消息时可以按照正确的顺序重新排列消息。
    - 由于上述功能约束,只能对流模式使用传输级安全选项,并且无法打开可靠会话。因此,流模式仅在下列系统定义的绑定中可用:
        - BasicHttpBinding
        - NetTcpBinding
        - NetNamePipeBing
    - 由于 NetTcpBinding 和 NetNamePipeBing 的基础传输具有内在的可靠传递和基于连接的会话支持,因此与 HTTP 不同,这两个绑定在实践中受上述约束的影响非常小。
    - 流模式在消息队列 (MSMQ)传输中不可用,因此不能与  NetMsmqBinding 或 MsmqIntegrationBinding 类一起使用。消息队列传输仅支持限定消息大小的缓冲数据传输,而大多数情形小其他所有传输都不具有任何实际的消息大小限制。
    - 当使用对等通道传输时,流模式也不可用,因此流模式在 NetPeerTcpBinding 中不可用。
    - 请用流模式
      - 可以通过以下方式启用流模式:
        - 以流模式发送和接受请求,以缓冲模式接受和返回响应(StreamedRsequest)。
        - 以缓冲模式发送和接受请求,以流模式接受和返回响应(StreamedResponse)。
        - 在两个方向均以流模式发送/接收请求/响应(Streamed)。
      - 可以通过将传输模式设置为 Buffered 来禁用流模式,该设置是所有绑定的默认设置
        <system.serviceModel>
          <bindings>
            <basicHttpBinding>
      <binding name="ExampleBinding" messageEncodeing="Streaming"/>
     </basicHttpBinding>
          </bindings>
        </system.serviceMode>
    - 流式传输的编程模型
      - 流式传输的编程模型非常简单。要接收流数据,请指定具有单个 Stream 类型化输入参数的操作协定。为了返回流数据,应返回一个 Stream 引用。
        [ServiceContract(Namespace="http://Microsoft.SeriviceModel.Samples")]
        public interface IStreamedService
        {
          [OprationContract]
          Stream Echo(Stream data);
          [OprationContract]
          String RequestInfo(string query);
          [OprationContract(OneWay=true)]
          void ProvideInfo(Stream data);
        }
      - 上面示例中的操作 Echo 接收并返回一个流,因此应当用在具有 Streamed 的绑定上。对于操作 RequestInfo, StreamedResposne 最合适,因为他仅仅返回 Stream 。单向操作最适合于 StreamedRequest。
      - 请注意,向后面的 Echo 或 ProvideInfo 操作添加第二个参数会导致服务模型回复为缓冲策略,并使用流的运行时序列化表示。只有具有单个输入流参数的操作才与端对端请求流兼容。
    - 类似地,此规则也适用于消息协定。如下面的消息协定所示,在流模式的消息协定中,只能有一个正文成员。如果希望使用流传送更多信息,必须在消息头中携带这一信息。消息正文是专为流内容保留的。
      [MessageContract]
      public class UploadStreamMessage
      {
        [MessageHeader]
        public string appRef;
        [MessageBodyMember]
        public Stream data;
      }

  • 相关阅读:
    perl练习——FASTA格式文件中序列GC含量计算&perl数组排序如何获得下标或者键
    短序列组装Sequence Assembly(转载)
    MEGA软件——系统发育树构建方法(图文讲解) 转载
    R语言中的read.table()
    网络七层模型OSI(Open System Interconnection)
    MySQL报错“The server time zone value '�й���׼ʱ��' is unrecognized”
    JDK环境变量配置
    netstat命令
    敏捷方法论(Agile Methodologies)
    0 upgraded, 0 newly installed, 0 to remove and 6 not upgraded解决方法
  • 原文地址:https://www.cnblogs.com/htht66/p/2329238.html
Copyright © 2011-2022 走看看