PeteAC
PeteAC

Reputation: 799

How to achieve concurrent requests to WCF service, from 1 client, using Net.TCP

I have a C#.Net IIS-hosted WCF server and a C#.Net WCF client of it. Both support HTTP(S) and Net.TCP protocols. We get correct results, using both protocols.

Because of the nature of the server-side processing, overall performance is better if a few requests are in flight, between the server and single client, at once. Using HTTP, this works fine - by monitoring the activity of the server, I can see that it really is handling multiple requests at once. But using Net.TCP, the server-side activity is sequential - it doesn't start on the next request until the current request is finished.

I would like to be able to use Net.TCP with the same or better performance than HTTP, but I need to sort out this concurrent execution problem.

Server side config snippet: -

<netTcpBinding>
    <binding name="ServiceLayerNetTcpBinding" maxReceivedMessageSize="20000000" portSharingEnabled="true">
      <security mode="Transport">
        <transport clientCredentialType="Windows"/>
      </security>
    </binding>
</netTcpBinding>
...
<protocolMapping>
  ...
    <add scheme="net.tcp" binding="netTcpBinding" bindingConfiguration="ServiceLayerNetTcpBinding" />
</protocolMapping>

Client-side programmatic configuration: -

var netTcpBinding = new NetTcpBinding(SecurityMode.Transport)
                                      {
                                          MaxReceivedMessageSize = MaxReceivedMessageSize,
                                          SendTimeout = TimeSpan.FromMinutes(SendTimeoutMinutes)
                                      };
        netTcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;

Can anyone suggest what I need to do, to make Net.TCP behave the same as HTTP(S), regarding concurrent execution of requests on server?

Upvotes: 3

Views: 815

Answers (1)

PeteAC
PeteAC

Reputation: 799

I think that I found the problem.

My services were not declared with an explicit ConcurrencyMode. So they defaulted to ConcurrencyMode=Single. However, they were all set to InstanceContextMode=PerCall.

It seems that the HTTP(S) and Net.TCP protocols result in different interpretations of this combination. In HTTP(S), we end up with multiple instances of a service active at once, all processing one request each. But in Net.TCP, it doesn't happen like that - the ConcurrencyMode.Single seems to "win", resulting in only one request being processed at a time.

However, my services are all stateless, so they can happily be declared as ConcurrencyMode=Multiple, which results in both HTTP(S) and Net.TCP running several requests at once.

I would be interested to know if this is a well-understood and documented difference between the HTTP(S) and Net.TCP bindings, which I should have known about, or something that can only be found by experimentation.

Upvotes: 2

Related Questions