Push-Style Streaming Sample

Download sample

Windows Communication Foundation (WCF) has different models for dealing with streamed data. WCF implements a "pull" model in which the application code (the service) returns an instance of Stream and relies on the lower-level infrastructure to pull data from this stream and write it out to the network. ASP.NET uses a "push" model: the infrastructure creates the output stream and makes it available to the application code (the IHttpHandler) using the OutputStream property. The application code is responsible for writing data to the stream. Both models are valid approaches and it is common to bridge the two methods in some way.

Note

This sample requires that .NET Framework version 3.5 is installed to build and run. Visual Studio 2008 is required to open the project and solution files.

This sample demonstrates how to address streaming using ASP.NET scenarios using the Web programming model.

Service

The service implements two operations that illustrate common ASP.NET scenarios, as shown in the following code.

[OperationContract]
        [WebGet(UriTemplate = "images")]
        public Message GetDynamicImage()
        {
            string text = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["text"];

            Bitmap theBitmap = GenerateImage(text);

            Message response = StreamMessageHelper.CreateMessage(MessageVersion.None, "", "image/jpeg",
                delegate(Stream outputStream)
                {
                    theBitmap.Save(outputStream, ImageFormat.Jpeg);
                });

            return response;
        }

Note that the GetDynamicImage() method returns Message rather than Stream. A custom implementation of BodyWriter (DelegateBodyWriter) is used to implement the "push" streaming semantics.

DelegateBodyWriter takes a delegate parameter, which takes the output stream as input.

public delegate void StreamWriterDelegate(Stream output);

class DelegateBodyWriter : BodyWriter
    {
        StreamWriterDelegate writer;

        public DelegateBodyWriter(StreamWriterDelegate writer)
            : base(false)
        {
            this.writer = writer;
        }

        protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
        {
            writer.WriteStartElement("Binary");

            XmlWriterStream stream = new XmlWriterStream(writer);
            this.writer(stream);
            stream.Close();

            writer.WriteEndElement();
        }
    }

The StreamWriterDelegate delegate is then invoked during the execution of RawStreamResponseMessage.OnWriteBodyContents().

The XmlWriterStream class is an adapter that provides a Stream API over the XmlDictionaryWriter used by the Message class.

You can view the output of the sample in a Web browser. To interact with the sample, navigate to the following URLs while the service is running.

https://localhost:8000/images?text=Hello, world!

https://localhost:8000/text?text=Hello, world!

To set up, build, and run the sample

  1. Ensure that you have performed the One-Time Set Up Procedure for the Windows Communication Foundation Samples.

  2. To build the C# or Visual Basic .NET edition of the solution, follow the instructions in Building the Windows Communication Foundation Samples.

  3. To run the sample in a single- or cross-machine configuration, follow the instructions in Running the Windows Communication Foundation Samples.

See Also

Other Resources

Streaming Feeds Sample

© 2007 Microsoft Corporation. All rights reserved.