使用从外部解决方案托管在Windows服务中的WCF服务

我使用以下演练设置了在Windows服务中托管的WCF库:

http://msdn.microsoft.com/en-us/library/ff649818.aspx

消费者winforms位于同一解决方案中,该解决方案位于我的工作PC的C:驱动器本地。

演练工作即winforms按钮给出了正确的答案。

如果我在C-Drive上创建一个新的解决方案,其中包含一个Windows窗体项目,我无法成功添加对此运行服务的service reference ,我收到以下消息:

在此处输入图像描述

详细信息说明如下:

无法识别URI前缀。 元数据包含无法解析的引用:’net.tcp:// localhost:8526 / Service1’。 无法连接到net.tcp:// localhost:8526 / Service1。 连接尝试持续时间跨度为00:00:02.0020000。 TCP错误代码10061:无法建立连接,因为目标计算机主动拒绝它127.0.0.1:8526。 无法建立连接,因为目标计算机主动拒绝它127.0.0.1:8526如果在当前解决方案中定义了服务,请尝试构建解决方案并再次添加服务引用。

为什么我可以将此服务引用添加到与服务相同的解决方案中的项目,而不是来自不同解决方案中的项目?


编辑

我的同事在MSDN文章中发现了一个错误 – 我在这里详细说明了他的发现

MSDN上的一步一步演练文章很遗憾地结束了有趣的地方,所以让我们继续这里。 因为有很多可能导致错误,我在下面描述了几个选项(=可能导致问题的情景),这应该有助于排除故障:

第一个选项:尝试指定

  net.tcp://localhost:8526/Service1/mex 

将服务引用添加到新客户端时 – 确保在执行此操作之前已安装并运行该服务。

说明:后缀“mex”代表“元数据交换”,允许Visual Studio下载WCF合同的详细信息。 此后缀也用于演练示例,它是自动添加的(如果通过右键单击“配置服务引用…” 重新打开添加的服务引用 ,您将在“地址”字段中看到它)。


第二个选项:我在测试演练时注意到的是,有时右键单击服务引用并在“更新服务引用”的“更新服务引用”菜单中进行选择。

系统托盘中一段时间后,您可以看到气球消息“您的服务已被托管”。 之后,您可以在同一解决方案中启动客户端。 在这种情况下,服务已临时创建但未永久部署 – 这意味着,如果您停止调试,则会将其删除。 因此,您无法从远程PC使用此服务,它只在Visual Studio的解决方案中可见。 Visual Studio内部调用该工具

 WcfSvcHost.Exe /Service: /Configuration: 

使用正确的参数支持它以正确注册服务(您可以在Visual Studio的Common7\IDE子目录中找到此工具,并且还有WcfTestClient.Exe可用 – 一个充当客户端的工具,对调试WCF非常有用)。

例如,如果您已停止调试,并从Visual Studio外部的Windows资源管理器启动client.exe,则它找不到该服务,您将收到您在问题中描述的错误消息。

关于Microsoft的这个问题,有两个有趣的链接: 元数据交换和发布元数据的问题

请注意,这与第3个选项中所述的部署不同


第3个选项:您是否使用过InstallUtil来部署服务? 在这种情况下,您可能会意外删除了[...]/bin/Debug子目录,并且服务无法启动,因为缺少.EXE文件。

注意:如果您正在使用ServiceInstaller项目,可以避免这种情况,该项目会在注册服务之前复制二进制文件。 或者 – 如果您想简单地使用InstallUtil – 您可以在注册之前将服务二进制文件复制到目标目录(包括.config文件和.dll)。


第四个选项:如果在远程计算机上运行该服务,则需要指定主机正确主机名或IP地址而不是localhost ,并且需要确保个人防火墙 (Windows防火墙或第三方) 不阻止端口8526 (示例中使用的端口号)。 指定例外以允许此端口用于传入和传出通信。


第五个也是最后一个选项(UPDATE):命名冲突 – Service1是服务,但也是Wcf库中的类名。 要么从服务中的WCF库中完全限定您正在使用的类名,即WcfServiceLibrary1.Service1要么重命名该类。 Whytheq已经与同事一起找到了它,并在此发布。


更多阅读:看看我最近发现的这篇文章:“ WCF:一些提示 ”。 它解释了WCF的故障排除。 我对控制台托管示例的唯一更改是 a 替换 using语句

 ServiceHost host = new ServiceHost(typeof(Service)); try { host.Open(); Console.WriteLine("WCF Service is ready for requests." + "Press any key to close the service."); Console.WriteLine(); Console.Read(); Console.WriteLine("Closing service..."); } finally { if (host!=null) { host.Close(); host=null; } } 

如果您想了解更多有关原因的信息,请查看本文:“ 代理打开和关闭 ”。

你可以按如下方式解决这个问题:

  • 浏览服务的WSDL URL并将WSDL保存到本地文件。
  • 然后对文件进行以下更改:
  • 从用于wsdl:binding的名称中删除名称空间前缀,即将name =“wb:wsclocks-inboundSoapBinding”更改为name =“wsclocks-inboundSoapBinding”
  • 更改wsdl:port属性的绑定属性以匹配,并从name属性的值中删除名称空间前缀,因此它只是wsclocks-inbound。

然后运行svcutil / o:Client \ WBServices / noConfig