【问题标题】:Consuming a WCF Service that is hosted in a Windows Service from outside solution从外部解决方案使用托管在 Windows 服务中的 WCF 服务
【发布时间】:2012-10-05 16:31:59
【问题描述】:

我使用以下演练设置了托管在 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 文章中发现了一个错误 - 我已经详细说明了他的发现 HERE

【问题讨论】:

  • 您可以确认服务和您的客户端解决方案在同一台计算机(您的)上运行吗?还要检查你的防火墙不是罪魁祸首。
  • @mbarthelemy 服务正在运行,但我正在尝试让网络上的客户端找到该服务 - 这就是我想要实现的目标。
  • @whytheq:我很好奇是什么导致了这个问题。你检查过我已经提到的选项了吗?
  • @Matt 我的同事在 MSDN 文章中发现了一个错误,我已经在另一个 SO POST 中详细说明了它

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


【解决方案1】:

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

第一个选项:尝试指定

  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,则它找不到该服务,而您收到的错误消息正是您在问题中描述的。

在微软有两个关于这个问题的有趣链接: Problem with Metadata ExchangePublishing Metadata

请注意,这与在第三个选项中描述的部署它不同。


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

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


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


第五个也是最后一个选项(更新): 命名冲突 - Service1 是服务,也是 Wcf 库中的类名。从服务中的 WCF 库 完全限定您正在使用的类名称,即 WcfServiceLibrary1.Service1 或重命名该类。 Whytheq 自己和一位同事找到了它,并在here 上发布了它。


更多阅读:查看我最近发现的这篇文章:“WCF: a few tips”。它很好地解释了 WCF 故障排除。我对控制台托管示例所做的唯一更改是 替换 using 声明 by 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 for info matt - 我的同事在 MSDN 文章中发现了一个错误,我已经详细说明了它in this other SO POST
  • 我没想到命名冲突,这真是令人头疼的啊哈效应……感谢您分享此信息!但它显示了在您真正找出问题原因之前,有多少种可能性需要检查。
  • 我同事的所有工作;感谢所有这些信息 - + 答案(将在几天内将其标记为)......现在我需要处理你的所有建议,因为这些对我来说是新的复杂项目,而且我需要更多信息可以学得更好
  • 很高兴听到我写的内容对您也有帮助。不要忘记标记答案;-)
  • 我喜欢暂时不回复帖子,以防万一这鼓励更多的贡献
【解决方案2】:

你可以通过以下方式解决这个问题:

  • 浏览服务的 WSDL URL 并将 WSDL 保存到本地文件。
  • 然后对文件进行以下更改:
  • 从用于 wsdl:binding 的名称中删除命名空间前缀,即更改 name="wb:wsclocks-inboundSoapBinding" 为 name="wsclocks-inboundSoapBinding"
  • 将wsdl:port属性的binding属性改成匹配,同时去掉name属性值的命名空间前缀,所以就是wsclocks-inbound。

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

【讨论】:

  • 如何“浏览服务的 WSDL URL”?
猜你喜欢
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
  • 2010-11-04
  • 1970-01-01
  • 1970-01-01
  • 2012-01-13
相关资源
最近更新 更多