Цель
Я хотел бы иметь возможность размещать и подключаться к серверу Vanilla Sockets через WCF, в рамках структуры хостинга, которую я разрабатываю. Я хочу иметь возможность использовать WCF для кодирования транспортных и протокольных соединений, которыми сегодня должны управлять программисты сокетов. Это позволило бы мне обеспечить максимальную совместимость с демонами серверов Linux, которые предоставляют только традиционные сокеты и проприетарные протоколы. Меня интересует только проверка уровня транспортного канала, в общем, с использованием WcfTestClient на данный момент. Насколько я понимаю, WcfTestClient не поддерживает сложные методы обслуживания.
Кто-нибудь думает, что можно заставить WcfTestClient работать на пользовательских транспортных каналах? Было бы очень приятно иметь возможность использовать этот клиент в общем для тестирования любого количества пользовательских транспортных каналов.
Обзор
Я работаю над тем, чтобы понять пример WCF Udp, включенный в Windows SDK, который обычно находится в C: \ Program Files \ Microsoft SDK \ Windows \ v6.1 \ Samples \ WCFSamples \ TechnologySamples \ Extensibility \ Transport \ Udp \ CS, при условии, что файл WCFSamples.zip полностью извлечен из каталога Samples.
Вот шаги, которые я предпринял до сих пор:
(успех): успешно запустите службу и клиент решения в Visual Studio 2008.
(успех): подключиться к конечной точке MEX с помощью WcfTestClient, обычно расположенного в C: \ Program Files \ Microsoft Visual Studio 9.0 \ Common7 \ IDE
(ошибка): используйте WcfTestClient, чтобы попытаться выполнить метод из контракта на обслуживание ICalculatorContract или IDatagramContract.
Например, когда я выполняю метод Hello (), я получаю следующую ошибку:
Дружеское сообщение:
Не удалось вызвать службу. Возможный
причины: служба не работает или
недоступный; на стороне клиента
конфигурация не соответствует
прокси; существующий прокси-сервер недействителен.
Обратитесь к трассировке стека для более
подробно. Вы можете попытаться восстановить путем
запуск нового прокси, восстановление
конфигурация по умолчанию или обновление
услуга.
Сведения об ошибке:
CustomBinding на
ServiceEndpoint с контрактом
«IDatagramContract» не хватает
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
тайм-аут) в
System.ServiceModel.ChannelFactory.EnsureOpened ()
в
System.ServiceModel.ChannelFactory 1.CreateChannel(EndpointAddress
address, Uri via) at
System.ServiceModel.ChannelFactory
1.CreateChannel ()
в
System.ServiceModel.ClientBase 1.CreateChannel()
at
System.ServiceModel.ClientBase
1.CreateChannelInternal ()
в
System.ServiceModel.ClientBase`1.get_Channel ()
в DatagramContractClient.Hello ()
Понимание ошибки клиента
UdpTransportBindingElement, который определен в проекте UdpTransport, определенно происходит от TransportBindingElement, как показано ниже, поэтому я думаю, что в файле конфигурации WcfTestClient должно быть что-то не хватает и / или, возможно, мне нужно как-то предоставить тестовый клиент с дополнительной информацией. Я попытался в основном скопировать раздел System.ServiceModel клиентского проекта решения Udp в файл конфигурации 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, потому что это интерфейс, который реализуется стандартными производными WCF для TransportBindingElement, но пример Udp не реализует этот интерфейс, и я не могу найти ничего полезного в веб-поиске или в 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>