• [WCF编程]10.操作:流操作


    一、流操作概述

        在默认情况下,当客户端调用服务时,服务只有在接收到完整的消息后才会被调用,同样,客户端只有在包含了调用结果的返回消息被完整接受时,才会解除对它的阻塞。

        对于数据量小的消息,这种交换模式提供了简单的编程模型,因为接收消息的耗时较之处理消息本身而言是微不足道的。然而,一旦需要处理数据量较大的消息,如包含了多媒体内容、大文本或数据块的消息,如果每次都要等到完整接收消息之后才能解除阻塞,则未免不太现实。

        为了解决这样的问题,WCF允许接收到(客户端或服务)在通过通道接收消息的同时,启动对消息数据的处理。这种类型的处理过程称为流传输模型。对于具有大量负载的消息而言,流操作改善了系统的吞吐量和响应速度,因为在发送 或接收消息的同时,不管是发送方还是接收方都不会被阻塞。

    二、I/O流

        若要处理消息流,WCF需要使用.NET的Stream类。事实上,契约操作对流的使用看起来和传统的I/O方法并无区别。在.NET中,Stream类是所有I/O的基类(如FileStream、NetworkStream和MemoryStream类),它允许将I/O资源中的内容转化为流。我们需要做的就是返回或接收一个Stream类型的操作参数,如下例所示:

    [ServiceContract]
        interface IMyContract
        {
            [OperationContract]
            System.IO.Stream StreamReply1();
    
        [OperationContract]
        System.IO.Stream StreamReply2(</span><span style="color: #0000ff">out</span><span style="color: #000000"> System.IO.Stream stream);
    
        [OperationContract]
        </span><span style="color: #0000ff">void</span><span style="color: #000000"> StreamRequest(System.IO.Stream stream);
    
        [OperationContract(IsOneWay </span>= <span style="color: #0000ff">true</span><span style="color: #000000">)]
        </span><span style="color: #0000ff">void</span><span style="color: #000000"> OneWayStream(System.IO.Stream stream);
    }</span></pre></div>
    

        注意,只能将抽象类型Stream类型或特定的可序列化的子类(如MemoryStream)作为操作参数。诸如FileStream这样的子类都不支持序列化,因为使用基类Stream其实是无奈之举。

        WCF允许服务将请求消息、应答消息,以及请求与应答消息转换为流。

    三、流操作与绑定

        只有TCP、IPC和基本的HTTP绑定支持流操作。在默认的情况下,这些绑定是禁止流操作的。即使使用了Stream对象,绑定仍然会将消息整体放到缓存中。我们需要根据所需的流模式,通过设置TrasferMode属性启用流操作,例如,以下使用BasicHttpBingding时。

    public enum TransferMode
    {
        //对请求和响应消息进行缓冲处理
        Buffered,
        //对请求和响应消息进行流式处理
        Streamed,
        //对请求消息进行流式处理,对响应消息进行缓冲处理
        StreamedRequest,
        //对请求消息进行缓冲处理,对响应消息进行流式处理
        StreamedResponse
    }
    

    public class BasicHttpBingding:Bingding
    {
    public TransferMode TransferMode{get;set}
    .......
    }

        TransferMode.Streamed支持所有的流模式,也是唯一支持第二节例子中定义的所有操作。但是,如果契约只包含特定的流类型,如以下转换为流的应答消息,则可以包含一个设置为buffered的请求消息,也可以通过选择TransferMode.StreamedResponse将消息转化为流:

    [ServiceContract]
    interface IMyConttract
    {
        //流的应答消息
        [OperationContract]
        Stream GetStream1();
        [OperationContract]
        int MyMethod();
    }

        在客户端或服务段(或同时在两端),必须为每个所需的流模式配置绑定。

    <system.serviceModel>
          <client>
             <endpoint 
                address  = "http://localhost:8000/MediaService" 
                binding  = "basicHttpBinding"
                bindingConfiguration = "StreamedHTTP"
                contract = "IMediaService"
             />
          </client>
          <bindings>
             <basicHttpBinding>
                <binding name = "StreamedHTTP" transferMode="Streamed">
                </binding>
             </basicHttpBinding>
          </bindings>
       </system.serviceModel>

    四、流操作与传输

        WCF的流操作只不过是一种良好的编程模型。从根本上讲,传输自身并不支持流操作,它默认的最大消息长度为64KB。这样的数据可能存在问题时,开发者可能希望使用流操作,转换为流的消息往往会非常大。如果默认的限制不够大,开发者可以增加接收端消息的最大长度,以适应大数据量的消息。可以通过MaxReceivedMessageSize属性,以获得期望的最大消息长度。

    public class BasicHttpBingding:Bingding,...
    {
        public long MaxReceivedMessageSize{get;set;}
    }

        可以在运行时采用反复试验找出消息的大小,然后设置相应的绑定。

        通常,我们应避免使用编程方式,而是将一段配信息放到配置文件中,因为消息大小的改变通常发生在部署阶段:

    <bindings>
         <basicHttpBinding>
            <binding name = "StreamedHTTP" transferMode="Streamed" maxReceivedMessageSize ="120000">
            </binding>
         </basicHttpBinding>
    </bindings>

        当使用流操作时,不能使用消息层的传输安全。这是因为TCP、IPC和基本的HTTP绑定支持流操作,对于这些绑定,通常不能使用消息安全。在使用TCP绑定执行流操作时,同样不能启用可靠消息传输。

    示例下载:下载

  • 相关阅读:
    阿里云配置mysql远程连接
    [转载]Lodop用户应对谷歌浏览器停用Plugin技术的处理办法
    利用lodop打印控件轻松实现批量打印
    ThinkPHP 中M方法和D方法的具体区别
    Codeforces
    POJ
    HDU
    POJ
    POJ
    HDU
  • 原文地址:https://www.cnblogs.com/zxj159/p/3994599.html
Copyright © 2020-2023  润新知