简体   繁体   中英

Self hosted WCF not reachable

Hi guys I just want a simple WinForm app with one button. When I press the button i want to start the selfhosted WCF service. I want to able to connect to this service with for example another client app (winforms) by just adding a service reference.

However the solution that I created is not working. I can't get connected with adding a service reference to this service. I don't actually know what address to call than except the address that I defined in the app.config file. Any help would be great.

Here is the app.config file.

<configuration>
    <system.serviceModel>
        <services>
            <service name="WindowsFormsApplication11.WmsStatService">
                <endpoint address="http://192.168.0.197:87" binding="basicHttpBinding" 
                    bindingConfiguration="" contract="WindowsFormsApplication11.IWmsStat"/>
            </service>
        </services>
    </system.serviceModel>
</configuration>

And forms code:

namespace WindowsFormsApplication11
{
    public partial class Form1 : Form
    {
        public ServiceHost _host = null;

        public Form1()
        {
            InitializeComponent();
        }      

        private void button1_Click(object sender, EventArgs e)
        {
            _host = new ServiceHost(typeof(WmsStatService));
            _host.Open();
        }
    }

    // Define a service contract.
    [ServiceContract(Namespace = "http://WindowsFormsApplication11")]
    public interface IWmsStat
    {
        [OperationContract]
        string sayHello(string name);
    }

    public class WmsStatService : IWmsStat
    {
        public string sayHello(string name)
        {
            return "hello there " + name + " nice to meet you!";
        }
    }
}

I changed the app.config file. The problem is solved. Also thanks for the tips and your answers. The config is changed to.

<configuration>
  <system.serviceModel>
    <services>
      <service name="WindowsFormsApplication11.WmsStatService" behaviorConfiguration="mex">
        <host>
          <baseAddresses>
            <add baseAddress="http://192.168.0.197:87/" />
          </baseAddresses>
        </host>
        <endpoint address="http://192.168.0.197:87/Test" binding="basicHttpBinding" bindingConfiguration="" contract="WindowsFormsApplication11.IWmsStat" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="mex">
          <serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

The host should open on http://192.168.0.197:81 as in the config file.

So once the host is up and running then, try and broswe to it using the service reference.

I assume that the address is that your machine, and you don't have anything else on that port address. The other things to check are firewalls blocking that port.

I would not have the service class that implements the service contract (interface) be the form - make it a separate interface, a separate class. The reasoning behind this is the fact that the service host will have to create (instantiate) one instance of the service class for each request it needs to handle --> make those classes as small as possible and don't bloat them by baggage (like the Winform) that they don't need for their job!

Then instantiate a ServiceHost inside your Winform - but make that a global member variable of the form! Otherwise, the ServiceHost is gone once your ButtonClick event is finished!

// Define a service contract.
[ServiceContract(Namespace = "http://WindowsFormsApplication11")]
public interface IWmsStat
{
   [OperationContract]
   string sayHello(string name);
}

public class YourServiceClass : IWmsStat
{
   public string sayHello(string name)
   {
      return "hello there " + name + " nice to meet you!";
   }
}

public partial class Form1 : Form
{
    private ServiceHost _host = null;

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        // Create a ServiceHost for the CalculatorService type and 
        // provide the base address.
        _host = new ServiceHost(typeof(YourServiceClass));

        // Open the ServiceHostBase to create listeners and start 
        // listening for messages.
        _host.Open();
    }

Don't mix the class that contains the ServiceHost, with the ServiceClass (which will need to be instantiated by the host to satisfy incoming requests) - the Service implementation should be standalone, and as lean as possible!

Also, it's good practice to follow the Single Responsability Principle - one class should have one job and one job only - don't pack up your whole app logic into a single, huge class - separate out the different jobs into separate classes and compose those together.

Marc

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM