C# 是否可以使 WcfTestClient 用于自定义传输通道?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/484717/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to make the WcfTestClient work for custom transport channels?
提问by EnocNRoll - AnandaGopal Pardue
Goal
目标
I would like to be able to both host and connect to a vanilla sockets server via WCF, within the hosting framework I am devising. I want to be able to use WCF to codify the transport and protocol communications that have to be manually managed by sockets programmers today. This would allow me the ultimate interoperability with Linux server daemons that expose nothing but traditional sockets and proprietary protocols. I am only interested in verifying that transport channel layer generically using WcfTestClient at this point. My understanding is that the WcfTestClient does not support complex service methods.
我希望能够在我设计的托管框架内通过 WCF 托管和连接到 vanilla 套接字服务器。我希望能够使用 WCF 对当今必须由套接字程序员手动管理的传输和协议通信进行编码。这将使我能够与 Linux 服务器守护进程实现最终的互操作性,这些守护进程只公开传统套接字和专有协议。我现在只对使用 WcfTestClient 验证传输通道层感兴趣。我的理解是 WcfTestClient 不支持复杂的服务方法。
Does anybody think it is possible to make the WcfTestClient work for custom transport channels?It would be really sweet to be able to generically use this client to test any number of custom transport channels.
有人认为可以让 WcfTestClient 用于自定义传输通道吗?能够通用地使用这个客户端来测试任意数量的自定义传输通道真的很不错。
Overview
概述
I am working to understand the WCF Udp sample that is included in the Windows SDK, located typically at C:\Program Files\Microsoft SDKs\Windows\v6.1\Samples\WCFSamples\TechnologySamples\Extensibility\Transport\Udp\CS, assuming that the WCFSamples.zip file is fully extracted from the Samples directory.
我正在努力了解 Windows SDK 中包含的 WCF Udp 示例,该示例通常位于 C:\Program Files\Microsoft SDKs\Windows\v6.1\Samples\WCFSamples\TechnologySamples\Extensibility\Transport\Udp\CS,假设WCFSamples.zip 文件是从 Samples 目录中完全提取出来的。
These are the steps I have taken thus far:
这些是我迄今为止采取的步骤:
(success): Run the solution's service and client successfully within Visual Studio 2008.
(success): connect to a MEX endpoint using the WcfTestClient typically located at C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE
(failure): use the WcfTestClient to attempt to execute a method from either the ICalculatorContract or the IDatagramContract service contract.
(成功):在 Visual Studio 2008 中成功运行解决方案的服务和客户端。
(成功):使用通常位于 C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE 的 WcfTestClient 连接到 MEX 端点
(失败):使用 WcfTestClient 尝试执行来自 ICalculatorContract 或 IDatagramContract 服务协定的方法。
When I execute the Hello() method, for example, I receive the following error:
例如,当我执行 Hello() 方法时,我收到以下错误:
Friendly message:
Failed to invoke the service. Possible causes: The service is offline or inaccessible; the client-side configuration does not match the proxy; the existing proxy is invalid. Refer to the stack trace for more detail. You can try to recover by starting a new proxy, restoring to default configuration, or refreshing the service.
Error Details:
The CustomBinding on the ServiceEndpoint with contract 'IDatagramContract' lacks a TransportBindingElement. Every binding must have at least one binding element that derives from TransportBindingElement. at System.ServiceModel.Channels.Binding.EnsureInvariants(String contractName) at System.ServiceModel.Description.ServiceEndpoint.EnsureInvariants() at System.ServiceModel.Channels.ServiceChannelFactory.BuildChannelFactory(ServiceEndpoint serviceEndpoint) at System.ServiceModel.ChannelFactory.CreateFactory() at System.ServiceModel.ChannelFactory.OnOpening() at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.ChannelFactory.EnsureOpened() at System.ServiceModel.ChannelFactory
1.CreateChannel(EndpointAddress address, Uri via) at System.ServiceModel.ChannelFactory
1.CreateChannel() at System.ServiceModel.ClientBase1.CreateChannel() at System.ServiceModel.ClientBase
1.CreateChannelInternal() at System.ServiceModel.ClientBase`1.get_Channel() at DatagramContractClient.Hello()
友情留言:
调用服务失败。可能原因:服务离线或无法访问;客户端配置与代理不匹配;现有代理无效。有关更多详细信息,请参阅堆栈跟踪。您可以尝试通过启动新代理、恢复到默认配置或刷新服务来恢复。
错误详情:
具有合同“IDatagramContract”的 ServiceEndpoint 上的 CustomBinding 缺少 TransportBindingElement。每个绑定必须至少有一个从 TransportBindingElement 派生的绑定元素。在 System.ServiceModel.Channels.Binding.EnsureInvariants(String contractName) 在 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(TimeSpan timeout) 在 System.ServiceModel.ChannelFactory.EnsureOpened() 在 System.ServiceModel.ChannelFactory
1.CreateChannel(EndpointAddress address, Uri via) at System.ServiceModel.ChannelFactory
1.CreateChannel() 在 System.ServiceModel.ClientBase1.CreateChannel() at System.ServiceModel.ClientBase
1.CreateChannelInternal() 在 System.ServiceModel.ClientBase`1.get_Channel() 在 DatagramContractClient.Hello()
Understanding the Client Error
了解客户端错误
The UdpTransportBindingElement that is defined in the UdpTransport project definitely derives from TransportBindingElement, as shown below, so I'm thinking that there must be something missing from the WcfTestClient configuration file and/or possibly that I have to somehow provide the test client with more information. I tried basically copying the System.ServiceModel section of the Udp solution's client project into the WcfTestClient's config file, as well as copying the transport assembly dll to the same folder as the test client, but I receive the same error.
UdpTransport 项目中定义的 UdpTransportBindingElement 肯定源自 TransportBindingElement,如下所示,所以我认为 WcfTestClient 配置文件中一定缺少某些内容和/或可能我必须以某种方式向测试客户端提供更多信息. 我基本上尝试将 Udp 解决方案的客户端项目的 System.ServiceModel 部分复制到 WcfTestClient 的配置文件中,并将传输程序集 dll 复制到与测试客户端相同的文件夹中,但我收到相同的错误。
My understanding is that the MEX endpoint should be enough to get the information required to invoke simple methods on the service. Of course, I understand that there is probably more to the story, considering that I'm trying to make a client that was designed to test the out-of-the-box transport channels work with custom transport channels.
我的理解是 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
Is ITransportPolicyImport Important for Custom Transport Channels?
ITransportPolicyImport 对自定义传输通道重要吗?
I ask about ITransportPolicyImport because that is an interface that is implemented by the standard WCF derivations of TransportBindingElement, but the Udp sample does not implement this interface, and I cannot find anything useful in web searches or on Safari. It may not even be relevant.
我询问 ITransportPolicyImport 是因为这是一个由 TransportBindingElement 的标准 WCF 派生实现的接口,但 Udp 示例没有实现这个接口,我在 Web 搜索或 Safari 上找不到任何有用的东西。它甚至可能不相关。
For example...
例如...
public class HttpTransportBindingElement :
: TransportBindingElement
, IWsdlExportExtension
, IPolicyExportExtension
, ITransportPolicyImport
Sample Configs...
示例配置...
The service config looks like this:
服务配置如下所示:
<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>
The client config from the solution looks like this:
解决方案中的客户端配置如下所示:
<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>
回答by janasainik
I am not aware of custom transport channels. I think as per my experiance, it may not possible to make the WcfTestClient work for custom transport channels.
我不知道自定义传输通道。我认为根据我的经验,可能无法让 WcfTestClient 用于自定义传输通道。
回答by Tim Roberts
It is possible to create custom transports in WCF. It's quite involved though!
可以在 WCF 中创建自定义传输。不过还是挺有参与感的!
Roman Kiss has built a Null Transport that allows you to consume and host the services from within the same process without the overhead of marshalling the data through one of the built in transports. His CodePlex article is available at:
Roman Kiss 构建了一个空传输,它允许您在同一进程内使用和托管服务,而无需通过内置传输之一编组数据的开销。他的 CodePlex 文章可从以下网址获得:
http://www.codeproject.com/KB/WCF/NullTransportForWCF.aspx
http://www.codeproject.com/KB/WCF/NullTransportForWCF.aspx
It may be a good starting point for helping you learn how to build your own transport. Good luck!
这可能是帮助您学习如何构建自己的交通工具的一个很好的起点。祝你好运!