Passing Large Files in Windows Communication Foundation (WCF) using Streaming and TCP

Windows Communication Foundation (WCF) Introduction

In Windows Communication Foundation (WCF) you can opt for buffering or streaming mode for transferring data. Both these modes have pros and cons. While the former is well suited for applications where you wouldn’t need to transfer large files or data, the later is best suited for such scenarios. This article discusses how we can pass large data or files using TCP binding in WCF.

Pre-requisites

To work with the concepts and the code examples presented in this article, you should have the following installed in your system:

  • Microsoft Visual Studio 2010 RC or higher

Let’s take a quick tour of the basics before we delve deep into the implementation details of the application.

What is Windows Communication Foundation (WCF)?

Windows Communication Foundation (WCF) is a platform that can be used to design and implement platform independent, scalable services. It is a framework from Microsoft that provides a platform for unification of a number of enterprise technologies under one roof. The MSDN states, “Windows Communication Foundation (WCF) is Microsoft’s unified programming model for building service-oriented applications. It enables developers to build secure, reliable, transacted solutions that integrate across platforms and interoperate with existing investments.”

Windows Communication Foundation Version 4 was released some time ago by Microsoft. Note that WCF was introduced as part of .NET Framework 3.0. There has been quite a few enhancements and new features introduced in WCF 4.0. These new features and enhancements are a major boost to productivity, flexibility and facilitate seamless development of service oriented applications. WCF 4.0 has eliminated the pain of specifying tedious configuration details to host WCF services. With enhancements to configuration, tracing, serialization, message queuing, service discovery, routing, and workflow services, WCF 4.0 promises to be the technology of choice for building scalable, service oriented, REST-based services.

Using Streamed Mode for Large Data Transfer

The WCF transport channels support two modes for transferring data. These are:

  • Buffered – in this mode, the complete data is held in the memory buffer until the transfer is complete in totality
  • Streamed – in this mode, the message body is exposed as a stream and data is read in chunks one at a time

Note that in the “buffered” mode, if the size of the data is more than the size of the buffer, the data cannot be transferred. In contrast, in the streamed mode, only the message headers are buffered.

You can optimize the WCF configuration and use streaming in lieu of buffering for faster data transfer and also, ensure that data of large sizes can be transferred from client to the server. Streamed mode is much better and yields better results as far as performance is concerned.

We just need to specify the following in the binding configuration to switch over to streamed mode from the buffered mode:

  <customBinding>
      <binding name="streamedBinding">
          <binaryMessageEncoding />
              <tcpTransport transferMode="Streamed" />
       </binding>
  </customBinding>

To change the transfer mode all you have to do is add a binding configuration to your application’s web.config file as shown below:

  <bindings>
   <basicHttpBinding>
   <binding name="StreamedResponseBinding"  transferMode="StreamedResponse"/>
   </basicHttpBinding>
  </bindings>

Once done, you can apply this configuration to the binding of your WCF service as shown below:

  <endpoint address="" binding="basicHttpBinding" bindingConfiguration="StreamedResponseBinding" contract="MyCustomDownloadService">

In the next section, we will discuss how we can implement a sample application that illustrates how TCP and Streaming can be used in conjunction to upload data of large sizes.

Implementing a Sample Application in WCF

In this section we will discuss the strategies involved to implement a simple client server application that can be used to transfer data of large sizes in WCF.

All you need to do is create two projects – one for the server and one for the client. The following method illustrates how you can use TCP binding at the server together with streaming to transfer large data chunks:

   private static void StartFileUploadService(String tcpURI, String mexURI)
           {
               ServiceHost serviceHost = new ServiceHost(typeof(FileTransfer));
               NetTcpBinding netTCPbinding = new NetTcpBinding();
               netTCPbinding.TransferMode = TransferMode.Streamed;
               netTCPbinding.MaxReceivedMessageSize = Int32.MaxValue;
               netTCPbinding.CloseTimeout = TimeSpan.MaxValue;

               serviceHost.AddServiceEndpoint(typeof(IFileTransfer
   ), netTCPbinding, new Uri(tcpURI));
               serviceHost.Description.Behaviors.Add(new ServiceMetadataBehavior());
               Binding mexBinding = MetadataExchangeBindings.CreateMexTcpBinding();
               serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, new Uri(mexURI));

               serviceHost.Open();
               Console.WriteLine("Service Just Started ... Press any Key to Stop");
               Console.Read();
               serviceHost.Close();
           }

   Note that FileTransfer is the service class that implements the IFileTransfer interface.

   [ServiceContract]
       interface IFileTransfer
       {
           [OperationContract]
           void Upload(Stream data);
       }

   class FileTransfer : IFileTransfer
       {
           public void Upload(Stream data)
           {
               //Necessary code
           }
       }
 

At the client you can then use the same binding information to upload a large file. The following method shows how you can achieve this:

  private static void StartUpload(String endpointAddress, String filePath)
          {
              NetTcpBinding netTCPbinding = new NetTcpBinding();
              netTCPbinding.TransferMode = TransferMode.Streamed;
              netTCPbinding.SendTimeout = TimeSpan.MaxValue;

              EndpointAddress endpointAddressObj = new EndpointAddress(endpointAddress);
              ChannelFactory<IDataUploader> channelFactory = new ChannelFactory<IDataUploader>(netTCPbinding, endpointAddressObj);

              IFileTransfer iFileTransfer = channelFactory.CreateChannel();
              iFileTransfer.Upload(File.Open(filePath, FileMode.Open));
              ((IClientChannel)iFileTransfer).Close();
          }

The service contract at the client side looks like this:

   [ServiceContract]
       interface IFileTransfer
       {
           [OperationContract]
           void Upload(Stream data);
       }
 

And you are done! Start the server application first, followed by the client. The client application would upload the file (passed as an argument to the StartUpload() method).

Suggested Readings

Here are a few good links to resources on this topic for further study on this topic:

Summary

In this article we have had a look at how we can take advantage of streaming mode of data transfer and TCP in Windows Communication Server (WCF)to transfer large data seamlessly. Happy reading!

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read