5

我使用以下演练设置了托管在 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 文章中发现了一个错误 - 我在此处详细介绍了他的发现

4

2 回答 2

12

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

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

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


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

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


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


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


更多阅读:查看我最近发现的这篇文章:“ WCF:一些技巧”。它很好地解释了 WCF 故障排除。我对控制台托管示例所做的唯一更改是将语句替换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;
    }
}

如果您想了解更多原因,请查看这篇文章:“代理打开和关闭”。

于 2012-10-09T13:02:01.017 回答
0

您可以按以下方式解决此问题:

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

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

于 2012-10-05T16:39:02.510 回答