Share via


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!