IIS 7 : Support for non-HTTP Protocols

Yesterday we hold here in Wallisellen an IIS7 Event where the main features (with plenty of demos) of this fresh new release were presented from a developer point of view.

As in the last time I'm diving into Windows Communication Foundation, one of the demo I particularly liked (which I want now to reproduce here) is the one about the new Windows Process Activation Service (WAS) IIS7 component. With WAS it is in fact possible to host WCF services beyond HTTP and without having to install the whole IIS package. Of course this offers you a lot of advantages: from one side you can host non-HTTP WCF service inside IIS7, profiting from IIS built-in feature like process recycling, process isolation, easier support of HTTPS, .... XCopy deployment is also a big advantage: if you have a new version of a service you can deploy it just by replacing the DLL's representing the service (that's all), while when you host your service for instance inside a Windows Service you need to stop it and start it again.

Of course hosting one service just in one place (in our case IIS) can make things simpler. You can in fact configure your service to support multiple protocols by defining multiple endpoints. Therefore you can for example define a TCP endpoint (that use the TCP protocol) that serves requests coming from your intranet (having a gaining in performance) and then define another endpoint, an HTTP endpoint, that communicates with the external world (through a firewall) and serves requests coming also from consumer not necessarily based on Microsoft technologies.

Now that we have seen some of the big advantages of WAS in relation with IIS7, it's time to built our sample. But before you start, be sure that you are using Windows Vista SP1 or Windows Server 2008.

Be sure also that the following selected item has been installed:

 image

Create now a new Web Site project (location HTTP) inside Visual Studio 2008 and name it IIS7HostedService as shown in the following image:

image

 

Note that by using the WCF Service (Web Site) template, the service will automatically be deployed to IIS (...and that is exactly what we want to do ...).

If you open the generated Service.cs file, you will see that a sample service with 2 operations (GetData and GetDateUsingDataContract) has already been created for you (we are going to use the first one).

 image

As we want to modify the return value of the GetData method by adding information on the used protocol, modify the method in the following way:

image

Notice also that as we are going to host our service inside IIS, Visual Studio created a Service.svc file. This file is a service definition file required by IIS (is optional if you create your own Service Host Application), which tells IIS how to identify the assembly containing the service implementation à a ServiceHost instance will then be created for this specific type.

Note that the service definition file (Service.svc) must have the same name as the Web service and have the .svc suffix!

You can now open the web.config file by using the integrated WCS Service Configuration Editor Tool provided inside Visual Studio 2008.

image

Once you have open the mentioned config file, you can expand the Services node and you will see that inside the Endpoints folder, 2 Endpoints have already been created. Select the one that use the wsHttpBinding Binding.

 image

Change the name Property of the selected endpoint with EndPointHTTP and change the Binding property by selecting the basicHttpBinding as shown in the following figure:

 image

Note that the main difference between the basicHttpBinding and the wsHttpBinding, is that the first one conforms to the WS-I Basic Profile 1.1 (use this binding if you want to maintain compatibility with client developed to access the "old" ASMX-based web service), while the wsHttpBinding conforms to the WS-* specifications.

Add now a second endpoint by selecting New Service Endpoint as shown in the following figure

image

and set the following properties:

Name

EndPointTCP

Binding

netTcpBinding

Contract

IService

 image

Note that instead of using basicHttpBinding we use this time netTcpBinding (the Contract remains the same). This also shows how it is easy with WCF to implement a service that can handle multiple protocols (it's just a configuration change inside a configuration file!).

If you now open the browser and you enter https://localhost/IIS7HostedService/Service.svc, you will get the following error:

 image

The error message says that our Web Site doesn't support TCP; no address match the schema net.tcp. What do we have to do?

If you open the IIS7 management console and you look at the advance setting of our IIS7HostedService WebApplication, you will see that in the Enabled Protocols section just http is defined. You now have to add net.tcp (separated by a comma), so that our service will be able to respond also to TCP requests.

image

Click OK and then go back to browser window and click refresh. What happens? The error message disappears and another message tells you that you now have to create a client proxy class.

image

And this is exactly what we are going to do now!

Add a Windows Form Application project to your solution and open the form designer. Drag&Drop a comboBox control, a TextBox Control and a Button control. Add a label control on top of the comboBox control and name it EndPoints (Protocols) . Add another Label control on top of the TextBox control and name it Input Value. Change the Text property of the button control to call service You should have something that looks like the following dialog:

 image

Fill the Combox control with fixed values by selecting Edit Items and entering the endpoints name values (EndPointHTTP, EndPointTCP) we defined before inside the WCF Configuration Tool, as shown in the following figure:

 image

image

On the UI side we are now ready. We still need to implement some code. Before we do that we have to generate the proxy class. To do that right-click the Windows Form project and select Add Service Reference. Inside the Add Service Reference dialog enter the URL that point to the .svc file (the same URL you entered before in the browser window), click Go and then OK.

 image

The proxy class has been generated! Moreover inside the app.config file two endpoints that reflect the endpoints we defined for the service have been generated.

We just need to make a small change to the address property of the TCP endpoint. Replace the generated address with the following address:

net.tcp://localhost:808/IIS7HostedService/Service.svc

image

Note that we also replaced the machine name with localhost (it wasn't really necessary) and that we added the TCP port (in my case 808). But where you can find out the TCP port number? It's easy. Open the IIS management console, select the main Site and select Bindings... as shown in the following picture. As you can notice, for the net.tcp protocol the port 808 has been defined.

image

Important note:

The possibility to edit TCP setting within a UI is available on Windows Vista just after installing the SP1. Windows Server 2008 that has been released to manufacturing this Monday (4th of February) already provides it. With the installation of the SP1 of Windows Vista, you have the same IIS7 (with the same features) that is provided inside Windows Server 2008 à Windows Vista was released about 1 year ago and in the meantime IIS7 has evolved!

IIS 7 is just part of Windows Vista and Windows Server 2008 (no IIS 7 for Windows Server 2003 will be released!).

We now have to implement the button_click EventHandler of our "call service" Button define in the client application as shown in the following figure:

image

Note that when we instantiate the proxy class (ServiceClient) we pass the name of the endpoint we want to use (value retrieved from our combobox). To the GetData method we pass the value of the TextBox (it must be a number otherwise the application will throw an exception). The result of the service call will be shown inside a MessageBox.

Now you just need to test your application. Set the Windows Form Application as start up project, then press Ctrl+F5 and try to call the service (once by using TCP and once by using HTTP).

Voilà, you are finished!

Hope this helps,

Ken

IIS7HostedService.zip