WCF service run very slow with reliable session

May 19 2015 6:38 AM
The server is hosted on a WPF application and use net.tcp binding for duplex channel. We have the client code (.NET 4.0) to send a burst of async request to the server. After reliable session is on, the service ran very slow (approx. 50-100 call/s) and callback messages aren't sent to the client.

The issue happens in two cases.
1. We send approx. 1000 messages per seconds to the server. If we send 300-500 messages is all OK.
2. We send a single message to the server with size 10-20 MB. And in this case messages from the server callbacks wait until the big message is sending.

Does anyone know why this happen? Is there anyway to avoid this?

The slowness didn't happen if we turned OFF the Reliable session feature.

Below are the codes and configuration for the server and client.
 
Server's binding:
(Also we tried to use standart net.tcp binding istead of custom one but it didn't help)
 
                                       var customBinding= new CustomBinding()
                    {
                        CloseTimeout = new TimeSpan(0, 1, 10),
                        OpenTimeout = new TimeSpan(0, 1, 10),
                        ReceiveTimeout = new TimeSpan(0, 5, 30),
                        SendTimeout = new TimeSpan(0, 2, 0)
                    };
                       customBinding.Elements.Add(new BinaryMessageEncodingBindingElement()
                         {                         
                             MessageVersion = MessageVersion.Default,
                             ReaderQuotas =
                             {
                                 MaxBytesPerRead = int.MaxValue,
                                 MaxDepth = int.MaxValue,
                                 MaxNameTableCharCount = int.MaxValue,
                                 MaxStringContentLength = int.MaxValue,
                                 MaxArrayLength = int.MaxValue
                             }
                         });
                       customBinding.Elements.Add(new ReliableSessionBindingElement()
                            {
                                AcknowledgementInterval = TimeSpan.FromMilliseconds(1),
                                FlowControlEnabled = true,
                                InactivityTimeout = new TimeSpan(0, 30, 0),
                                MaxPendingChannels = 1000,
                                MaxRetryCount = 10,
                                MaxTransferWindowSize = 4096,
                                Ordered = true,
                                ReliableMessagingVersion = ReliableMessagingVersion.Default
                            });
                              var tcpTransport = new TcpTransportBindingElement()
                       {
                           ChannelInitializationTimeout = TimeSpan.FromSeconds(30),
                           ConnectionBufferSize =8192,
                           ListenBacklog = 10000000,
                           MaxBufferPoolSize = int.MaxValue,
                           MaxBufferSize = int.MaxValue,
                           MaxOutputDelay= TimeSpan.FromMilliseconds(1000),
                           MaxPendingAccepts = int.MaxValue,
                           MaxPendingConnections = 40000,
                           MaxReceivedMessageSize = int.MaxValue,
                           PortSharingEnabled = true,
                           TransferMode = TransferMode.Buffered,
                       };
                       tcpTransport.ConnectionPoolSettings.GroupName = "OnlineList";
                       tcpTransport.ConnectionPoolSettings.IdleTimeout = TimeSpan.FromMinutes(5);
                       tcpTransport.ConnectionPoolSettings.LeaseTimeout = TimeSpan.FromMinutes(5);
                       tcpTransport.ConnectionPoolSettings.MaxOutboundConnectionsPerEndpoint = 40000;
                                                         customBinding.Elements.Add(tcpTransport);
 
 
Client side configuration: 
 
                              CloseTimeout = new TimeSpan(0, 0, BaseTimeout),
                OpenTimeout = new TimeSpan(0, 0, BaseTimeout),
                ReceiveTimeout = new TimeSpan(0, 0, BaseTimeout*4),
               SendTimeout = new TimeSpan(0, 0, BaseTimeout),
                ///Security
                Security = { Mode = SecurityMode.None },
                ///Session
                ReliableSession =
                {
                    Enabled = true,
                    InactivityTimeout = new TimeSpan(1, 10, 0),
                    Ordered = true
                },
                ///Buffer and message
                MaxBufferPoolSize = int.MaxValue,
                MaxBufferSize = int.MaxValue,
                MaxReceivedMessageSize = int.MaxValue,
                ///ReaderQuotas
                ReaderQuotas =
                {
                    MaxBytesPerRead = int.MaxValue,
                    MaxDepth = int.MaxValue,
                    MaxNameTableCharCount = int.MaxValue,
                    MaxStringContentLength = int.MaxValue,
                    MaxArrayLength = int.MaxValue
                },
                //Other
                PortSharingEnabled = true,
                MaxConnections = 1000,
                TransactionFlow = true,
                TransferMode = TransferMode.Buffered,