工作组上的 WCF
Posted
技术标签:
【中文标题】工作组上的 WCF【英文标题】:WCF on a workgroup 【发布时间】:2020-11-27 02:54:42 【问题描述】:我已经使用 net tcp 绑定开发了 WCF windows 服务。当 wcf 客户端和 wcf 服务都在域中(在两个不同的系统中)时,它工作正常
当两个系统都在工作组而不在域中时出现错误
请建议我需要更改哪些配置。
错误:System.ServiceModel.CommunicationException:套接字连接被中止。这可能是由于处理您的消息时出错或远程主机超出接收超时,或者是潜在的网络资源问题引起的。本地套接字超时为“00:00:58.9879193”。 ---> System.Net.Sockets.SocketException: 现有连接被远程主机强行关闭
客户端配置
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<client>
<endpoint kind="discoveryEndpoint" address="net.tcp://localhost:8005/Probe" binding="netTcpBinding" bindingConfiguration="RequestReplyNetTcpBinding">
</endpoint>
<endpoint binding="netTcpBinding" bindingConfiguration="RequestReplyNetTcpBinding" contract="Test2ServLib.IService1" behaviorConfiguration="LargeEndpointBehavior">
<identity>
<dns value="WCFServer" />
</identity>
<!--The behaviorConfiguration is required to enable WCF deserialization of large data sets -->
</endpoint>
</client>
<behaviors>
<serviceBehaviors>
<behavior name="announcementBehavior">
<!--The following behavior attribute is required to enable WCF serialization of large data sets -->
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<serviceDiscovery>
<announcementEndpoints>
<endpoint kind="announcementEndpoint" address="net.tcp://localhost:8005/Announcement" binding="netTcpBinding" bindingConfiguration="RequestReplyNetTcpBinding" />
</announcementEndpoints>
</serviceDiscovery>
<serviceThrottling maxConcurrentCalls="1500" maxConcurrentSessions="1500" maxConcurrentInstances="1500" />
<clientCredentials>
<clientCertificate findValue="WCFClient"
storeLocation="LocalMachine"
storeName="TrustedPeople"
x509FindType="FindBySubjectName" />
<serviceCertificate >
<authentication certificateValidationMode="PeerTrust" revocationMode="NoCheck"/>
</serviceCertificate>
</clientCredentials>
</behavior>
<behavior name="LargeEndpointBehavior">
<!--The behavior is required to enable WCF deserialization of large data sets -->
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<clientCredentials>
<clientCertificate findValue="WCFClient"
storeLocation="LocalMachine"
storeName="TrustedPeople"
x509FindType="FindBySubjectName" />
<serviceCertificate >
<authentication certificateValidationMode="PeerTrust" revocationMode="NoCheck"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="disableEndpointDiscovery">
<endpointDiscovery enabled="false" />
<!--The behavior is required to enable WCF deserialization of large data sets -->
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<clientCredentials>
<clientCertificate findValue="WCFClient"
storeLocation="LocalMachine"
storeName="TrustedPeople"
x509FindType="FindBySubjectName" />
<serviceCertificate >
<authentication certificateValidationMode="PeerTrust" revocationMode="NoCheck"/>
</serviceCertificate>
</clientCredentials>
</behavior>
<behavior name="LargeEndpointBehavior">
<!--The behavior is required to enable WCF deserialization of large data sets -->
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<clientCredentials>
<clientCertificate findValue="WCFClient"
storeLocation="LocalMachine"
storeName="TrustedPeople"
x509FindType="FindBySubjectName" />
<serviceCertificate >
<authentication certificateValidationMode="PeerTrust" revocationMode="NoCheck"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="RequestReplyNetTcpBinding" receiveTimeout="05:00:00" openTimeout="00:00:59" closeTimeout="00:00:59" maxBufferPoolSize="524288" maxBufferSize="25000000" maxConnections="50" maxReceivedMessageSize="25000000" sendTimeout="00:05:00" listenBacklog="1500">
<reliableSession ordered="false" inactivityTimeout="00:01:00" enabled="true" />
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security>
<message clientCredentialType="Certificate"/>
</security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
服务配置
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="announcementBehavior">
<!--The following behavior attribute is required to enable WCF serialization of large data sets -->
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<serviceDiscovery>
<announcementEndpoints>
<endpoint kind="announcementEndpoint"
address="net.tcp://localhost:8005/Announcement"
binding="netTcpBinding"
bindingConfiguration="RequestReplyNetTcpBinding"/>
</announcementEndpoints>
</serviceDiscovery>
<serviceThrottling
maxConcurrentCalls="1500"
maxConcurrentSessions="1500"
maxConcurrentInstances="1500"/>
<serviceCredentials>
<serviceCertificate findValue="WCFServer"
storeLocation="LocalMachine"
storeName="TrustedPeople"
x509FindType="FindBySubjectName" />
<clientCertificate>
<authentication certificateValidationMode="PeerTrust" trustedStoreLocation="LocalMachine" revocationMode="NoCheck" mapClientCertificateToWindowsAccount="false" />
</clientCertificate>
</serviceCredentials>
</behavior>
<endpointBehaviors>
<behavior name="disableEndpointDiscovery">
<endpointDiscovery enabled="false"/>
<!--The behavior is required to enable WCF deserialization of large data sets -->
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<serviceCredentials>
<serviceCertificate findValue="WCFServer"
storeLocation="LocalMachine"
storeName="TrustedPeople"
x509FindType="FindBySubjectName" />
<clientCertificate>
<authentication certificateValidationMode="PeerTrust" trustedStoreLocation="LocalMachine" revocationMode="NoCheck" mapClientCertificateToWindowsAccount="false" />
</clientCertificate>
</serviceCredentials>
</behavior>
<behavior name="LargeEndpointBehavior">
<!--The behavior is required to enable WCF deserialization of large data sets -->
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<serviceCredentials>
<serviceCertificate findValue="WCFServer"
storeLocation="LocalMachine"
storeName="TrustedPeople"
x509FindType="FindBySubjectName" />
<clientCertificate>
<authentication certificateValidationMode="PeerTrust" trustedStoreLocation="LocalMachine" revocationMode="NoCheck" mapClientCertificateToWindowsAccount="false" />
</clientCertificate>
</serviceCredentials>
</behavior>
</endpointBehaviors>
</behavior>
</serviceBehaviors>
<service name="Test2ServLib.IService1"
behaviorConfiguration="announcementBehavior">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8006/Service1"/>
</baseAddresses>
</host>
<endpoint binding="netTcpBinding"
bindingConfiguration="RequestReplyNetTcpBinding"
contract="Test2ServLib.IService1"
behaviorConfiguration="LargeEndpointBehavior" />
<bindings>
<netTcpBinding>
<binding RequestReplyNetTcpBinding>
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
【问题讨论】:
【参考方案1】:根据您提供的信息,很可能是由于传输的数据量大导致错误。 NetTcpbing 在局域网中会有更高的传输性能。所以你在同一个域中没有错误。 WCF 默认超时期限为 1 分钟。如果一分钟内没有传输数据,就会报错。我建议你延长服务器端的超时时间:
<bindings>
<netTcpBinding>
<binding openTimeout="00:10:00"
closeTimeout="00:10:00"
sendTimeout="00:10:00"
receiveTimeout="00:20:00">
</binding>
</netTcpBinding>
</bindings>
另外,请启用支持NetTCP协议的windows功能。
如果问题仍然存在,请随时告诉我。
更新
如果客户端和服务器不在同一台机器上,客户端需要提供windows凭据,因为nettcpbinding默认是windows认证:
ServiceReference1.CalculatorClient calculatorClient = new ServiceReference1.CalculatorClient();
calculatorClient.ClientCredentials.Windows.ClientCredential.UserName = "Administrator";
calculatorClient.ClientCredentials.Windows.ClientCredential.Password = "Password";
如果这个问题依然存在,建议添加一个mex端点:
<endpoint address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange"></endpoint>
将 Mode 值设置为 Message:
<binding name="Binding">
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
在你的配置文件中,我发现你没有设置Mode的值。
这是我的 App.config:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="Microsoft.Samples.X509CertificateValidator.CalculatorService" behaviorConfiguration="CalculatorServiceBehavior">
<!-- use host/baseAddresses to configure base address provided by host -->
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8001/servicemodelsamples/service"/>
</baseAddresses>
</host>
<!-- use base address specified above, provide one endpoint -->
<endpoint address="certificate" binding="netTcpBinding" bindingConfiguration="Binding" contract="Microsoft.Samples.X509CertificateValidator.ICalculator"/>
</service>
</services>
<bindings>
<netTcpBinding>
<!-- X509 certificate binding -->
<binding name="Binding">
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata/>
<serviceCredentials>
<!--
The serviceCredentials behavior allows one to specify authentication constraints on client certificates.
-->
<clientCertificate>
<authentication certificateValidationMode="None" revocationMode="NoCheck"/>
</clientCertificate>
<!--
The serviceCredentials behavior allows one to define a service certificate.
A service certificate is used by a client to authenticate the service and provide message protection.
This configuration references the "localhost" certificate installed during the setup instructions.
-->
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
【讨论】:
问题依旧 我的绑定设置为证书身份验证以上是关于工作组上的 WCF的主要内容,如果未能解决你的问题,请参考以下文章