需要有关WCF服务编程的专家建议

时间:2013-05-14 17:55:25

标签: .net wcf web-services silverlight web-config

!---如果这篇帖子与其他帖子多余,我很抱歉,但我的项目问题似乎是我的架构问题,所以我需要一般的帮助。 ---!

我正在尝试配置连接到Silverlight 5客户端的WCF服务和对数据库执行CRUD请求的C#类库。该服务必须通过GIGANTIC数据量。例如,我有一个公共IList< RainRecord>我的服务类中的GetAllRain()方法可以检索数据库中的数十万条记录,有一天可能会比这更多。所以我认为我可以通过较小的批次获得所有这些记录(我认为这是一个非常好的方法)。

这是我的web.config文件:

<?xml version="1.0" encoding="utf-8"?>

<!--This file contains the web configuration used by the WCF service. -->

<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" maxBatchGeneratedFileSize="2147483647" maxBatchSize="2147483647" />
    <httpRuntime maxRequestLength="2147483647" />
  </system.web>

  <system.serviceModel>

   <serviceHostingEnvironment aspNetCompatibilityEnabled="true">
     <serviceActivations>
       <add service="PoseidonServiceNamespace.PoseidonService" relativeAddress="~/PoseidonService.svc"/>
     </serviceActivations>
   </serviceHostingEnvironment>

    <bindings>
      <basicHttpBinding>
        <binding  closeTimeout="00:01:00"
                  openTimeout="00:01:00"
                  receiveTimeout="00:10:00"
                  sendTimeout="00:01:00"
                  allowCookies="false"
                  bypassProxyOnLocal="false"
                  hostNameComparisonMode="StrongWildcard"
                  maxBufferSize="2147483647"
                  maxBufferPoolSize="2147483647"
                  maxReceivedMessageSize="2147483647"
                  messageEncoding="Text"
                  textEncoding="utf-8"
                  transferMode="Buffered"
                  useDefaultWebProxy="true">
          <readerQuotas maxDepth="2147483647"
                        maxStringContentLength="2147483647"
                        maxArrayLength="2147483647"
                        maxBytesPerRead="2147483647"
                        maxNameTableCharCount="2147483647" />
          <security mode="None">
            <transport  clientCredentialType="None"
                        proxyCredentialType="None"
                        realm="" />
            <message clientCredentialType="UserName"
                     algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name="PoseidonServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>



    <services>
      <service  behaviorConfiguration="PoseidonServiceBehavior"
                name="PoseidonServiceNamespace.PoseidonService">
        <endpoint address="http://localhost:49455/PoseidonService.svc"
                  binding="basicHttpBinding"
                  contract="PoseidonServiceNamespace.IPoseidonService"/>

        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange"/>
      </service>
    </services>
  </system.serviceModel>

 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

</configuration>

我应该在此文件中进行哪些更改(以及为什么?),以及如何在我的服务中实现公共IList GetAllRain()方法?

非常感谢, 我一直在敲打这个问题

1 个答案:

答案 0 :(得分:3)

您确定需要传输数十万条记录吗? 客户申请?客户如何查看这些记录? 这些记录是否会以某种方式进行预处理/汇总 在某些网格中显示? 如果预处理 - 考虑在服务器端进行预处理。 如果刚刚显示 - 考虑重新设计您的界面以包括分页:

IList<RainRecord> GetList(int startPage, int pageSize);

如果分页不是一个选项,但您仍然希望批量检索数据 - 您可以通过向您的服务引入状态来实现手动批处理 (您需要知道谁请求列表,您目前在哪个位置, 还有多少数据需要转移):

public interface IService
{
  Guid BeginGetList();
  IList<RainRecord> GetNextBatch(Guid id);
}

GetNextBatch返回的空列表或null表示传输结束。 换句话说,它是相同的分页,但使用有状态服务实现。

现在,如果绝对需要传输数十万条记录, 并且必须作为一个电话完成 - 考虑using streaming to transfer your data。 但您需要更改合同,将Stream与序列化的RainRecords一起包含。

另一种选择是implement duplex service,它会传递回调 到客户端,当客户端完成前一批处理后,它可以请求下一个。 这方面的缺点是,据我所知,Silverlight不支持WSDualHttpBinding。

通过附加绑定,您将被限制为每批2Gb,我相信这已经足够了。此外,您可能需要调整超时,this post详细描述所有可能的超时值。