1

我使用 comet 和 tomcat 6 将数据推送到客户端。

我想在连接关闭之前接收数据(XMLHttpRequest的就绪状态= 3),问题是tomcat 6在发送数据之前会缓冲数据,所以我需要做一些棘手的事情来实现这一点。

我已将请求内容类型设置为 application/x-javascript 并将 req 内容类型设置为 application/xml (以禁用浏览器缓存)。

我在 tomcat 6 中使用了许多可用选项来禁用缓存(nio 连接器中的 socketBuffer = -1 等....),这适用于我的本地 tomcat 6(在 Windows 操作系统上)(实际上,即使没有修改任何默认选项)。

但是,与 tomcat 6 相同配置的事件,当我在http://jelastic.com提供的 tomcat 6 服务器上部署应用程序时,服务器输出缓冲区很大,我必须发送空字节以触发输出写入器刷新(参见以下代码)

byte[] bytes = new byte[event.getHttpServletResponse().getBufferSize()-new Gson().toJson(messagesContent).getBytes().length]; event.getHttpServletResponse().getOutputStream().write(new Gson().toJson(messagesContent).getBytes()); event.getHttpServletResponse().getOutputStream().write(bytes); event.getHttpServletResponse().getOutputStream().flush();

如果除了数据内容之外我不写入字节,则数据不会发送到客户端。这真的很烦人,因为我发送了无用的空字节,并且因为我必须在客户端上管理这些空字节。可怕。

有没有人有办法解决吗 ?如何禁用 comet servlet 输出缓冲区。对我来说似乎很明显,默认情况下应该为彗星 servlet 禁用输出缓冲区。听起来怪怪的。

预先感谢,

Ĵ

4

1 回答 1

3

您是否尝试过使用过滤器? http://www.oracle.com/technetwork/java/filters-137243.html中的自定义请求和响应编程

使用装饰器模式,您可以控制输出。执行此操作的方法是将生成响应的 servlet 传递给替代流。替代流防止 servlet 在完成时关闭原始响应流。

class CharResponseWrapper extends HttpServletResponseWrapper {
    private CharArrayWriter output;
    public String toString() {
      return output.toString();
    }
    public ResponseWrapper(HttpServletResponse response) {
        super(response); 
        output = new CharArrayWriter();
    }
    public PrintWriter getWriter(){
        return new PrintWriter(output);
    }

}

所以在过滤器的doFilter方法中你得到原始的PrintWritter,通过包装器

PrintWriter out = response.getWriter();
CharResponseWrapper wrapper = new CharResponseWrapper((HttpServletResponse)response);
chain.doFilter(request, wrapper);

然后 Servlet 会将所有输出写入 CharrArrayWritter 中,这样您就可以在字符串中获取输出而无需缓冲

wrapper.toString()

然后您可以修改、追加..等,然后使用原始响应输出来编写内容。

out.write(wrapper.toString());
out.close();
于 2012-11-09T13:44:55.573 回答