none
How to communicate with a WCF service from its host Window Service itself ?

    Question

  • Hi,

    I have a WCF service hosted as a Windows Service.  And I want to call one of its exposed method from the host Windows Service itself right after it is opened using ServiceHost.Open() in OnStart().  In other words, is it possible to use the host Windows service as a client as well to the WCF service it is hosting ?

    Basically, my WCF service is an IVR app which I want to host as a Windows service with Automatic startup type, so that it can start itself automatically (and starts lisetning for incoming phone calls) after the machine reboots.  To do this, I would somehow need to call, for example, StartPhoneChannels() method of WCF service from its host Windows service after ServiceHost.Open() call .  If I call this method from my WCF client (which is a WPF app), I would have to start my client manually after machine reboot which won't provide automatic startup facility of my WCF service.

    I would really appreciate any suggestions or work arounds ?

    Thanks,

    Vijay

    Friday, May 21, 2010 4:56 PM

Answers

  • Hi Vijay

    It is possible to call the service from the process hosting the service. Here is a possible implementation:

    Console.WriteLine("Opening Service1...");
    ServiceHost host = new ServiceHost(typeof(Service1), new Uri("http://localhost:8732/Design_Time_Addresses/Single/Service1/"));
    ReadOnlyCollection<ServiceEndpoint> endpoints = host.AddDefaultEndpoints();
    host.Open();
    Console.WriteLine("Service1 opened");
    using (ChannelFactory<IService1> ChannelFactory
      = new ChannelFactory<IService1>(new BasicHttpBinding(), new EndpointAddress("http://localhost:8732/Design_Time_Addresses/Single/Service1")))
    {
      try
      {
       IService1 channel = ChannelFactory.CreateChannel();
       Console.WriteLine(channel.StartPhoneChannels());
      }
      catch (Exception ex)
      {
       Console.WriteLine(ex);
      }
    }
    Console.WriteLine("Closing Service1...");
    host.Close();
    Console.WriteLine("Service1 closed");

    Note, I have set the InstanceContextMode of the service behavior to Single which means a single instance of the service is ever created and shared across all clients. A PerSession service could also have been used.

    Cheers,

    Francois


    Please, mark the answer as helpful if it is. Thanks.
    Saturday, May 22, 2010 9:26 AM
  • Besides calling the service with a ChannelFactory<T> client from the same process, another option would be to hook an IInstanceProvider (http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iinstanceprovider.aspx) so that before you handle the service instance to the WCF host, you can call the initialization method on the instance itself, bypassing the WCF stack for that.
    • Proposed as answer by Francois Magnin Saturday, May 22, 2010 9:06 PM
    • Marked as answer by vg_jain Monday, May 24, 2010 3:38 PM
    Saturday, May 22, 2010 4:08 PM

All replies

  • Hi Vijay

    It is possible to call the service from the process hosting the service. Here is a possible implementation:

    Console.WriteLine("Opening Service1...");
    ServiceHost host = new ServiceHost(typeof(Service1), new Uri("http://localhost:8732/Design_Time_Addresses/Single/Service1/"));
    ReadOnlyCollection<ServiceEndpoint> endpoints = host.AddDefaultEndpoints();
    host.Open();
    Console.WriteLine("Service1 opened");
    using (ChannelFactory<IService1> ChannelFactory
      = new ChannelFactory<IService1>(new BasicHttpBinding(), new EndpointAddress("http://localhost:8732/Design_Time_Addresses/Single/Service1")))
    {
      try
      {
       IService1 channel = ChannelFactory.CreateChannel();
       Console.WriteLine(channel.StartPhoneChannels());
      }
      catch (Exception ex)
      {
       Console.WriteLine(ex);
      }
    }
    Console.WriteLine("Closing Service1...");
    host.Close();
    Console.WriteLine("Service1 closed");

    Note, I have set the InstanceContextMode of the service behavior to Single which means a single instance of the service is ever created and shared across all clients. A PerSession service could also have been used.

    Cheers,

    Francois


    Please, mark the answer as helpful if it is. Thanks.
    Saturday, May 22, 2010 9:26 AM
  • Besides calling the service with a ChannelFactory<T> client from the same process, another option would be to hook an IInstanceProvider (http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iinstanceprovider.aspx) so that before you handle the service instance to the WCF host, you can call the initialization method on the instance itself, bypassing the WCF stack for that.
    • Proposed as answer by Francois Magnin Saturday, May 22, 2010 9:06 PM
    • Marked as answer by vg_jain Monday, May 24, 2010 3:38 PM
    Saturday, May 22, 2010 4:08 PM
  • Hi Francois and Carlos,

    Thanks a lot for your valuable suggestions.  I will definitely try these approaches and get back to you guys if I encounter any further issue.

    Thanks again,

    Vijay

    Monday, May 24, 2010 3:40 PM