【问题标题】:Streaming JSON to browser with GZIP使用 GZIP 将 JSON 流式传输到浏览器
【发布时间】:2012-01-10 16:02:47
【问题描述】:

我正在尝试将一些 JSON 流转换为通过我编写的 GZIPFilter。到目前为止,当我告诉它时,我已经能够将过滤器调整为刷新,它可能会输出兼容的 gzip 浏览器数据。 我将输出重定向到一个文件并运行 gzip -cd -v test.gz ,它产生了预期的输出,然后是“文件意外结束”。

问题是浏览器仍然看到零输出(萤火虫),所以我想知道浏览器是否解释了对 gzip 流的部分刷新。

流主要包含 javascript 指令/对象,应在客户端接收和解析。 servlet 被调用一次并在整个会话期间保持打开状态,为客户端提供数据;连接未关闭,因此流继续运行,提供来自服务器的一种推送数据。

我的设置: WinXP 32位, GWT 2.4.0, 码头7.4.., GzipFilter(带有调整), 火狐 8 / Chrome 10

据我所知,根据 RFC 规范,内容仅在流结束后才被解码,所以我尝试做的事情可能是不可能的。不过,您可能有一些建议可以在主流浏览器上使用。

稍后编辑:

  • 通过web.xml指定GzipFilter就可以了
  • 浏览器接收到 Content-Encoding: gzip
  • 字节正在写入 HTTPResponse 流
  • 在编译和实时 GWT 模式下测试
  • 使用字符集 iso-8859-1 测试或未指定
  • content-type 是 text/html
  • 没有通过 web.xml 应用的过滤器一切正常

【问题讨论】:

  • 编写自己的 gzip 过滤器而不是使用 jetty 的原因是什么?
  • 已修复。在允许我提交答案后,我会写下详细信息。我这样做是因为 GzipFilter 上的刷新在 outputStream 关​​闭之前不会注册,所以如果您尝试进行实时流式传输,这将不起作用。
  • 最好在问题中包含您的动机,可能其他人也有同样的问题。

标签: json http gwt jetty gzip


【解决方案1】:

修复它。我正在使用自定义中介 OutputStream 进行调试,它将输出写入文件以及一些统计信息,我想我留下了一些未覆盖的方法。一旦我删除它,它就可以工作了。

我的参数,对于那些足够好奇的人:

  • 缓冲区大小:8k
  • 最小 gzip 大小:64b
  • 要刷新 gzip 流,您需要扩展 GzipStream,重写 flush 方法以将压缩级别设置为零,然后再次返回,在两者之间放气。
  • 将 gzOut 流分配操作替换为指向此自定义 Gzip/Deflater 流的操作

正如我已经说过的,这样做的原因是将 JSON 对象实时流式传输到浏览器,而无需关闭套接字。直到所有浏览器都正确实现 WebSocket。要进行推送数据,您要么需要 WebSocket 实现,要么需要服务器可以通过其推送数据的始终打开的连接。

后期编辑:重新发明轮子后:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4255743

【讨论】:

    猜你喜欢
    • 2013-04-18
    • 2010-09-14
    • 2012-07-02
    • 2015-05-22
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    相关资源
    最近更新 更多