Thursday, April 30, 2009

WCF NetTcp services and net TCP port sharing

WCF provides a TCP-based network protocol (net.tcp://) for high-performance communication. WCF also introduced the Net.TCP Port Sharing Windows Service (SMSvcHost.exe )that enables net.tcp ports to be shared across multiple user processes. The Net.TCP Port Sharing Service accepts net.tcp:// connections on behalf of the worker processes that connect through it. When a socket connection arrives, the port sharing service inspects the incoming message stream to find its destination address. Based on this address, the port sharing service can route the data stream to the application that ultimately processes it.
When a WCF service that uses net.tcp:// port sharing opens, the WCF TCP transport does not directly open a TCP socket in the application process. Instead, the transport registers the service’s base address URI with the Net.TCP Port Sharing Service and waits for the port sharing service to listen for messages on its behalf. The port sharing service dispatches messages addressed to the application service as they arrive.
When you expose a WCF service using NetTcpBinding, there is a property on the binding called “PortSharingEnabled”



<bindings>
<nettcpbinding name="binding" portsharingenabled="true">
</bindings>


// configure a binding with TCP port sharing enabled
NetTcpBinding binding = new NetTcpBinding();
binding.PortSharingEnabled = true;


If you target for example using port 15138 and port sharing is not allowed and another application is already using port 15138, this service would throw a “System.ServiceModel.AddressAlreadyInUseException” when opened.
The default path of SMSvcHost.exe is: "C:\WINDOWS\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ ". The root directory also contains a configuration file called SMSvcHost.exe.config.



<net.tcp listenbacklog="10" maxpendingconnections="100" maxpendingaccepts="2" receivetimeout="00:00:10" teredoenabled="false">
<allowaccounts>
<add securityidentifier="S-1-5-18">
</allowaccounts>
</net.tcp>


SMSvcHost.exe.config manages the list of all those processes that might use the port sharing feature and list of user accounts that can run this Windows Service. By default, permission to use the port sharing service is granted to system accounts (LocalService, LocalSystem, and NetworkService) as and to the Administrators group.

On windows vista or windows 7, if you don’t turn off the UAC feature, even members of the Administrators group cannot use the port sharing service without elevated permissions. To allow these users to make use of the port sharing service without elevation, the user's SID , or the administrative group SID must be explicitly added to the section of SMSvcHost.exe.config.

MaxPendingAccept is a socket-level property that describes the number of "pending accept" requests to be queued. The default value is 2. According to the WCF Team, you shouldn’t increase “maxPendingAccepts” too much. Up to 10 would be a good number. It means it spawns 10 concurrent threads to pull connections.

MaxPendingConnections This limits the number of simultaneous client connections awaiting dispatch. If this value is too low, client connection attempts may be rejected by the service. If it is too high, the service may appear slow or unresponsive to clients during heavy load periods. This property should be set to a value that allows the service to run at full capacity, and no higher.

TeredoEnabled indicates whether the port sharing service uses Microsoft Teredo service to listen on TCP ports on behalf of WCF services. This property is applicable only on Windows XP SP2, SP3 and Windows Server 2003. Windows Vista has a machine-wide configuration option for Teredo, so when running Windows Vista, this property is ignored. More about Teredo: Teredo Overview

NetTcpPortSharing also plays an important role in WAS architecture, which I’d like to dicuss later.