1

我有一个向订阅客户端发送数据的 WCF 服务。使用顺序循环过程非常慢,因为循环中有 3 个循环,例如;

for (int x = 0 ; x <= MasterTables.count - 1 ;x ++)
{
    for (int y = 0; y <= MasterData[x].count ; y++)
    {
        foreach (SubList subscriber in subscribers.ToList())
        {
            SendDatatoSubscriber();
        }
    }
}

因此,我将顺序循环转换为并行循环,这反过来又快得多,但缺点是服务器同时向单个订阅者发布大量回调,因此传输通道超时。

SendDatatoSubscriber() 事件是一个同步调用,因为我需要客户端确认它已接收到对象并向服务器返回特定消息,因为有更多事件取决于此结果。

我的网络配置和客户端配置如下:

服务配置:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0"/>
    <authentication mode="None"/>
    <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
  </system.web>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="NetTcpSecure" closeTimeout="23:00:00" openTimeout="23:00:00" receiveTimeout="23:00:00" sendTimeout="23:00:00" transactionFlow="false" transferMode="Buffered" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="2000" maxReceivedMessageSize="2147483647" portSharingEnabled="true">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
          <reliableSession inactivityTimeout="23:00:00" enabled="false"/>
          <security mode="Message">
            <transport clientCredentialType="None">
              <extendedProtectionPolicy policyEnforcement="Never"/>
            </transport>
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="service.ClientBehavior" name=" service.DTSClient">
        <endpoint address="" behaviorConfiguration="WcfDts.DTSClientEndpointBehavior" binding="netTcpBinding" bindingConfiguration="NetTcpSecure" name="ClientNetTcp" contract="WcfDts.IDTSClient"/>
        <endpoint address="mex" binding="mexHttpBinding" behaviorConfiguration="WcfDts.DTSClientEndpointBehavior" contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://127.0.0.1:8000/WcfDts/Services"/>
          </baseAddresses>
          <timeouts closeTimeout="23:00:00"/>
        </host>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name=" service.DTSClientEndpointBehavior">
          <wsdlExtensions location="http://127.0.0.1/ service /Services/DTSClient.svc" singleFile="True"/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name=" service.ClientBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType=" service.CustomUserNameValidator, service "/>
            <serviceCertificate findValue="CertName" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
            <clientCertificate>
              <certificate findValue=" CertName " storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
            </clientCertificate>
          </serviceCredentials>
          <serviceThrottling maxConcurrentCalls="2000" maxConcurrentInstances="2000" maxConcurrentSessions="2000"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <extensions>
      <behaviorExtensions>
        <add name="wsdlExtensions" type="WCFExtras.Wsdl.WsdlExtensionsConfig, WCFExtras, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
      </behaviorExtensions>
    </extensions>
  </system.serviceModel>
</configuration>

客户端配置:

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="ClientNetTcp" closeTimeout="23:59:59" openTimeout="23:59:59" receiveTimeout="23:59:59" sendTimeout="23:59:59" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="100000" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="100000" maxReceivedMessageSize="2147483647">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
          <reliableSession ordered="true" inactivityTimeout="23:59:59" enabled="false"/>
          <security mode="Message">
            <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
            <message clientCredentialType="UserName" algorithmSuite="Default"/>
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://BaseAdress:Port/Services/Service.svc" binding="netTcpBinding" bindingConfiguration="ClientNetTcp" contract="Sub.IClient" name="ClientNetTcp">
        <identity>
          <dns value="CertName"/>
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>

所以我的问题是:

  1. 我是否需要修改配置以遏制超时情况
  2. 或者我如何让订阅者并行接收回调?
4

1 回答 1

0

您应该考虑使 SendData 如下所示。列是平行的,行是连续的。

订户 1 | 订阅者 2 | 订阅者 3 | ……

发送数据 1 | 发送数据 1 | 发送数据 1

发送数据 2 | 发送数据 2 | 发送数据 2

发送数据 3 | 发送数据 3 | 发送数据 3

......

我的意思是你可以同时调用为不同的订阅者发送数据。因此,您一次将数据发送给多个订阅者,但同时对于单个订阅者,您应该使其顺序化,这样您就不会陷入超时。

于 2013-02-11T12:53:11.723 回答