Streaming data with WCF

WCF defaults to buffering the entire message before transmitting. It is possible to stream your data so data can start to be processed on the server or client before it entirely transmitted.

Comprehensive documentation can be found on

Set server app.config to be:

<bindings>
   <netTcpBinding>
      <binding name="customNetTcpBinding"
               maxBufferSize="200000000"
               maxReceivedMessageSize="200000000"
               transferMode="Streamed">
      </binding>
    </netTcpBinding>
</bindings>

The above should allow files of up to about 190mb to be streamed.

The key attribute is:

 transferMode="Streamed" - default is buffered

The client config required is.

<bindings>
   <netTcpBinding>
      <binding name="NetTcpBinding_IFileUpload" transferMode="Streamed" />
   </netTcpBinding&gt;
</bindings>

For a complete example, our response type definition:

public class UploadFileResponse
{
   public string Message { get; set; }
}

Service interface:

[ServiceContract]
public interface IFileUpload
{
   [OperationContract]
   UploadFileResponse UploadFileViaStream(Stream fileStream);
}

Service class implementation:

public class FileUploadService : IFileUpload
{
   public UploadFileResponse UploadFileViaStream(Stream stream)
   {
      var response = new UploadFileResponse();

      using (var fileStream = File.Create("teststream"))
      {
         stream.CopyTo(fileStream);
      }

      response.Message = "Successfully completed";
      return response;
   }
}

And if we look at Microsoft Service Trace Viewer we can see that it is indeed streaming our data:

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
	<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
		<EventID>0</EventID>
			<Type>3</Type>
			<SubType Name="Information">0</SubType>
			<Level>8</Level>
			<TimeCreated SystemTime="2014-03-06T18:17:25.8188503Z" />
			<Source Name="System.ServiceModel.MessageLogging" />
			<Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" />
			<Execution ProcessName="WCFLargeFileAPI.vshost" ProcessID="2984" ThreadID="11" />
			<Channel />
	</System>
<ApplicationData>
<TraceData>
	<DataItem>
		<MessageLogTraceRecord Time="2014-03-06T18:17:25.8188503+00:00" Source="ServiceLevelReceiveRequest" Type="System.ServiceModel.Channels.StreamedMessage" xmlns="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace">
		<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
			<s:Header>
				<a:Action s:mustUnderstand="1">http://tempuri.org/IFileUpload/UploadFileViaStream</a:Action>
				<a:MessageID>urn:uuid:7e9efd61-3868-481c-ab5d-17c19f93526a</a:MessageID>
				<a:ReplyTo>
				<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
			</a:ReplyTo>
			<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink"<uIDPo1d4u3tgmU9MjjApxUoHeD8AAAAABU27dsajsEGNM7x3QCkSz7rxDZ3MpsRFrpqvfafNFOAACQAA</VsDebuggerCausalityData>
			<a:To s:mustUnderstand="1">net.tcp://localhost:7891/<a:To>
			</s:Header>
		<s:Body>... stream ...</s:Body>
		</s:Envelope>
		</MessageLogTraceRecord>
	</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>
Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)
This entry was posted in Uncategorized. Bookmark the permalink.