Click here to Skip to main content
14,976,234 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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)
C#
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:
C#
BaseTimeout = 7000;
        int.MaxValue = 2147483647;
        ///Common
                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,
Posted
Comments
virusstorm 19-May-15 14:28pm
   
Have you considered adding additional servers to create a web farm using some sort of load balancer?

If you logically think about the messages you are sending, 300 messages per second at 10 megabytes a piece comes out to 3 gigabytes of data per second. When up that to 1000 messages per second, you are at 10 gigabytes of data. To me, your problem doesn't sound like the code, rather the network interface simply can't keep up with all of the data coming in.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900