我想从一个IHttpHandler
类中流式传输数据。我正在从数据库中加载大量行,对其进行序列化和压缩,然后将它们发送到网络中。另一方面,我希望我的客户端能够在服务器完成对所有对象的序列化之前解压缩和反序列化数据。
我context.Response.OutputSteam.Write
用来写我的数据,但看起来输出数据在发送到客户端之前仍然被放入缓冲区。有没有办法避免这种缓冲?
我想从一个IHttpHandler
类中流式传输数据。我正在从数据库中加载大量行,对其进行序列化和压缩,然后将它们发送到网络中。另一方面,我希望我的客户端能够在服务器完成对所有对象的序列化之前解压缩和反序列化数据。
我context.Response.OutputSteam.Write
用来写我的数据,但看起来输出数据在发送到客户端之前仍然被放入缓冲区。有没有办法避免这种缓冲?
该Response.Flush
方法应将其发送到网络;但是,也有一些例外。如果 IIS 使用动态压缩,即它被配置为压缩动态内容,那么 IIS 将不会刷新流。然后是整个“分块”传输编码。如果您没有指定Content-Length
,则接收端不知道响应正文有多大。这是通过分块传输编码完成的。一些 HTTP 服务器要求客户端使用Accept-Encoding
包含 chunked 关键字的请求标头。当您在指定完整长度之前开始写入字节时,其他人只是默认为分块;Transfer-Encoding
但是,如果您指定了自己的响应标头,它们不会这样做。
在 IIS 7 和压缩被禁用的情况下,Response.Flush
应该总是能做到这一点,对吧?并不真地。IIS 7 可以有许多模块来拦截请求和响应并与之交互。我不知道默认情况下是否已安装/启用,但您仍然应该知道它们会影响您想要的结果。
...我正在从数据库中加载大量行,对其进行序列化和压缩,然后将它们发送到网络中...
好奇您正在压缩此内容。如果您使用的是 GZIP,那么您将无法通过调用 flush 来控制发送数据的时间和数量。此外,使用 GZIP 内容意味着接收端也可能无法立即开始读取数据。
您可能希望将记录分成 10 行、50 行或 100 行的更小、易于消化的块。压缩并发送它,然后处理下一组行。当然,现在您需要向客户端写一些东西,以便他们知道每个压缩的行集有多大,以及它们何时到达末尾。有关分块传输如何工作的示例,请参见http://en.wikipedia.org/wiki/Chunked_transfer_encoding 。
您可以使用context.Response.Flush()
或context.Response.OutputSteam.Flush()
强制立即写入缓冲内容。