Windows Service Hosted TCP WCF Service

2019-04-11 09:43发布

问题:

I am trying to host a WCF service on a windows 2008 R2 server as a windows service. I followed the directions provided by msdn (found here). Everything works fine as long as everything is part of the same solution in visual studio. However, I tried creating a client in a different solution (on the same machine) and it can't find the service. I get an 'Add Service Reference Error' shown below.

My goal is to be able to access the wcf service remotely, but I can't seem to even access it locally unless the client was created within the same client. Is there any guides, tutorials, or helpful hints that anyone can give me to get this to work?

Update: It seems that even though the windows service is running, the WCF service doesn't seem to be listening to any ports. Which would suggest that it isn't running. This also explains why everyone's first thought I didn't have the service running. I had assumed that since the windows service was running and that the same solution client worked, that the WCF service was working as well. Turns out that Visual Studio was starting up a WCF service whenever I ran the same solution client.

So, why isn't the windows service starting the WCF service? Any ideas?

回答1:

It turns out that there was a problem with the tutorial provided by MSDN (provided in the question above). They named both the windows service and the WCF service Service1 which is the default name for both of them.

The windows service was suppose to start the WCF service, however, it was actually trying to start itself again because both services had the same name.

myServiceHost = new ServiceHost(typeof(Service1));

To fix this problem, you can rename one of the services or fully qualify the WCF service when referenced in the windows service.

myServiceHost = new ServiceHost(typeof(WcfServiceLibrary1.Service1));

The funny thing is that the code provided still looks like it works because Visual Studio is smart enough to notice that the WCF service isn't running and it starts an instance up behind the scenes.

It was a simple bug to fix, but because Visual Studio was hiding the problem from me, I don't think I would have found it without the help from Espen Burud.



回答2:

There are two ways for Add Service Reference to learn about a service:

Discover button: searches the projects in the current solution.
Go button: connects to the service in the Address box and retrieves the metadata.

You need to actually have the service running before you click Go.

EDIT

I just noticed from your screenshot that you're trying to connect to a net.tcp URL. I think it's more common to use http for MEX. Your app.config would look something like:

<services>
  <service behaviorConfiguration="WcfServiceLibrary1.Service1Behavior"
    name="WcfServiceLibrary1.Service1">
    <endpoint address="" binding="netTcpBinding" bindingConfiguration=""
      contract="WcfServiceLibrary1.IService1">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
      contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8523/Service1" />
        <add baseAddress="http://localhost:8524/Service1" />
      </baseAddresses>
    </host>
  </service>
</services>

Note the different port number for the http base address. You would then use "http://localhost:8524/Service1" in the Add Service Reference tool. You should also be able to connect to it with your web browser.

To allow metadata exchange via http GET (e.g. from a browser), you also need to enable it via a behavior:

<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceMetadata httpGetEnabled="True"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

I'm not sure if the Add Service Reference tool cares about that.

Even if you don't want to allow http get access (httpGetEnabled="False"), you still need to include this behavior to enable MEX (unless you're adding it programatically).



回答3:

I have tested the MSDN article in the and it works without modifications. If the firewall is enabled on the server, I think you will need to add some rules for your service.

To verify that the service are listening on the correct tcp port, you can use command: netstat -a. If the service are listening on the correct port, this command will return:

Proto  Local Address          Foreign Address        State
TCP    0.0.0.0:8523           machinename:0          LISTENING


回答4:

I managed to figure out the issue. My service didn't know about the endpoints because I hadn't copied the service configuration from the app.config in the WCF project into the app.config of the actual windows service. Once I did that it functioned correctly.

This was not made clear in the original MSDN article which I had also followed although it is mentioned in a comment in the WCF app.config.