Host WCF in a Windows Service Using TCP

Introduction

There are many ways to host a WCF service library, such as IIS, WAS, self-hosting and Windows Service. Windows Service hosting is more suitable for a long-running WCF service hosted outside of IIS.

The following are the advantages of hosting a WCF service in a Windows Service:

  • The service will be automatically began when the Windows Service is started.
  • Hosting in a Windows Service allows us to select the binding protocols.
  • The Windows Services Control Manager allows us to select an identity under which the process will run (Local service, Local system or Network service).

Disadvantages

  • Required custom installer action or .Net utility (Installutil.exe).
  • Windows Services do not have the scalability, security, administrative and manageability features included in IIS.

Procedure to host WCF in a Windows Service using TCP

The following is the procedure to host a WCF service in a Windows Service using TCP.

Step 1: Create WCF Service

The first step is to create a WCF service using a WCF class library project and create a contract and service methods that we want to expose.

WCF service

Step 2: Configure WCF Service Endpoints to use TCP

During this step, we modify the WCF configuration, so that the endpoints use TCP instead of HTTP and then we need to set the base address for our service. Also we need to set the httpGetEnable property to false to run our service under TCP.

To configure the WCF service, we need to use the following procedure:

  1. Right-click on the App.config file of the WCF Service library project and click on Edit WCF Configuration. Alternatively, go to the Tools menu and click WCF Service Configuration Editor.

    WCF Service library project

    WCF Service Configuration Editor

  2. Expand the Services node and then expand Endpoint node.
  3. Change the Binding to netTcpBinding under the Endpoint Properties.
  4. Change the Binding to mexTcpBinding under the Endpoint Properties.
  5. Select the BaseAddress property under the Service >> Host Node and set the base address to the following and click OK.

    net.tcp://localhost:8523/TcpService

    Host Node and set base address

  6. Expand the Advanced >> Service Behaviours node and select service metadata and set httpGetEnabled to false.

    httpGetEnabled

  7. Select the File Menu and click on save to save the configuration changes.

    Now the configuration looks as follows.
    1. <system.serviceModel>  
    2.   <services>  
    3.     <service name="WcfServiceLibrary.TcpService">  
    4.       <endpoint address="" binding="netTcpBinding" bindingConfiguration=""  
    5.         contract="WcfServiceLibrary.ITcpService">  
    6.         <identity>  
    7.           <dns value="localhost" />  
    8.         </identity>  
    9.       </endpoint>  
    10.       <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""  
    11.         contract="IMetadataExchange" />  
    12.       <host>  
    13.         <baseAddresses>  
    14.           <add baseAddress="net.tcp://localhost:8523/TcpService" />  
    15.         </baseAddresses>  
    16.       </host>  
    17.     </service>  
    18.   </services>  
    19.   <behaviors>  
    20.     <serviceBehaviors>  
    21.       <behavior name="">  
    22.         <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />  
    23.         <serviceDebug includeExceptionDetailInFaults="false" />  
    24.       </behavior>  
    25.     </serviceBehaviors>  
    26.   </behaviors>  
    27. </system.serviceModel>  

Step 3: Create Windows service

In this, we add a Windows Service project to our solution.

To add a new project, right-click on the solution, select the Add option, click on New project and select Windows Service type project.

Copy the app.config file from the WCF service library to the newly created Windows Service project.

Step 4:
Add the Service Installers to the Windows Service.

  1. Right-click on the base service file (in the demo base service file id TCPTestService.cs) and click on Add Installer.

    This adds the ProjectInstaller.cs file and this file contains two objects called service Process Installer and Service Installer.

    Add Installer

  2. Open the design view of ProjectInstaller.cs and right-click on the Service Process Installer and click on Properties.

    Set the Account attribute to "NetworkService".

    NetworkService

  3. Right-click the service installer and select properties.

    Set the StartType attribute to Atomatic.

    properties

Step 5: Modify the Windows Service to host the WCF Service.

In this step we override the OnStart() and OnStop() methods. In this step, first we need to add a reference to the System.ServiceModel and WCF service library project to our Windows Service project.

Now open the base service file in code view and declare an internal static member of ServiceHost type (please note that ServiceHost is part of System.ServiceModel namespace).

  1. internal static ServiceHost myServiceHost = null;  
The next step is to override onstart() and open the service host as follows:
  1. protected override void OnStart(string[] args)  
  2. {  
  3.    if (myServiceHost != null)  
  4.    {  
  5.       myServiceHost.Close();  
  6.    }  
  7.    myServiceHost = new ServiceHost(typeof(WcfServiceLibrary.TcpService));  
  8.    myServiceHost.Open();  
  9. }  
Override the OnStop() method and close the service host as follows:
  1. protected override void OnStop()  
  2. {  
  3.    if (myServiceHost != null)  
  4.    {  
  5.       myServiceHost.Close();  
  6.       myServiceHost = null;  
  7.    }  
  8. }  
Now build both projects. The Windows Service project produces WindowsService.exe in the bin\debug folder.

Step 6: Install the Windows Service

In the previous step, we generated WindowsService.exe and this is used to install the services.

To install the service use the following procedure. 
  1. Open the Visual Studio command prompt in Administrator mode.
  2. Go to the bin\debug directory of the Windows Service project.
  3. Run the following command to install the service.

Installutil WindowsService.exe

click service installer and select properties

We may uninstall the service using the following command:

Installutil /u WindowsService.exe

Note: After the successful installation of the service we need to start the service manually. To start the service go to the Control Panel then seelct Administrative Tools >> Open Services in administrator mode. Find the service, right-click the service and click on Start.

When the service is started, you might receive the following error:

    The 'service name' on the local computer started and then stopped. Some services stop automatically if they are not in use by other services or programs.

service

There are many causes of this error including the following possibilities:

  • The service user has insufficient access rights to the WindowsService.exe directory. To resolve the issue provide the access rights to the appropriate user to the service directory.
  • There are also some issues with WCF configuration like the base address is not aligned with the service name, the service does not expose an endpoint for specific protocol (for example the httpGetEnabled property is set to true but does not define an endpoint for HTTP).

    Open Services in administrator mode

  • Internal window service error. This error is also caused by an unhandled exception occurred during the OnStart() method.

Test Application

To test our Windows service, create a new console application and add a reference to the service endpoint address (as defined in the appconfig file in Step 2).

add reference to service endpoint address

Create an instance of the proxy and call the ConcateString function of our WCF service. The code should look as follows:

  1. static void Main(string[] args)  
  2. {  
  3.    TCPServiceRef.TcpServiceClient service = new TCPServiceRef.TcpServiceClient();  
  4.    Console.WriteLine(service.ConcateString("Jignesh""Trivedi"));  
  5. }  
Output

Output


Happy coding!