Reputation: 799
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
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