6

I have a service accessible via http and net.pipe. It is being hosted in IIS 7 (Server 2008). I may be hosting different instances of this service for several customers on the same machine and hence the HTTP is setup with virtual hostnames etc. This is all working fine.

I thought I would do similar for the net named pipe binding - using some form of the customers 'virtualhostname' in the named pipe base address, therefore allowing me to access the different customer instances with different net.pipe urns (I realize the net.pipe names are URN's not URL's so they can be essentially arbitrary but I thought I would follow a similar pattern to the HTTP addresses).

Here is my web.config

<service name="Administration" behaviorConfiguration="AdministrationBehavior">
    <endpoint address="" binding="wsHttpBinding" bindingConfiguration="normalWsBinding" contract="IAdministration" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <endpoint address="" binding="netNamedPipeBinding" bindingConfiguration="normalNetNamedPipeBinding" contract="IAdministration" />
    <endpoint address="mex" binding="mexNamedPipeBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://virtualhostname.com/service" />
        <add baseAddress="net.pipe://virtualhostname.com/administration/service" />
      </baseAddresses>
    </host>
</service>

However, when accessing the WSDL for the service - the base address for the net.pipe seems to be ignored by IIS. Instead I get the real hostname of the machine, and a net.pipe address URN that seems to have been formatted entirely by IIS.

<wsdl:port name="NetNamedPipeBinding_IAdministration" binding="tns:NetNamedPipeBinding_IAdministration">
   <soap12:address location="net.pipe://realhostname/service/Administration.svc"/>
   <wsa10:EndpointReference>
       <wsa10:Address>net.pipe://realhostname.com/service/Administration.svc</wsa10:Address>
       <Identity>
          <Spn>host/realhostname.com</Spn>
       </Identity>
   </wsa10:EndpointReference>
</wsdl:port>

With no control over the way net.pipe names are formed, I will not be able to discriminate between the multiple customer service instances on the machine. Does anyone have any clue as to how the net named pipe binding URN can be controlled within the IIS environment?

(I do a lot of standalone net.pipe hosting during testing (i.e. new ServiceHost()) so I know that my net.pipe bindings do work outside of IIS, and do allow control over the exact named pipe URN used)

If the names can't be controlled within IIS - does anyone have any experience with hosting and accessing multiple separate net.pipe service instances on the same machine?

Andrew Patterson
  • 1,338
  • 1
  • 12
  • 26
  • you are aware that net.pipe bindings only work "on machine", e.g. you cannot access those from some other machine, even if they're hosted in IIS.... – marc_s Nov 27 '09 at 06:19
  • when hosting in IIS, you don't really get to choose your service address - it's always `http://machinename[:port]/virtualdir/yourservice.svc` - I suspect the same applies to net.pipe addresses - you don't get to control their naming if hosted in IIS.... – marc_s Nov 27 '09 at 06:20
  • Yes, the HTTP endpoints are for access off-machine, and I was hoping to use the net.pipe endpoints for some limited (but hopefully faster) on-machine access. When I host my HTTP endpoints in IIS, I do however get to chose the service address (at some level) because I specify the domain I want to use. This lets me have multiple IIS sites each accessible via different urls i.e http://customer1.com/admin/Admin.svc and http://customer2.com/admin/Admin.svc If I can't choose my base addresses for net.pipe, how can I have multiple net.pipe bindings hosted for different customers in IIS? – Andrew Patterson Nov 27 '09 at 08:00
  • 1
    I'm still interested in any thoughts on this - is the question unclear or are not many people doing this? – Andrew Patterson Dec 07 '09 at 06:56
  • 1
    If it helps, I've done this for a service hosted in a Windows service and it worked fine, name was inferred from the virtual host name. – Meidan Alon Dec 28 '09 at 15:28
  • I would expand on Meidan's idea. Host a copy of the library in a windows service for the faster net.pipe scenario. – Rob Murdoch Jan 01 '10 at 02:43
  • Thanks Meidan and Rob - I could do as you suggest, but I lose a lot of other benefits that come with hosting inside IIS. One important feature that IIS provides is that I can use virtual domains for my HTTP endpoints (each endpoint needs to support both HTTP and net.pipe) - I'm not sure how I would go about rolling that myself using multiple windows services. – Andrew Patterson Jan 13 '10 at 00:46

2 Answers2

3

This is an old question, but I figured I'd add my answer since I also needed an answer for this (and maybe there are others out there who need it too).

The base address of an IIS-hosted WCF service is controlled by IIS and cannot be overridden in web.config. Instead, you can control the base addresses by updating the IIS site binding information for the site you're hosting your service in.

Most of the documentation I found online suggests using * as the binding configuration for net.pipe. But if you instead use "virtualsite.com" as the binding configuration value, the base address of your net.pipe endpoint will be "virtualsite.com" rather than the machine name.

Here is an example using appcmd to configure a site in IIS with the correct net.pipe binding:

%windir%\system32\inetsrv\appcmd.exe set site "Default Web Site" -+bindings.[protocol='net.pipe',bindingInformation='virtualhostname.com']

One note about HostnameComparisonMode, it has no effect in IIS according to MSDN:

These values have no effect when used inside of the Internet Information Services (IIS) or Windows Process Activation Service (WAS) hosting environment. In those cases, WCF uses whatever hostname comparison mode is provided by the IIS Web Site hosting the WCF services.

Instead, you have to use the mechanism I described above. I figured this out by investigating how hostname binding works in HTTP for IIS. Unfortunately, I've not been able to find any official documentation for this IIS-based scenario for other WCF transports.

Chris Gillum
  • 14,526
  • 5
  • 48
  • 61
  • Thanks Chris. My need for this to be solved has long since passed but this looks like good info! – Andrew Patterson Jan 21 '14 at 01:45
  • This fixed it for me when we moved our services from a Windows Server 2008 R2 environment to a Windows Server 2016 environment. The * binding works for "localhost" in Server 2008 but breaks in 2016; After updating it explicitly to "localhost", this resolved the issue for me. – Charles Chen May 03 '18 at 16:07
0

It appears that the host name portion of the URI is ignored and replaced by the implementation based upon the HostNameComparisonMode of the channel binding. You can try changing it to "Exact" via the service's configuration...

http://msdn.microsoft.com/en-us/library/system.servicemodel.netnamedpipebinding.hostnamecomparisonmode.aspx

NetNamedPipeBinding.HostnameComparisonMode The HostnameComparisonMode value that indicates whether the hostname is used to reach the service when matching the URI. The default value is StrongWildcard(), which ignores the hostname in the match.

See the configuration syntax here: http://msdn.microsoft.com/en-us/library/ms731291.aspx

csharptest.net
  • 62,602
  • 11
  • 71
  • 89
  • I'm not sure if this is new since your original answer, but according to your link, HostnameComparisonMode has no effect in IIS. – Chris Gillum Jan 08 '14 at 01:56