简短版本:localhost
当客户端是不同机器上的 Java 时, WCF Windows 服务端点地址配置可以用作主机名吗?
长版:
我有一个作为 Windows 服务运行的 WCF 服务。该服务的客户端是用 Java 编写的,代理类使用wsimport
. 当 WCF 服务上的端点配置包含包含 WCF 服务所在主机名的地址时,我可以生成 Java 代理类wsimport
并成功运行客户端。在这种情况下,WCF 配置文件如下所示:
<service name="crOps.CompanionService" behaviorConfiguration="CompanionServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://chvprdctxxa604.eu.scor.local:8432/crOpsCompanion/service"/>
</baseAddresses>
</host>
<endpoint address="" binding="basicHttpBinding" contract="crOps.ICompanionService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
这是wsimport
生成代理的命令:
C:\Program Files\Java\jdk1.7.0_17\bin\wsimport.exe -p crOps.companion -keep http://chvprdctxxa604.eu.scor.local:8432/crOpsCompanion/service?wsdl
这一切都很好。
然而,这个 WCF 服务在大约十几个服务器上运行。我目前的愿望是使配置文件“与主机无关”,这意味着相同的配置文件适用于所有服务器。换句话说,配置文件中没有主机名。
我四处寻找一种方法来确认 WCF 配置文件,但一无所获。所以我决定尝试localhost
代替主机名。看起来像这样...
<service name="crOps.CompanionService" behaviorConfiguration="CompanionServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8432/crOpsCompanion/service"/>
</baseAddresses>
</host>
<endpoint address="" binding="basicHttpBinding" contract="crOps.ICompanionService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
但是,当我运行wsimport
命令(上面列出)时,出现以下错误:
parsing WSDL...
[ERROR]
Unable to parse "http://localhost:8432/crOpsCompanion/service?wsdl=wsdl0" :
Connection refused: connect
line 1 of http://chvprdctxxa604.eu.scor.local:8432/crOpsCompanion/service?wsdl
[ERROR]
Unable to parse "http://localhost:8432/crOpsCompanion/service?wsdl=wsdl0" :
Connection refused: connect
Failed to read the WSDL document:
http://chvprdctxxa604.eu.scor.local:8432/crOpsCompanion/service?wsdl, because
1) could not find the document;
2) the document could not be read;
3) the root element of the document is not <wsdl:definitions
>.
[ERROR] failed.noservice=Could not find wsdl:service in the provided WSDL(s):
http://chvprdctxxa604.eu.scor.local:8432/crOpsCompanion/service?wsdl
At least one WSDL with at least one service definition needs to be provided.
Failed to parse the WSDL.
所以,我想知道的是:localhost
当客户端是不同机器上的 Java 时,WCF Windows 服务端点地址配置可以用作主机名吗?如果不是,为什么不呢?如果是这样,怎么做?
24 小时后:
还是没有解决。
Shiraz Bhaiji 提出的使用 NLB 的技术确实实现了我的部分目标:为所有服务器提供一个配置文件。端点地址中的主机名将是集群呈现给世界的“集群名称”,并且所有服务器上的所有服务都将具有相同的名称。
在我的 NLB 解决方案中,问题是运行该服务器的每台服务器都必须单独联系。它不是真正的集群类型服务,它更像是一种本地服务,十几个服务器中的每一个都需要运行,并且客户端将单独联系每个服务。
继续使用 Yaron Naveh 的回复中描述的技术,即使用本地 WSDL 文件生成代理。我能够生成 Java 代理类,wsimport
但是当我使用它们访问 Web 服务(端点地址中有 localhost)时,我得到了这个异常。这本身对我来说很奇怪,它是单个 printStackTrace() 调用的输出,似乎是包装了另外两个的异常,但它看起来不像我习惯从堆栈跟踪中的包装异常中看到的那样.
com.sun.xml.internal.ws.wsdl.parser.InaccessibleWSDLException: 2 counts of InaccessibleWSDLException.
javax.xml.stream.XMLStreamException: Invalid WSDL http://chvprdctxxa604:8432/crOpsCompanion/service, expected {http://schemas.xmlsoap.org/wsdl/}definitions found HTML at (lineLine number = 1
Column number = 7
System Id = http://chvprdctxxa604:8432/crOpsCompanion/service
Public Id = null
Location Uri= http://chvprdctxxa604:8432/crOpsCompanion/service
CharacterOffset = 10
)
java.io.IOException: Got Connection refused: connect while opening stream from http://localhost:8432/crOpsCompanion/service?wsdl=wsdl0
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(Unknown Source)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(Unknown Source)
at javax.xml.ws.Service.<init>(Unknown Source)
at crOps.companion.CompanionService.<init>(CompanionService.java:58)
at crOps.companion.Main.main(Main.java:14)
我在堆栈跟踪中注意到代理类正在尝试连接以localhost
在运行时检索 WSDL,尽管代理是使用不包含对 localhost 的引用的 WSDL 生成的。<wsdl:import>
但是,WCF 服务发出的 WSDL 确实在元素中包含 localhost 引用:
<wsdl:import namespace="http://crOps.CompanionService" location="http://localhost:8432/crOpsCompanion/service?wsdl=wsdl0" />
所以Java试图检索location
属性中的WSDL并且不能。
我开始想,用 C# 编写的 WCF 客户端会做同样的事情吗?换句话说,WCF 客户端是否想在运行时访问<wsdl:import>
'slocation
属性中指定的 WSDL?我经历了创建 WCF 客户端代理的相同过程,就像我为 Java 所做的那样。我使用了一个没有引用 to 的 WSDLlocalhost
来生成代理类,然后访问了一个 WCF 服务,该服务的配置文件包含localhost
在 WCF 端点地址配置中。
这行得通!WCF 客户端不需要能够在运行时检索在元素的location
属性中指定的 WSDL。<wsdl:import>
所以现在这已成为我眼中的 Java/wsimport 问题。
我的大脑现在很累。我稍后会回来清理这堵文字墙,让它成为有人愿意阅读和回应的东西。