Hosting in IIS using NetTcpBinding
I've recently run across several non-intuitive steps when trying to host a simple Hello-World WCF service in IIS using NetTcpBinding. These tips apply to IIS7. There's also a great article that quickly goes through setting up TCP activation:
https://msdn.microsoft.com/en-us/library/ms731053.aspx
Now, when I did a quick ad-hoc Net.Tcp service, the "gotchas" I ran into were:
- Make sure the Net.Tcp Listener Adapter and Net.Tcp Port Sharing Service are both running.
- If you're running on Server2k8, these appear under ServerManager -> Configuration -> Services
- Make sure to enable the Net.Tcp protocol in site bindings for your website
- In inetmgr, right-click the site (Probably "Default Web Site")
- Select Edit Bindings
- If net.tcp isn't already there, you can add it with the default port like so:
- click Add…
- Type = net.tcp
- Binding information = 808:*
- Make sure to actually allow the Net.Tcp protocol under your site's advanced settings in IIS.
- The symptom of not doing this is the exception:
The message could not be dispatched because the service at the endpoint address 'net.tcp://<your service>.svc' is unavailable for the protocol of the address.
- To fix it, select your app in inetmgr, click Advanced Settings… in the Actions pane
- Under Enabled Protocols, add net.tcp. The format is that each protocol must be comma-separated.
- Such as: http,net.tcp
- Make sure there is no space between the protocols; it's just a comma.
- Make sure to close the client, regardless of whether it's successful or not. You can do this in a finally block; close it if the state is Opened, otherwise, abort it if it isn't already closed.
if (client != null)
{
IChannel clientChannel = (IChannel)client;
if (clientChannel.State == CommunicationState.Opened)
{
clientChannel.Close();
}
else if (clientChannel.State != CommunicationState.Closed)
{
clientChannel.Abort();
}
}
- If you think your service is in a bad state and you want to start fresh, I found the following steps reliable:
- Call iisreset
- In ServerManager -> Configuration -> Services, stop the Net.Tcp Listener Adapter and the Net.Tcp Port Sharing Service. Then start them again.
Note: Typically, in an ad-hoc testing or prototyping environment, one ends up pinging the service with a client repeatedly, not necessarily closing the client each time. This can leave the service in a bad state because the channels are opened on the server side. Of course, this is typically mitigated by the ReceiveTimeout on the binding, but if you are just ad-hoc testing something, you might not want to always wait for ReceiveTimeout before trying the request again with a different client. And dropping ReceiveTimeout temporarily to something ridiculously small only makes it timeout when you are debugging. So recycling the services and IIS is meant only as an on-the-fly way to force the release of any opened channels. One obviously wouldn't need to do this in a production environment because of the various server-side timeouts.
- I wouldn't call this non-intuitive, but make sure your firewall isn't blocking the port on which you're hosting.
- Of course, you have to have Non-Http Activation enabled!
Comments
Anonymous
January 24, 2013
Dude! Your insight saved me hours of fussing! THANKS SO MUCH!!!Anonymous
June 22, 2014
Thanks james, it saved timeAnonymous
December 25, 2014
Excellent depiction of the things to be carried out to create the nettcpbibding .. Thanks a lotAnonymous
April 12, 2015
Thanks! It works on a Windows 2012 r2 installation after an inplace upgrade from 2008 r2. This service stopped working.Anonymous
September 21, 2015
Hi, This article helped a l9t thank you. I went one step further and created a powershell script creat the bindings for me www.codingcurve.com/.../creating-iis-net-tcp-binding-using-powershell