Section 5.5. Streaming


5.5. Streaming

By default, when the client and the service exchange messages, these messages are buffered on the receiving end and delivered once the entire message is received. This is true whether it is the client sending a message to the service or the service returning a message to the client. When the client calls the service, the service is invoked when the message is received in its entirety. The client is unblocked when the returned message with the results of the invocation is received in its entirety. For sufficiently small message sizes, this exchange pattern provides for a simple programming model because the latency caused by receiving the message is usually negligible compared with the message processing itself. However, when it comes to much larger messages, such as ones involving multimedia content, large files, or batches of data, blocking every time until the message is received may be impractical. To handle such cases, WCF enables the receiving side (be it the client or the service) to start processing the data in the message while the message is still being received by the channel. Such processing is called streaming transfer mode. With large payloads, streaming provides improved throughput and responsiveness because neither the receiving nor sending side is blocked when sending or receiving the message.

5.5.1. I/O Streams

For message streaming, WCF requires the use of the .NET Stream class. In fact, the contract operations used for streaming look just like conventional I/O methods. The Stream class is the base class of all the I/O streams in .NET (such as the FileStream, NetworkStream, and MemoryStream classes) allowing you to stream content from any of these I/O sources. All you need to do is to return or receive a Stream as an operation parameter, as shown in Example 5-17.

Example 5-17. Streaming operations

 [ServiceContract] interface IMyContract {    [OperationContract]    Stream StreamReply1( );    [OperationContract]    void StreamReply2(out Stream stream);    [OperationContract]    void StreamRequest(Stream stream);    [OperationContract(IsOneWay = true)]    void OneWayStream(Stream stream); } 

Note that you can only define as an operation parameter the abstract class Stream or a specific serializable subclass such as MemoryStream. Subclasses such as FileStream are not serializable and you will have to use the base Stream.

WCF lets services stream the reply, the request, or both the request and the reply, using one-way streaming.

To stream the reply, either return the Stream from the operation:

 [OperationContract] Stream GetStream1( ); 

or provide the stream as an out parameter:

 [OperationContract] void GetStream2(out Stream stream); 

To stream the request, provide a Stream as a method parameter:

 [OperationContract] void SetStream1(Stream stream); 

Finally, you can even stream the request for a one-way operation:

 //One-way streaming [OperationContract(IsOneWay = true)] void SetStream2(Stream stream); 

5.5.2. Streaming and Binding

Only the BasicHttpBinding, NetTcpBinding, and NetNamedPipeBinding support streaming. With all these bindings streaming is disabled by default, and the binding will buffer the message in its entirety, even when a Stream is used. You have to enable streaming by setting the transferMode Boolean property according to the desired streaming mode; for example, when using BasicHttpBinding:

 public enum TransferMode {    Buffered, //Default    Streamed,    StreamedRequest,    StreamedResponse } public class BasicHttpBinding : Binding,... {    public TransferMode TransferMode    {get;set;}    //More members } 

transferMode.Streamed supports all streaming modes, and is the only transfer mode that can support all the operations in Example 5-17. However, if the contract contains only a specific type of streaming such as streamed reply:

 [ServiceContract] interface IMyContract {    //Stream reply    [OperationContract]    Stream GetStream1( );    [OperationContract]    int MyMethod( ); } 

you can have a buffered request and streamed reply by selecting transferMode.StreamedResponse.

You will need to configure the binding on the client or service side (or both) per the required stream mode:

 <configuration>    <system.serviceModel>       <client>          <endpoint             binding = "basicHttpBinding"             bindingConfiguration = "StreamedHTTP"             ...          />       </client>       <bindings>          <basicHttpBinding>             <binding name = "StreamedHTTP" transferMode = "Streamed">             </binding>          </basicHttpBinding>       </bindings>    </system.serviceModel> </configuration> 

5.5.3. Streaming and Transport

It is important to realize that WCF streaming is merely a programming model nicety. The underlying transport itself (such as HTTP) is not streamed, and the default maximum message size is set to 64 KB. This may be a problem with the sort of data you are likely to use streaming with, because streamed messages tend to be very large (hence the motivation for streaming in the first place). You may find the need to increase the max message size on the receiving side to accommodate the large message by setting the MaxReceivedMessageSize property to the expected maximum message size:

 public class BasicHttpBinding : Binding,... {    public long MaxReceivedMessageSize    {get;set;}    //More memebrs } 

Typically you would place that piece of configuration in the config file and avoid doing it programmatically, as message size tends to be deployment-specific:

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

5.5.4. Stream Management

When the client passes a request stream to the service, the service may read from the stream long after the client is gone. The client has no way of knowing when the service is done using the stream. Consequently the client should not close the streamWCF will automatically close the client-side stream once the service is done using the stream.

A similar problem exists when the client interacts with a response stream. The stream was produced on the service side, and yet the service does not know when the client is done using the stream, nor can WCF help, because it has no idea what the client is doing with the stream. The client is always responsible for closing reply streams.

When you use streaming, you cannot use message-level transfer security. You will see more on security in Chapter 10. When streaming with the TCP binding, you also cannot enable reliable messaging.


There a few additional implications on streamed messages: first you need to synchronize access to the streamed content; for example, by opening the file stream in a read-only mode to allow other parties to access the file, or opening the stream in an exclusive mode to prevent others from accessing it if so required. In addition, you cannot use streaming with a sessionful servicethe session implies a lock-step execution and has a well-defined demarcation, unlike streaming, which may be continuous for a long period of time.




Programming WCF Services
Programming WCF Services
ISBN: 0596526997
EAN: 2147483647
Year: 2004
Pages: 148
Authors: Juval Lowy

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net