目标
我希望能够通过wcf在我正在设计的托管框架内托管和连接到vanilla sockets服务器。我希望能够使用wcf来对传输和协议通信进行编码,这些通信现在必须由sockets程序员手动管理。这将允许我与linux服务器守护进程的最终互操作性,这些守护进程只公开传统的套接字和专有协议。我只想在这一点上验证通常使用wcftestclient的传输通道层。我的理解是wcftestclient不支持复杂的服务方法。
有人认为可以让wcftestclient为自定义传输通道工作吗?
能够通用地使用这个客户机来测试任意数量的自定义传输通道,这将是非常好的。
概述
我正在努力理解windows sdk中包含的wcf udp示例,该示例通常位于c:\ Program Files\Microsoft sdks\windows\v6.1\samples\wcfsamples\technologysamples\extensibility\transport\udp\cs,假设wcfsamples.zip文件完全从samples目录提取。
这些是我迄今为止采取的步骤:
-
(成功):在Visual Studio 2008中成功运行解决方案的服务和客户端。
-
(成功):使用wcftestclient连接到MEX端点,该客户端通常位于C:\ Program Files\Microsoft Visual Studio 9.0\Common7\IDE
-
(失败):使用wcftestclient尝试从icalculatorcontract或idatagramcontract服务合同执行方法。
例如,当我执行hello()方法时,收到以下错误:
友好消息:
无法调用服务。可能的
原因:服务脱机或
不可访问;客户端
配置与
代理;现有代理无效。
有关更多信息,请参阅堆栈跟踪
细节。你可以试着通过
启动新代理,还原到
默认配置,或刷新
服务。
错误详细信息:
上的custombinding
具有协定的ServiceEndpoint
“idatagramcontract”缺少
传输绑定元素。每个
绑定必须至少有一个绑定
从中派生的元素
传输绑定元素。在
system.servicemodel.channels.binding.EnsureVariants(字符串
合同名称)
system.servicemodel.description.serviceEndpoint.EnsureInvariants()
在
system.servicemodel.channels.serviceChannelFactory.buildChannelFactory(serviceEndpoint
serviceEndpoint)位于
system.servicemodel.channelfactory.createfactory()
在
system.servicemodel.channelfactory.onopening()
在
system.servicemodel.channels.communicationobject.open(时间跨度
超时)在
system.servicemodel.channelfactory.ensureopened()
在
系统.servicemodel.channelfactory
1.CreateChannel(EndpointAddress
address, Uri via) at
System.ServiceModel.ChannelFactory
1.创建频道()
在
system.servicemodel.clientbase系统
1.CreateChannel()
at
System.ServiceModel.ClientBase
1.创建通道内部()
在
system.servicemodel.clientbase`1.get_channel()
在datagramcontractclient.hello()
理解客户端错误
在udptTransport项目中定义的udptTransportBindingElement肯定是从transportBindingElement派生的,如下所示,因此,我认为wcftestclient配置文件中一定缺少某些内容,并且/或者可能需要以某种方式向测试客户机提供更多信息。我尝试将udp解决方案的客户端项目的system.servicemodel部分复制到wcftestclient的配置文件中,并将传输程序集dll复制到与测试客户端相同的文件夹中,但收到了相同的错误。
我的理解是,mex端点应该足以获取调用服务上的简单方法所需的信息。当然,考虑到我正在尝试让一个设计用于测试开箱即用传输通道的客户机与自定义传输通道一起工作,我知道这个故事可能还有更多内容。
/// <summary>
/// Udp Binding Element.
/// Used to configure and construct Udp ChannelFactories and ChannelListeners.
/// </summary>
public class UdpTransportBindingElement
: TransportBindingElement // to signal that we're a transport
, IPolicyExportExtension // for policy export
, IWsdlExportExtension
itransportpolicyimport对于自定义传输通道重要吗?
我询问itransportpolicyimport,因为它是由transportbindingelement的标准wcf派生实现的接口,但是udp示例没有实现此接口,并且在web搜索或safari中找不到任何有用的东西。这甚至可能无关紧要。
例如。。。
public class HttpTransportBindingElement :
: TransportBindingElement
, IWsdlExportExtension
, IPolicyExportExtension
, ITransportPolicyImport
示例配置…
服务配置如下:
<system.serviceModel>
<!--
add our udpTransport handler for use by binding declarations
-->
<!--
add our standard binding handler for use by binding declarations
-->
<extensions>
<bindingElementExtensions>
<add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport" />
</bindingElementExtensions>
<bindingExtensions>
<add name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />
</bindingExtensions>
</extensions>
<services>
<service name="Microsoft.ServiceModel.Samples.ConfigurableCalculatorService" behaviorConfiguration="udpServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/udpsample"/>
</baseAddresses>
</host>
<endpoint address="soap.udp://localhost:8001/"
binding="sampleProfileUdpBinding"
bindingConfiguration="CalculatorServer"
contract="Microsoft.ServiceModel.Samples.ICalculatorContract" />
<endpoint address="soap.udp://localhost:8002/datagram"
binding="customBinding"
bindingConfiguration="DatagramServer"
contract="Microsoft.ServiceModel.Samples.IDatagramContract" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<!--
server bindings
-->
<sampleProfileUdpBinding>
<binding name="CalculatorServer" clientBaseAddress="soap.udp://localhost:8003/" />
<binding name="DatagramServer" reliableSessionEnabled="false" />
</sampleProfileUdpBinding>
<customBinding>
<binding name="DatagramServer">
<binaryMessageEncoding />
<udpTransport/>
</binding>
</customBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="udpServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
<client>
<endpoint address="" binding="sampleProfileUdpBinding" bindingConfiguration="CalculatorServer"
contract="Microsoft.ServiceModel.Samples.ICalculatorContract"
name="CalculatorClient" />
</client>
</system.serviceModel>
解决方案中的客户端配置如下所示:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomBinding_IDatagramContract">
<binaryMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
maxSessionSize="2048">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binaryMessageEncoding>
<UpdTransportElementClientSide maxBufferPoolSize="524288" maxMessageSize="65536"
multicast="false" />
</binding>
</customBinding>
<sampleProfileUdpBinding>
<binding name="SampleProfileUdpBinding_ICalculatorContract" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
orderedSession="true" reliableSessionEnabled="true" sessionInactivityTimeout="00:10:00"
clientBaseAddress="soap.udp://localhost:8003/" />
</sampleProfileUdpBinding>
</bindings>
<client>
<endpoint address="soap.udp://localhost:8001/" binding="sampleProfileUdpBinding"
bindingConfiguration="SampleProfileUdpBinding_ICalculatorContract"
contract="ICalculatorContract" name="SampleProfileUdpBinding_ICalculatorContract" />
<endpoint address="soap.udp://localhost:8002/datagram" binding="customBinding"
bindingConfiguration="CustomBinding_IDatagramContract" contract="IDatagramContract"
name="CustomBinding_IDatagramContract" />
</client>
<extensions>
<bindingElementExtensions>
<add name="UpdTransportElementClientSide" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport" />
</bindingElementExtensions>
<!-- This was added manually because svcutil.exe does not add this extension to the file -->
<bindingExtensions>
<add name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />
</bindingExtensions>
</extensions>
</system.serviceModel>