我正在使用一个较旧的 WCF 服务/客户端。向其添加了一个新的(静态)日志系统,实际上现在正在做一些负载测试。
现在遇到一些非常烦人的零星问题 - 声称“无法打开安全通道,因为与远程端点的安全协商失败”。我注意到我收到一个 CommunicationException,错误名称为 Sender,子代码为 BadContextToken。
奇怪的是,我会得到 2-4 个正确的响应,然后是一连串的异常,然后又开始得到好的响应。
这是我第一次真正涉足 WCF,到目前为止我并不喜欢它:)
服务 web.config:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="ServiceBehavior" name="MyNamespace.MyService">
<endpoint address="" binding="wsHttpBinding" contract="MyNamespace.IMyService" bindingConfiguration="wsMessage">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceCredentials>
<serviceCertificate findValue="MyValue" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyNamespace.UserNamePassValidator, MyNamespace" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
在客户端,客户端是这样实例化的:
var binding = new WSHttpBinding();
binding.Name = "WSHttpBinding_IMyService";
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
var client = new MyService(binding, "http://myserver:8080/myapp/service.svc");
var endpointIdentity = new DnsEndpointIdentity("MyValue"); // Match the certificate name used by the server
client.Endpoint.Address = new EndpointAddress(new Uri("http://myserver:8080/myapp/service.svc"), endpointIdentity, client.Endpoint.Address.Headers);
var creds = client.ClientCredentials;
creds.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
creds.UserName.UserName = "myuser";
creds.UserName.Password = "mypassword";
string retVal = client.SendRequest(); // SendRequest == one of the methods on my IMyService, returns a string. This is also where I sporadically see my error when load testing.
如果有任何指示可以帮助我完成此 WCF 设置,我将不胜感激!
最佳答案
这些可能对您的 web.config 有用:
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="False" />
<serviceMetadata httpGetEnabled="True"/>
<serviceThrottling maxConcurrentCalls="20" maxConcurrentInstances="100"/>
</behavior>
</serviceBehaviors>
</behaviors>
<binding name="basicHttp" allowCookies="true" maxReceivedMessageSize="1048576" maxBufferSize="1048576" maxBufferPoolSize="1048576">
<readerQuotas maxDepth="32" maxArrayLength="1048576" maxStringContentLength="1048576"/>
</binding>
通常这种“随机”行为可能取决于:
- 超时(可能不是你的情况,因为你会得到不同的异常)
- 连接太多:如果您的客户端打开太多连接(并且“忘记”关闭它们),您将超过默认允许的最大值(取决于上下文,可能是 10 个连接)。
如果您更改 web.config,编辑
maxConcurrentCalls
和maxConcurrentInstances
,您可以对此采取行动
- 也许这些错误不是随机的,而是特定于某些消息;如果是这样,那可能是由于它的大小(即太大):再次更改您的 web.config 设置
maxReceivedMessageSize
、maxBufferSize
、maxBufferPoolSize
和readerQuotas
当然,如果您打开WCF tracing,您将获得更多信息。 .
关于c# - WCF/wsHttpBinding/消息安全 - BadTokenRequest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46944942/