Windows服务托管的TCP WCF服务

4
我正在尝试将WCF服务作为Windows服务托管在Windows 2008 R2服务器上。我遵循了MSDN提供的指南(在此处找到)。只要所有内容都是Visual Studio中同一解决方案的一部分,一切都正常工作。但是,我尝试在不同的解决方案(在同一台机器上)中创建客户端,但它找不到该服务。我收到如下所示的“添加服务引用错误”。

enter image description here

我的目标是能够远程访问WCF服务,但我似乎甚至无法在本地访问它,除非在同一个客户端内创建客户端。有没有任何指南、教程或有用的提示可以帮助我使其正常工作?

更新: 看起来即使Windows服务正在运行,WCF服务也似乎没有监听任何端口。这表明它没有运行。这也解释了为什么每个人都认为我没有运行服务的原因。我以为由于Windows服务正在运行,而同一解决方案客户端也在工作,所以WCF服务也在工作。结果发现,每当我运行同一解决方案客户端时,Visual Studio都会启动一个WCF服务。

那么,为什么Windows服务没有启动WCF服务呢?有什么想法吗?


当您尝试添加服务引用时,您是否已经运行了该服务? - Dylan Meador
是的,如上所述,我已经按照教程中所解释的一切工作正常,包括启动服务。 - Bryan Watts
你有没有在尝试从新客户端添加服务引用时,确保你开发的服务实际正在运行? - Dylan Meador
是的,我认为很明显,在我连接到服务甚至从中提取元数据之前,该服务必须正在运行。 - Bryan Watts
然而,服务实际上正在运行可能并不那么明显。事实证明,尽管Windows服务已经启动,但WCF服务并没有启动。我不知道为什么,也不知道如何解决它... - Bryan Watts
4个回答

7

原来,MSDN提供的教程(在上面的问题中提供)存在问题。他们将Windows服务和WCF服务都命名为Service1,这是它们的默认名称。

Windows服务应该启动WCF服务,但实际上它尝试重新启动自己,因为两个服务具有相同的名称。

myServiceHost = new ServiceHost(typeof(Service1));

为了解决这个问题,您可以将其中一个服务重命名或在Windows服务中引用WCF服务时使用完全限定的名称。
myServiceHost = new ServiceHost(typeof(WcfServiceLibrary1.Service1));

有趣的是,提供的代码看起来仍然可以工作,因为Visual Studio足够聪明,注意到WCF服务没有运行,并在幕后启动一个实例。

这是一个简单的错误修复,但由于Visual Studio将问题隐藏起来,我认为如果没有Espen Burud的帮助,我不会发现它。


尽管这两个服务(WCF 和 Windows 服务)有不同的名称,但这解决了我的(相同)问题!! - Tratak

3

添加服务引用有两种方式来了解一个服务:

发现 按钮: 在当前解决方案中搜索项目。
前往 按钮: 连接到地址框中的服务并检索元数据。

在点击 前往 之前,您需要确保服务已经在运行。

编辑

我刚才从您的屏幕截图中注意到,您正在尝试连接到一个 net.tcp URL 。使用 http 来进行 MEX 更为常见。您的 app.config 应该类似于下面:

<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>

请注意http基础地址的不同端口号。在添加服务引用工具中,您将使用“http://localhost:8524/Service1”。您也应该能够通过浏览器连接到它。
为了允许元数据交换通过http GET(例如从浏览器),您还需要通过一个行为来启用它:
<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceMetadata httpGetEnabled="True"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

我不确定“添加服务引用工具”是否关心这个问题。

即使您不想允许http get访问(httpGetEnabled=“False”),您仍然需要包括此行为以启用MEX(除非您是以编程方式添加它)。


是的,我明白这一点,但它并没有真正解决我的问题。 - Bryan Watts
我参考的教程让你通过TCP利用元数据交换,而不添加HTTP基础地址。我想我可以尝试添加HTTP基础地址来看看是否有效,但我真的不想通过HTTP提供服务访问权限。 - Bryan Watts
我从未尝试过这个,但是这里有一个通过TCP公开MEX的示例:http://social.technet.microsoft.com/wiki/contents/articles/exposing-a-metadata-exchange-mex-endpoint-over-tcp-with-an-iis-hosted-wcf-service.aspx - Igby Largeman
对于HTTP,您可能需要包含serviceMetadata行为,请参见我的最后编辑。我查看了您引用的教程,它将httpGetEnabled设置为false(这会明显地阻止通过HTTP GET访问元数据)。 - Igby Largeman
确认我不需要处理HTTP。 我可以通过TCP实现所有功能,但我还没有完全弄清楚如何做到这一点(请参见Espen的答案)。 我更新了问题并提供了更多详细信息。 - Bryan Watts

2
我已经测试了MSDN文章,并且在不做修改的情况下可以正常工作。如果服务器上启用了防火墙,我认为您需要为您的服务添加一些规则。
要验证服务是否正在侦听正确的TCP端口,您可以使用命令:netstat -a。如果服务正在侦听正确的端口,则此命令将返回:
Proto  Local Address          Foreign Address        State
TCP    0.0.0.0:8523           machinename:0          LISTENING

我也已经成功地运行了它,没有进行任何修改。然而,它会在同一个解决方案中创建客户端。如果我尝试在服务所在的解决方案之外创建客户端,即使它们在同一台机器上并且服务正常运行,客户端也无法连接到服务。 - Bryan Watts
它对我有效,即使我在单独的解决方案中创建了客户端。 - Espen Burud
1
所以,我尝试了您建议的netstat命令,并注意到即使Windows服务正在运行,WCF服务似乎并未运行。 您是否遇到过这个问题?我的问题可能是什么? - Bryan Watts
@BryanWatts:服务运行的用户是否有使用该端口的权限?如果没有,您需要创建 ACL 或以提升的权限运行服务。 - Igby Largeman
它有权限。最终,在您的回答帮助下,我找出了主要问题。请参阅我的答案以获取完整详细信息。谢谢。 - Bryan Watts

0

我成功解决了问题。我的服务不知道这些端点,因为我没有将WCF项目中的app.config中的服务配置复制到实际Windows服务的app.config中。一旦我这样做了,它就正常运行了。

在原始的MSDN文章中并没有明确提到这一点,尽管在WCF app.config的评论中提到了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接