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

时间:2012-10-05 16:31:59

标签: c# visual-studio-2010 wcf windows-services

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

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

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

演练工作,即winforms按钮给我正确的答案。

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

enter image description here

详细信息说明如下:

  

无法识别URI前缀。元数据包含一个引用   无法解决:'net.tcp:// localhost:8526 / Service1'。不能   connect to net.tcp:// localhost:8526 / Service1。连接尝试   持续时间为00:00:02.0020000。 TCP错误代码10061:否   可以建立连接,因为目标机器主动拒绝   它127.0.0.1:8526。由于目标,无法建立连接   机器主动拒绝它127.0.0.1:8526如果服务已定义   在当前的解决方案中,尝试构建解决方案并添加   服务参考。

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


编辑

我的同事在MSDN文章中发现错误 - 我详细说明了他的发现HERE

2 个答案:

答案 0 :(得分:12)

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

第一个选项:尝试指定

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

将服务引用添加到新客户端时 - 确保已安装该服务并在之前运行

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


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

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

WcfSvcHost.Exe /Service:<Service1Binary> /Configuration:<Service1Config> 

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

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

微软有两个有趣的链接: Problem with Metadata ExchangePublishing Metadata

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


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

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


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


第5个也是最后一个选项(UPDATE):命名冲突 - Service1是服务,但也是Wcf库中的类名。您可以从服务中的 WCF库中完全限定您正在使用的类名,即WcfServiceLibrary1.Service1或重命名该类。 Whytheq与同事一起发现了它并发布了here


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

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

如果您想了解更多原因,请查看此文章:“Proxy open and close”。

答案 1 :(得分:0)

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

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

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