flayn
flayn

Reputation: 5322

ChannelFactory: Channel Close() not closing connection (netstat shows ESTABLISHED)

I have a WPF application that is communicating with a WCF server.

I am using one ChannelFactory to create channels for each call:

var channel = _channelFactory.CreateChannel();
var contextChannel = channel as ICommunicationObject;
try
  {
      channel.DoSomething();
  }
  catch (Exception)
  {
      contextChannel?.Abort();
      throw;
  }
  finally
  {
      contextChannel?.Close();
  }

There are many requests to the server when starting the application and at some points it grinds to an halt and I get timeouts. Looking at netstat I see a few ESTABLISHED connection to the server,

When I change the ServicePointManager.DefaultConnectionLimit to 10, I can process more calls to the server, but it still comes to a halt after some time with a timeout exception.

Setting ServicePointManager.DefaultConnectionLimit to int.MaxValue processes all my request, but I have about 720 ESTABLISHED connections to the server (netstat on the server gives me the same result).

I am confused about two things here:

  1. It looks like WCF is not pooling connections, but creating a new connection for each request
  2. Even after a I close the channel, the connection seems to remain established.

I also checked the ServicePointManager.FindServicePoint(new Uri("https://server:3000")); and it confirms that CurrentConnections are at the limit I set as the ServicePointManager.DefaultConnectionLimit.

I have reduced the ServicePointManager.MaxServicePointIdleTime to 500, this closes the connections faster, but it still creates a connection for each call I make.

How can I convince the channel factory to reuse exising channels when communicating with my server.

This is my binding:

new WebHttpBinding
{
    TransferMode = TransferMode.Streamed,
    ReceiveTimeout = TimeSpan.FromMinutes(1),
    SendTimeout = TimeSpan.FromMinutes(1),
    MaxReceivedMessageSize = 2147483647,
    MaxBufferPoolSize = 2147483647,
    ReaderQuotas =
        {
            MaxDepth = 2147483647,
            MaxStringContentLength = 2147483647,
            MaxArrayLength = 2147483647,
            MaxBytesPerRead = 2147483647,
            MaxNameTableCharCount = 2147483647
        },
    Security = new WebHttpSecurity() { Mode = WebHttpSecurityMode.Transport, Transport = new HttpTransportSecurity() { ClientCredentialType = HttpClientCredentialType.None } }
};

Upvotes: 0

Views: 822

Answers (1)

flayn
flayn

Reputation: 5322

Turns out that some of the streams that the server returns were not closed properly, which caused the client to keep the connection open, even after Close() was called.

If Close() is called and the stream that was returned to the client has not been closed, the connection will not be reused and the client will get a TimeoutException at some point.

Thanks to Zhang Lan for giving the hint in the MSDN forums: https://social.msdn.microsoft.com/Forums/vstudio/en-US/a91a6d05-05ae-402e-bf7d-306289c4d0e2/wcf-with-streaming-mode-timeout-after-two-calls-when-client-and-service-are-not-on-same-machine?forum=wcf

Upvotes: 0

Related Questions