2

I have a standalone WCF service running on a server behind a firewall. It currently uses wsDualHttpBinding as the service utilizes callbacks. The client works fine in a LAN environment. We have opened the firewall to allow traffic on a custom port and so the discovery of the service now works from outside LAN.

Due to the nature of wsDualHttpBinding this obviously cannot work if the client is behind a firewall of its own. So naturally, netTcpBinding comes to mind which should solve the bidirectional problem. But the strange thing is that when service configuration XML is updated to include netTcpBinding on the same port (and/or exclude wsDualHttpBinding), then even the service discovery no longer works.

I am wondering if there is anything else that I am missing. I have followed the exact advice for configuration from How to: Use netTcpBinding with Windows Authentication and Message Security in WCF Calling from Windows Forms and from Windows Communication Foundation QuickStart - Multiple Binding VS2010.

The configuration:

<system.serviceModel>
  <bindings>
    <netTcpBinding>
      <binding name="NetTcpBindingEndpointConfig">
        <security mode="Message" />
      </binding>
    </netTcpBinding>
  </bindings>
  <services>
    <service name="Service1.Service1.Service">
      <endpoint address="Service1" binding="wsDualHttpBinding" contract="Service1.IService1">
        <identity>
          <dns value="localhost"/>
        </identity>
      </endpoint>
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      <endpoint address="" binding="netTcpBinding"
                 bindingConfiguration="NetTcpBindingEndpointConfig"
                 name="NetTcpBindingEndpoint" contract="Service1.IService1">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
      <host>
        <baseAddresses>
          <add baseAddress="http://localhost:9999/Service1.Service1/"/>
          <add baseAddress="net.tcp://localhost:9999/Service1.Service1/" />
        </baseAddresses>
      </host>
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior>
        <!-- To avoid disclosing metadata information, 
        set the value below to false and remove the metadata endpoint above before deployment -->
        <serviceMetadata httpGetEnabled="True"/>
        <!-- To receive exception details in faults for debugging purposes, 
        set the value below to true.  Set to false before deployment 
        to avoid disclosing exception information -->
        <serviceDebug includeExceptionDetailInFaults="True"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>
wpfwannabe
  • 14,587
  • 16
  • 78
  • 129
  • What do you exactly mean by service discovery? Are you using WS-Discovery mechanisms from WCF 4? – Ladislav Mrnka Apr 25 '12 at 08:37
  • No, I may have used the wrong term. With "discovery" I really meant that adding a service reference is successful. – wpfwannabe Apr 25 '12 at 10:13
  • Show whole your configuration for the service. – Ladislav Mrnka Apr 25 '12 at 10:22
  • You must use different port for http and net.tcp if you want to expose both base addresses. – Ladislav Mrnka Apr 25 '12 at 10:38
  • OK, thanks. I really sent you an older configuration. But consider the scenario where `wsDualHttpBinding` and its base address are completely commented out (or removed) so only `netTcpBinding` remains. Why would that not work? – wpfwannabe Apr 25 '12 at 10:59
  • Because you still have `mexHttpBinding` and `httpGetEnabled="true"` - those two requires HTTP and it must be exposed on different port than TCP. – Ladislav Mrnka Apr 25 '12 at 11:01
  • So, what should I really do to prune the config to a pure `netTcpBinding` config? Would you mind adding an answer if you think this is correct? – wpfwannabe Apr 25 '12 at 11:10
  • Why don't you simply use different port for HTTP and try it again? – Ladislav Mrnka Apr 25 '12 at 11:44
  • I have a single port at my disposal. If I obviously can't share the port for two bindings, I'd rather use just `netTcpBinding`. You have helped me a lot anyway. I'd appreciate it if you could assemble your answer and I'll mark it... – wpfwannabe Apr 25 '12 at 13:32

1 Answers1

3

If you can use only single port and you must use netTcpBinding try to configure your service this way:

<system.serviceModel>
  <bindings>
    <netTcpBinding>
      <binding name="NetTcpBindingEndpointConfig">
        <security mode="Message" />
      </binding>
    </netTcpBinding>
  </bindings>
  <services>
    <service name="Service1.Service1.Service">
      <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
      <endpoint address="" binding="netTcpBinding"
                 bindingConfiguration="NetTcpBindingEndpointConfig"
                 name="NetTcpBindingEndpoint" contract="Service1.IService1">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
      <host>
        <baseAddresses>
          <add baseAddress="net.tcp://localhost:9999/Service1.Service1/" />
        </baseAddresses>
      </host>
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior>
        <serviceMetadata httpGetEnabled="False"/>
        <serviceDebug includeExceptionDetailInFaults="True"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

When adding service reference try to use this address:

net.tcp://localhost:9999/Service1.Service1/mex
Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • Let me just add to this that my specific scenario had several services hosted in a bunch so there was obviously a port conflict. Luckily, I found [this](http://connect.microsoft.com/VisualStudio/feedback/details/286744/port-sharing-mextcpbinding-and-nettcpbinding-fails-when-maxconnections-or-listenbacklog-is-adjusted) which helped me realize I also need `portSharingEnabled="true"` on my `binding`. I have also changed `mex` to use the same shared `netTcpBinding`. – wpfwannabe Apr 25 '12 at 15:24