複数の異なるコンピューターからアクセスするサーバー上で実行されている .NET WCF Web サービスがあります。接続をテストするために、プロキシを構築し、Web サービスに接続し、メッセージを送信し、切断する PowerShell スクリプトがあります。プロキシを構築するコードは、http ://www.ilovesharepoint.com/2008/12/call-wcf-services-with-powershell.html から取得します。
スクリプトを複数回 (500 回) 実行するバッチ ファイルがあり、テスト スクリプトを実行するクライアント コンピューターによって異なる動作が見られます。
- コンピューター A: 失敗することなく、スクリプトを正常に実行します。500 回の反復をすべて実行するには、約 15 分かかります。
- コンピューター B: 反復は約 3% から 4% の確率で失敗します。500 回の反復をすべて実行するには1 時間以上かかります。障害は 3 ~ 5 分ごとに発生します。
スクリプトが失敗すると、返されるメッセージは次のとおりです。
"0" 個の引数を指定して "GetMetadata" を呼び出し中に例外が発生しました: "メタデータには、解決できない参照が含まれています: 'https:// SERVER:8733/WSEngineService/?WSDL'." D:\CLIENT\proxyTest.ps1:32 char:41 + $metadataSet = $mexClient.GetMetadata <<<< () + CategoryInfo : NotSpecified: (:) []、ParentContainsErrorRecordException + FullyQualifiedErrorId : DotNetMethodException
例外のスタック トレースは次のとおりです。
System.Management.Automation.DotNetAdapter.AuxiliaryMethodInvoke (オブジェクト ターゲット、Object[] 引数、MethodInformation methodInformation、Object[] originalArguments) で System.Management.Automation.DotNetAdapter.MethodInvokeDotNet (文字列 methodName、オブジェクト ターゲット、MethodInformation [] methodInformation、 Object[] 引数) System.Management.Automation.Adapter.BaseMethodInvoke(PSMethod メソッド、Object[] 引数) で System.Management.Automation.ParserOps.CallMethod(トークン トークン、オブジェクト ターゲット、文字列 methodName、Object[] paramAr ray、 System.Management.Automation.MethodCallNode.InvokeMethod(オブジェクト ターゲット、Object[] 引数、オブジェクト値) で System.Management.Automation.MethodCallNode.Execute(配列入力、パイプ outputPipe、ExecutionContext コンテキスト) System.Management.Automation.AssignmentStatementNode.Execute (配列入力、パイプ outputPipe、ExecutionContext コンテキスト) で System.Management.Automation.StatementListNode.ExecuteStatement (ParseTreeNode ステートメント、配列入力、パイプ出力 Pipe、ArrayList& resultList、ExecutionContext コンテキスト) )
MEX クライアントのプロパティは次のとおりです。
PS D:\CLIENT>>> $mexClient
SoapCredentials : System.ServiceModel.Description.ClientCredentials
HttpCredentials :
OperationTimeout : 00:01:00
MaximumResolvedReferences : 2147483647
ResolveMetadataReferences : True
これは、例外が発生しているコードです。
# get metadata of a service
function global:Get-WsdlImporter($wsdlUrl=$(throw "parameter -wsdlUrl is missing"), $httpGet)
{
if($httpGet -eq $true)
{
$local:mode = [System.ServiceModel.Description.MetadataExchangeClientMode]::HttpGet
}
else
{
$local:mode = [System.ServiceModel.Description.MetadataExchangeClientMode]::MetadataExchange
}
$mexClient = New-Object System.ServiceModel.Description.MetadataExchangeClient((New-Object System.Uri($wsdlUrl)),$mode)
$mexClient.MaximumResolvedReferences = [System.Int32]::MaxValue
$metadataSet = $mexClient.GetMetadata() # <-- Fails sometimes on COMPUTER B but never on COMPUTER A.
$wsdlImporter = New-Object System.ServiceModel.Description.WsdlImporter($metadataSet)
return $wsdlImporter
}
私の Web サービスは次のように構成されています。
<behavior name="WsTuBehaviorConfig">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" httpsGetBinding="" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="40" maxConcurrentSessions="40" maxConcurrentInstances="40" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerTrust" />
</clientCertificate>
<userNameAuthentication userNamePasswordValidationMode="Custom" membershipProviderName="Ldap" customUserNamePasswordValidatorType="MyProduct.Framework.Security.AuthenticationProvider.UserNamePasswordLdapUserId,MyProduct.Framework.Security.AuthenticationProvider" />
</serviceCredentials>
<serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="LdapOperationProvider" />
<useRequestHeadersForMetadataAddress />
</behavior>
<ws2007HttpBinding>
<binding name="ws2007HttpTuBindingConfig" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="3200" maxStringContentLength="8192" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="Basic" proxyCredentialType="None" />
<message clientCredentialType="None" negotiateServiceCredential="false" establishSecurityContext="false" />
</security>
</binding>
</ws2007HttpBinding>
<service behaviorConfiguration="WsTuBehaviorConfig" name="MyProduct.BusinessLibrary.Services.WSEngineService">
<endpoint name="WsEngineWs2007HttpEp" address="ws2007HttpEP" binding="ws2007HttpBinding" bindingConfiguration="ws2007HttpTuBindingConfig" behaviorConfiguration="accessDeniedFaultBehaviorConfig" contract="MyProduct.BusinessLibrary.Services.IWSEngineService" />
<endpoint name="mexWSEngineEP" address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="https://SERVER:8733/WSEngineService/" />
</baseAddresses>
</host>
</service>
SSL 警告を無視するようにプロキシ テスト スクリプトに指示しています。
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
コンピューター B ではスクリプトが時々失敗するのに、コンピューター A では決して失敗しない理由がわかりません。残念ながら、コンピューター B は Web サービスに対してパフォーマンス テストを実行するためのロード ドライバーであり、この失敗により、次の作業が妨げられています。テストを実施します。ここには入りたくないので、テストにコンピュータ A を使用することはできません。2 台のコンピューターの唯一の違いは、コンピューター A が Windows 7 Professional ワークステーションであり、コンピューター B が Windows 2008 R2 サーバーであることです。どちらにも同じバージョンの .NET フレームワークと PowerShell がインストールされています。
コンピューター B が Web サービスのメタデータを取得しようとして失敗する理由について、何か考えがある人はいますか?