通过Web服务按需流式传输数据

时间:2011-04-04 12:42:59

标签: c# web-services wcf stream

我有一项公开服务的任务,该服务将提供可能非常大量的数据(千兆字节)。因此,它必须按需流式传输数据,以便数据不会缓存在内存中。在发送给客户端之前,数据将经过以下步骤。

  1. 从数据库中提取数据
  2. 将数据序列化为XML
  3. 使用gzip
  4. 压缩XML数据
  5. 以流形式将数据发送到客户端
  6. 可能会遗漏第3步,因为WCF可以进行压缩。是否有推荐的方法来执行此操作,而不会在任何步骤中缓冲大量数据,这显然会使应用程序崩溃,数据可能为100GB?

1 个答案:

答案 0 :(得分:3)

由于这是一项任务,我不确定你有什么限制或练习的基本目的是什么,但优化像这样的数据传输服务,并使其稳定,并非易事。发生通信问题的可能性很大,因此您需要处理这种可能性。但是如果出现问题,你不仅仅想重新开始,因为这会浪费你所做的所有工作直到问题。

在基本级别,服务应该将数据分解为可管理的部分(例如,100K,具体取决于网络速度,稳定性,环境)。块的大小意味着错误的可能性与请求每个块的开销之间的平衡。如果错误的可能性很高,那么块应该更小。

这也解决了在内存中缓冲大量数据的问题,但是对强大的错误处理机制的需求同样重要。因此,该服务应该有一个方法来发起请求,该方法将响应客户端,提供有关数据流总大小和块数的信息,以及另一个请求特定数据块的信息。

客户端可以选择指定块大小,或者协议可以设计为响应错误条件自动调整块大小。也就是说,如果经常发生错误,通常应该减少块大小。

无论哪种方式,一旦启动请求,客户端会调用另一个按顺序请求特定块的方法,并且当每个方法成功接收时,它会将它们附加到文件的末尾。如果发生故障,客户端可以仅重新请求特定块。

最后,以XML格式发送大量数据可能效率非常低,除非与标记相比存在大量数据。也就是说,如果数据结构与每个元素所包含的信息量(例如,大量简单的数字数据)相比具有许多元素(字段,记录),那么建立数据格式的合同将更有意义。什么时候最初请求。另一方面,如果每个字段都包含大量数据(例如文本),那么它并不重要。

如果数据格式始终相同(这是典型的),那么客户端可以设计为期望。如果没有,服务器可以通过为它要传输的数据提供结构来开始交换,然后在建立的结构中传输数据,而不会产生标记标记的开销。

对于一个非常有效的结构化数据编码器,请查看protocol buffers.基本点(无论是使用协议缓冲区,还是只使用自己的标准格式布局数据),标记标记可以添加很多内容如果客户端和服务器签订了正在发送的数据格式的合同,并且您应该将数据分解为客户专门请求的可管理部分,那么它们就完全没有必要了。