【问题标题】:Returning large collections from WCF Serivce从 WCF 服务返回大型集合
【发布时间】:2010-05-07 16:02:46
【问题描述】:

我正在尝试确定构建 WCF 服务的最佳方法,而我最苦恼的领域是返回对象列表。

64k 的内置 maxMessageSize 似乎相当高,我真的不想提高它(快速谷歌搜索发现有 100 个地方将 maxMessageSize 提高到数 GB 范围,这似乎很愚蠢)。但是,当我返回一个对象集合(约 150 个项目)时,我超过了默认的 64k。

我几乎要返回我自己的类,该类继承 IEnumerable 并具有 hasNext、hasPrevious 和 PageSize 的属性,以便我可以在客户端实现分页——这似乎是很多代码。另一种选择是提升 maxMessageSize 并希望获得最好的结果,但这感觉不对。

我的服务的所有其他方面都运行良好,只是返回了我遇到问题的大量收藏。

作为背景,此服务有两种类型的消费者,UI 应用程序主要是 Web 和/或 wpf 应用程序,以及数据处理应用程序、.NET 控制台应用程序,可能还有其他一些非 UI 应用程序。对于 UI 应用程序,我想让它们保持响应并保持低消息大小,在控制台应用程序上这并不重要,因为它们只是将数据拉下来进行处理并将其推送回服务。

【问题讨论】:

  • 为什么增加 maxMessageSize 是愚蠢的?它实际上要么增加大小,要么分块发送。我不会一一要求。如果调用是异步的,UI 仍然可以响应大型集合。
  • 我猜愚蠢是一个不好的词选择,但我的意思是默认值的存在是有原因的,当我需要更改默认值时,我总是尝试退后一步,尤其是当我不需要时完全理解为什么默认是这样的。
  • Bross:默认消息大小为 64K,以避免拒绝服务攻击。想象一下,例如2 GB - 攻击者可以用 2 GB 消息淹没您的服务,从而压倒您可能拥有的任何硬件。拒绝任何大于 64K 的消息是不可能的(或至少不太可能)
  • 那么合理的大小是多少,因为 64k 似乎对于我处理的相对适中的数据大小来说应该绰绰有余,但我一直遇到这个限制是一个问题。

标签: .net wcf service


【解决方案1】:

我认为 maxMessageSize 的默认值如此之低的原因是为了降低 DoS 攻击的风险。

如果响应消息很大,则 client 配置需要增加 maxMessageSize。对于客户而言,DoS 不太可能构成风险,因此将其提高到一个非常大的值是安全的。

但这并不是“提高 maxMessageSize 并希望得到最好的结果”——您应该确定您的应用程序的预期最大大小,考虑您是否决定使用分页,并适当地配置它。

在服务器上,maxMessageSize 需要足够大以容纳最大允许的 request 消息。这里 DoS 可能是一个问题,尽管在某些环境(例如 Intranet)中使用非常大的值可能是安全的。

如果您的服务公开允许客户端查询可能较大的数据集的操作,则另一种分页方法是定义客户端在一次调用中可以请求的最大项目数。

例如,您可能有一个操作允许客户请求货币列表和日期范围的汇率:

public IList<ExchangeRate> GetExchangeRates(string baseCurrency, IList<string> currencies, DateTime startDate, DateTime endDate);

然后,您可以对服务返回的结果数量进行限制,并将其公开给客户端:

public int GetMaximumResultCount();

然后客户端会查询GetMaximumResultCount,并确保:

(endDate - startDate).TotalDays * currencies.Count < maximumResultCount

如果客户端不遵守这一点,服务器会抛出一个合适的FaultException

【讨论】:

    【解决方案2】:

    您可以使用 MTOM 消息编码。在发送大数据时,它是 Stream 的替代品。这是一个配置示例:

     <system.serviceModel>
         …
        <bindings>
          <wsHttpBinding>
            <binding name="ExampleBinding" messageEncoding="Mtom"/>
          </wsHttpBinding>
        </bindings>
         …
    <system.serviceModel>
    

    只需在您的绑定配置上将 messageEncoding 属性设置为 Mtom。另外,更改 ma​​xReceivedMessageSizema​​xBufferSize

    How To here 和更多信息 link text

    【讨论】:

    • 您也可以设置异步调用的操作,在获取数据的同时释放客户端操作。
    猜你喜欢
    • 2017-01-12
    • 1970-01-01
    • 2016-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多