Saturday, January 10, 2009

How to send/receive large data in WCF

Sometimes, we need to send or receive large data in WCF. For example, if we want to send a large xml file from WCF-client to WCF-service then we cannot send this file using default configuration of binding. We need to do some tweaks to send large data. Let us see some of the properties of binding which can help us to increase the size of the send/receive message:


MaxBufferSize - gets or sets a value that specificies the maximum size, in bytes, of the buffer used to messages in memory.


MaxReceivedMessageSize – gets or sets the maximum size of the received message that is processed by binding. The default value is 65,536 bytes


If we change the default value of these two properties and set the maximum value supported by WCF, we can increase the size of sending/receiving message.

The following code snippet shows how you can set these properties.
NetTcpBinding netTcpBinding = new NetTcpBinding();
netTcpBinding.MaxBufferSize = 65536;//set max value supported by WCF
netTcpBinding.MaxReceivedMessageSize = 204003200;//set max value

These settings have to be in both client and server side. By setting the above properties, we can send/receive around 5MB.


There is a problem if we follow the above approach. To understand the problem, we need to know how WCF works while sending/receiving data.


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. Therefore, for sending/receiving large data, this can create a huge problem. 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.


We can change the transfer mode of the service by changing the following property.

TransferMode – specificies whether messages are buffered or streamed or a request, response.

The following code snippet shows how you can set this property:
NetTcpBinding netTcpBinding = new NetTcpBinding();
netTcpBinding.TransferMode = TransferMode.Streamed;

However, setting the TransferMode as a Streamed has some limitations. If we use streamed transfer mode then there are the following constraints in the operation contract:
· Parameter can be only stream type.
· Return type has to be stream type.
· Number of parameters have to be less than or equal to one.
· Only the BasicHttpBinding, NetTcpBinding, and NetNamedPipeBinding support streaming.

Setting the TransferMode as a Streamed is good choice when you will send/receive large file.

Hope this help!