简体   繁体   English

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

[英]Consuming a WCF Service that is hosted in a Windows Service from outside solution

I've set up a WCF Library hosted in a Windows Service using the following walk-through: 我使用以下演练设置了在Windows服务中托管的WCF库:

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

The consumer winforms is in the same solution, which is located locally on my work PC's C: drive. 消费者winforms位于同一解决方案中,该解决方案位于我的工作PC的C:驱动器本地。

The walk-through works ie the winforms button gives me the correct answer. 演练工作即winforms按钮给出了正确的答案。

If I create a new Solution on the C-Drive with a single Windows Forms project in it I cannot successfully add a service reference to this running service, i get the following message: 如果我在C-Drive上创建一个新的解决方案,其中包含一个Windows窗体项目,我无法成功添加对此运行服务的service reference ,我收到以下消息:

在此输入图像描述

The detailed message says the following: 详细信息说明如下:

The URI prefix is not recognized. 无法识别URI前缀。 Metadata contains a reference that cannot be resolved: 'net.tcp://localhost:8526/Service1'. 元数据包含无法解析的引用:'net.tcp:// localhost:8526 / Service1'。 Could not connect to net.tcp://localhost:8526/Service1. 无法连接到net.tcp:// localhost:8526 / Service1。 The connection attempt lasted for a time span of 00:00:02.0020000. 连接尝试持续时间跨度为00:00:02.0020000。 TCP error code 10061: No connection could be made because the target machine actively refused it 127.0.0.1:8526. TCP错误代码10061:无法建立连接,因为目标计算机主动拒绝它127.0.0.1:8526。 No connection could be made because the target machine actively refused it 127.0.0.1:8526 If the service is defined in the current solution, try building the solution and adding the service reference again. 无法建立连接,因为目标计算机主动拒绝它127.0.0.1:8526如果在当前解决方案中定义了服务,请尝试构建解决方案并再次添加服务引用。

Why can I add this Service Reference ok to a project within the same Solution as the Service but not from a project in a different solution? 为什么我可以将此服务引用添加到与服务相同的解决方案中的项目,而不是来自不同解决方案中的项目?


EDIT 编辑

My colleague found an error in the MSDN article - I have detailed his find HERE 我的同事在MSDN文章中发现了一个错误 - 我在这里详细说明了他的发现

The step by step walkthrough article at MSDN ends unfortunately where it gets interesting, so let's continue here. MSDN一步一步演练文章很遗憾地结束了有趣的地方,所以让我们继续这里。 Because there are many possibilities which may cause the error, I've described several options (= scencarios which may cause the issue) below, which should help troubleshooting: 因为有很多可能导致错误,我在下面描述了几个选项(=可能导致问题的情景),这应该有助于排除故障:

1st option: Try to specify 第一个选项:尝试指定

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

when you add the service reference to your new client - ensure that the service is installed and running before you do that. 将服务引用添加到新客户端时 - 确保在执行此操作之前已安装并运行该服务。

Explanation: The suffix "mex" stands for "metadata exchange" and allows Visual Studio to download details of the WCF contract. 说明:后缀“mex”代表“元数据交换”,允许Visual Studio下载WCF合同的详细信息。 This suffix is also used in the walk-through example, it was added automatically (you will see it in the Address field if re-open the added service reference by right-clicking on "Configure Service-Reference..."). 此后缀也在步骤示例中使用,它是自动添加的(如果通过右键单击“配置服务引用...” 重新打开添加的服务引用 ,您将在“地址”字段中看到它)。


2nd option: What I noticed when I tested the walk-through is that it helps sometimes to right-click on the service reference and select in the contect menu "Update Service-Reference". 第二个选项:我在测试演练时注意到的是,有时右键单击服务引用并在“更新服务引用”选项中选择。

After a while in the systray you can see the balloon message "Your service(s) have been hosted." 系统托盘中一段时间后,您可以看到气球消息“您的服务已托管”。 , after which you can start the client within the same solution. 之后,您可以在同一解决方案中启动客户端。 In this case, the service has been temporarily created but is not deployed permanently - which means, if you stop debugging, it is removed. 在这种情况下,服务已临时创建但未永久部署 - 这意味着,如果停止调试,则会将其删除。 As a result, you can't use this service from a remote PC, it is just visible within the solution in Visual Studio. 因此,您无法从远程PC使用此服务,它只在Visual Studio的解决方案中可见。 Visual Studio internally invokes the tool Visual Studio内部调用该工具

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

supporting it with the right parameters to register the service properly (you can find this tool in Visual Studio's Common7\\IDE subdirectory, and there is also WcfTestClient.Exe available - a tool which acts as a client, very useful to debug WCF). 使用正确的参数支持它以正确注册服务(您可以在Visual Studio的Common7\\IDE子目录中找到此工具,并且还有WcfTestClient.Exe可用 - 一个充当客户端的工具,对调试WCF非常有用)。

For instance, if you have stopped debugging, and launch the client.exe from Windows Explorer outside of Visual Studio, then it does not find the service and you're getting exactly the error message you have described in your question. 例如,如果您已停止调试,并从Visual Studio外部的Windows资源管理器中启动client.exe,则它找不到该服务,您将收到您在问题中描述的错误消息。

There are two interesting links regarding this matter at Microsoft: Problem with Metadata Exchange and Publishing Metadata Microsoft在此问题上有两个有趣的链接: 元数据交换发布元数据的问题

Note that this is different from deploying it as described in the 3rd option. 请注意,这与第3个选项中所述的部署不同


3rd option: Have you used InstallUtil to deploy the service? 第3个选项:您是否使用过InstallUtil来部署服务? In this case it can happen that you have accidently removed the [...]/bin/Debug subdirectory and the service fails to start, because the .EXE file is missing. 在这种情况下,您可能会意外删除了[...]/bin/Debug子目录,并且服务无法启动,因为缺少.EXE文件。

Note: This can be avoided if you're using a ServiceInstaller project, which copies the binaries before the service is registered. 注意:如果您使用的是ServiceInstaller项目,可以避免这种情况,该项目会在注册服务之前复制二进制文件。 Or - if you want to use InstallUtil for simplicity - you can copy the service binaries to a target directory (including the .config files and .dlls) before you register it. 或者 - 如果您想简单地使用InstallUtil - 您可以在注册之前将服务二进制文件复制到目标目录(包括.config文件和.dll)。


4th option: If you run the service on a remote computer , you need to specify the proper host name or IP address of the host instead of localhost , and you need to ensure that the personal firewall (windows firewall or 3rd party) doesn't block the port 8526 (the port number which was used in the example). 第四个选项:如果在远程计算机上运行该服务,则需要指定主机正确主机名或IP地址而不是localhost ,并且需要确保个人防火墙 (Windows防火墙或第三方) 不阻止端口8526 (示例中使用的端口号)。 Specify an exception to allow this port for incoming and outgoing traffic. 指定例外以允许此端口用于传入和传出通信。


5th and final option (UPDATE): Naming conflict - Service1 is the service but also the class name in the Wcf library. 第5个和最后一个选项(UPDATE):命名冲突 - Service1是服务,但也是Wcf库中的类名。 Either fully qualify the class name you're using from the WCF library in the service, ie WcfServiceLibrary1.Service1 or rename the class. 要么从服务中的WCF库中完全限定您正在使用的类名,即WcfServiceLibrary1.Service1要么重命名该类。 Whytheq has found it himself with a colleague and as posted it here . Whytheq已经发现自己与同事和张贴在这里


More reading: Check out this article, which I've found recently: " WCF: a few tips ". 更多阅读:看看我最近发现的这篇文章:“ WCF:一些提示 ”。 It explains very well troubleshooting WCF. 它解释了WCF的故障排除。 The only change I would made to the console hosting example is to replace the using statement by a 我对控制台托管示例的唯一更改是 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;
    }
}

If you want to know more about the reason why, check out this article: " Proxy open and close ". 如果您想了解更多有关原因的信息,请查看此文章:“ 代理打开和关闭 ”。

You can get round this as follows: 您可以按如下方式解决此问题:

  • Browse the service's WSDL URL and save the WSDL to a local file. 浏览服务的WSDL URL并将WSDL保存到本地文件。
  • Then make the following changes to the file: 然后对文件进行以下更改:
  • Remove the namespace prefix from the name used for the wsdl:binding ie change name="wb:wsclocks-inboundSoapBinding" to be name="wsclocks-inboundSoapBinding" 从用于wsdl:binding的名称中删除名称空间前缀,即将name =“wb:wsclocks-inboundSoapBinding”更改为name =“wsclocks-inboundSoapBinding”
  • Change the binding attribute of the wsdl:port attribute to match, and also remove the namespace prefix from the value of the name attribute, so it is just wsclocks-inbound. 更改wsdl:port属性的绑定属性以匹配,并从name属性的值中删除名称空间前缀,因此它只是wsclocks-inbound。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM