1

我有一个运行在服务器上的 .NET WCF Web 服务,我可以从几台不同的计算机访问该服务。为了测试我的连接性,我有一个 PowerShell 脚本,它构建代理、连接到 Web 服务、发送消息并断开连接。构建代理的代码来自这里:http ://www.ilovesharepoint.com/2008/12/call-wcf-services-with-powershell.html

我有一个批处理文件,它运行脚本的多次迭代(500 次),我看到不同的行为取决于我在哪台客户端计算机上运行测试脚本:

  • COMPUTER 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 target, Object[] arguments, MethodInformation methodInformation, Object[] originalArguments) 在 System.Management.Automation.DotNetAdapter.MethodInvokeDotNet(String methodName, Object target, MethodInformation [] methodInformation,对象 [] 参数)在 System.Management.Automation.Adapter.BaseMethodInvoke(PSMethod 方法,对象 [] 参数)在 System.Management.Automation.ParserOps.CallMethod(令牌令牌,对象目标,字符串方法名,对象 [] 参数阵列, Boolean callStatic, Object valueToSet) at System.Management.Automation.MethodCallNode.InvokeMethod(Object target, Object[] arguments, Object value) at System.Management.Automation.MethodCallNode.Execute(Array input, Pipe outputPipe,ExecutionContext 上下文)在 System.Management.Automation.AssignmentStatementNode.Execute(数组输入,管道 outputPipe,ExecutionContext 上下文)在 System.Management.Automation.StatementListNode.ExecuteStatement(ParseTreeNode 语句,数组输入,管道输出管道,ArrayList 和结果列表,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   
}

我的网络服务配置如下:

    <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 服务运行性能测试,并且这些故障阻碍了我的能力进行测试。我不能使用 COMPUTER A 进行测试,因为我不想进入这里。我可以看到两台计算机之间的唯一区别是计算机 A 是 Windows 7 Professional 工作站,计算机 B 是 Windows 2008 R2 服务器。两者都安装了相同版本的 .NET 框架和 PowerShell。

有人对为什么 COMPUTER B 无法尝试获取我的 Web 服务的元数据有任何想法吗?

4

1 回答 1

1

我想我找到了原因和治疗方法。

COMPUTER B 有 6 个网络适配器,一个连接到我们的公司网络,一个禁用,另外 4 个启用,每个都有自己的 IP 地址,并连接到“未知网络”。我禁用了除连接到我们网络的 1 个适配器之外的所有适配器,计算机 B 现在的行为类似于计算机 A。

于 2012-12-07T16:33:06.957 回答