Можно ли заставить WcfTestClient работать на пользовательских транспортных каналах? - PullRequest
14 голосов
/ 27 января 2009

Цель

Я хотел бы иметь возможность размещать и подключаться к серверу 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>

Ответы [ 2 ]

2 голосов
/ 05 октября 2010

Возможно создание пользовательских транспортов в WCF. Это довольно сложно, хотя!

Roman Kiss создал Null Transport, который позволяет вам использовать и размещать сервисы в одном и том же процессе без дополнительных затрат на маршалинг данных через один из встроенных транспортов. Его статья CodePlex доступна по адресу:

http://www.codeproject.com/KB/WCF/NullTransportForWCF.aspx

Это может быть хорошей отправной точкой для того, чтобы помочь вам научиться строить свой собственный транспорт. Удачи!

1 голос
/ 05 октября 2010

Я не знаю о пользовательских транспортных каналах. Я думаю, что, по моему опыту, WcfTestClient может не работать для пользовательских транспортных каналов.

...