We recently had a requirement to put in place a system where we could host WFs without Send/Receive activities into them inside a WorkflowServiceHost (WFSH) and to be able to customize the instances of these WFSH that the system spawns. Thanks to Simon Ince’s (blog here) help on this, we pretty much have it working now. So the situation is that a request comes in to a set of WCF Service on a standard https endpoint and one of this WCF service kicks this bizarre WF into action. The WCF service achieves this by calling onto another end point where our wizardry then intercepts the message and kicks up a workflowservicehost which then runs the WF. This end point is also on a https address. The bug that bit me (and actually I blame Zulfiqar from Microsoft for this ) was to change this https end point for the fake service that runs the workflow to a net.pipe end point. Simple, eh? Well you would think so! What followed next was an absolute nightmare of fiddling with horrendous web.config settings, IIS configurations, Windows Services configurations and what not. We eventually got there i.e. we succesfuly changed the binding to net.pipe instead of https but the journey wasn’t easy and here in this blog post I wanted to highlight some of the common mistakes I made in the hope that someone else might benefit from these experiences.
Mayday Captain! I see no port!
That’s right sailor and you shall see none! Basically I missed a very simple concept – net pipe addresses are “in-memory” addresses. Thus there is no concept of a port for them. So imagine your website runs on port 8200 and you have an address as http://{blahblah}:8200. If you host some services on net.pipe addresses within the broad umbrella of this site, the addresses will still not have any port associated with them. Say you have two WCF services, one over standard basicHttpBinding and other over net.pipe then they will look like http://{blahblah}:8200/Services/MyFirstService.svc net.pipe://seenoport/mysecondservice In this grand scheme of things you can consider the string “seenoport” as your http equivalent of a host name. Your WCF services can hang off addresses relative to this.
Fast Furious and Secure!
Well OK Fast and sort of Secured. Since these are in-memory addresses the overhead to serialize and de-serialize parameters arguments etc. over a wire is missing here. The calls to net.pipe addresses can be resolved very fast as compared to all the over head of reaching out to a remote server over network using tcp or http. Besides since the services are not exposed to external clients (i.e. they can be called from clients on the box itself) they do provide an element of security. That doesn’t mean that it can not be maliciously manipulated. I suspect it isn’t child play but there is always a possibility of using a tool such as AppSight which can enumerate memory state of various applications and can sniff out data. But since the access is from the box itself the chances of someone being able to hack into these remotely are negligible.
OK I am sold, what next?
Glad you came around. So if you are planning on enabling net.pipe binding support in your WCF services hosted under IIS there are a couple of gotchas you might want to be wary off
Start the Net.Pipe listener service
This made me sweat. I honestly did the next two steps which you will shortly read without ever doing this one. It was hours of frantic debugging before I realized that a service critical for net.pipe support should be turned on before you can use net.pipe binding. So head over to the Services control panel (Control Panel -> Administrative Tools -> Services) and find and enable the Net.Pipe Listener Adapter service as shown in the screenshot below.
Enable net.pipe for your website
Open up IIS, find your website then click Advanced Settings on the right hand side pane. In the dialogue box that opens up add net.pipe to the list of Enabled Protocols. Click OK (see screenshot below).
Add a net.pipe binding
Next click the Bindings link in the right hand side pain in IIS. In the dialogue box that opens up click “Add” then finally give the unique name (equivalent of a host) you want to give for this binding. See screenshot below.
That’s it! You are now set up to use a net.pipe address for your services. Please let me know if I have made a mistake or if something can be improved or made better.