ゴール
私が考案しているホスティング フレームワーク内で、WCF を介してバニラ ソケット サーバーをホストし、接続できるようにしたいと考えています。私は、WCF を使用して、今日ソケット プログラマーが手動で管理しなければならないトランスポートおよびプロトコル通信を体系化できるようにしたいと考えています。これにより、従来のソケットと独自のプロトコルのみを公開する 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 内でソリューションのサービスとクライアントを正常に実行します。
(成功): 通常は C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE にある WcfTestClient を使用して MEX エンドポイントに接続します
(失敗): WcfTestClient を使用して、ICalculatorContract または IDatagramContract サービス コントラクトからメソッドを実行しようとします。
たとえば、Hello() メソッドを実行すると、次のエラーが表示されます。
友好的なメッセージ:
サービスの呼び出しに失敗しました。考えられる原因: サービスがオフラインであるか、アクセスできません。クライアント側の構成がプロキシと一致しません。既存のプロキシは無効です。詳細については、スタック トレースを参照してください。新しいプロキシを開始するか、デフォルト構成に復元するか、サービスを更新することで、回復を試みることができます。
エラーの詳細:
コントラクト「IDatagramContract」を持つ ServiceEndpoint の CustomBinding に、TransportBindingElement がありません。すべてのバインディングには、TransportBindingElement から派生したバインディング要素が少なくとも 1 つ必要です。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()
クライアント エラーについて
UdpTransport プロジェクトで定義されている UdpTransportBindingElement は、以下に示すように、間違いなく 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>