使用从外部解决方案托管在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