尽管调用了flush(),Servlet 仍缓冲响应

2024-01-11

我们有一个系统,客户端发出 HTTP GET 请求,系统在后端进行一些处理,压缩结果,然后将其发送给客户端。由于处理可能需要一些时间,因此我们将其作为ZipOutputStream包裹着response.getOutputStream().

然而,当我们的第一个数据量非常少时ZipEntry,并且第二次进入时间较长,客户端使用的浏览器超时。我们尝试刷新流缓冲区,但在至少 1000 字节写入流之前,似乎没有响应发送到浏览器。奇怪的是,一旦发送了前 1000 个字节,后续的刷新似乎就可以正常工作。

我尝试将代码简化为简单的示例:

protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    try {
        ZipOutputStream _zos = new ZipOutputStream( response.getOutputStream());
        ZipEntry _ze = null;
        long startTime = System.currentTimeMillis();
        long _lByteCount = 0;

        response.setContentType("application/zip");

        while (_lByteCount < 2000) {
            _ze = new ZipEntry("foo");
            _zos.putNextEntry( _ze );

            //writes 100 bytes and then waits 10 seconds
            _lByteCount += StreamWriter.write( 
                    new ByteArrayInputStream(DataGenerator.getOutput().toByteArray()),
                    _zos );
            System.out.println("Zip: " + _lByteCount + " Time: " + ((System.currentTimeMillis() - startTime) / 1000));

            //trying to flush
            _zos.finish();
            _zos.flush();
            response.flushBuffer();
            response.getOutputStream().flush();
        }
    } catch (Throwable e) {
        e.printStackTrace();
    }
}

为了方便重现,我将浏览器超时设置为 20 秒左右。尽管多次写入 100 字节,但没有任何内容发送到浏览器,并且浏览器超时。如果我延长浏览器超时时间,则在写入 1000 个字节之前不会发送任何内容,然后浏览器会弹出“您要保存...”对话框。同样,在最初的 1000 字节之后,每添加 100 字节都可以正常发送,而不是缓冲到 1000 字节块。

如果我将 while 条件中的最大字节数设置为 200 左右,则它工作正常,仅发送 200 个字节。

我可以做什么来强制 servlet 发回非常少量的初始数据?


事实证明,为了提高效率而缓冲流中的数据的底层 Apache/Windows IP 堆栈存在限制。因为大多数人都会遇到这样的问题too much数据,而不是问题太少了数据,大多数时候这是正确的。我们最终要做的是要求用户请求足够的数据,以便在超时之前达到 1000 字节的限制。抱歉花了这么长时间才回答这个问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尽管调用了flush(),Servlet 仍缓冲响应 的相关文章

随机推荐

  • DTLS 和 TLS 之间的区别

    TLS 和 DTLS 之间的功能区别是什么 使用 TLS 与 DTLS 时应用程序流程 协商有何不同 基本上 DTLS 是在数据报 UDP DCCP 等 上构建 TLS DTLS 有意与 TLS 类似 只不过 DTLS 必须解决两个问题 数
  • (异步)NSURLConnection:下面发生了什么?

    我知道它必须处理启动线程来发出网络请求的丑陋 然后可能调用performSelectorOnMainThread 用我的委托方法 我知道怎么做use在进行 iOS 编程时 它效果很好 但是 我想知道如何使其在 例如 命令行实用程序的上下文中
  • 在keycloak登录页面显示应用程序名称

    我有两个应用程序App1 and App2与相互作用keycloak用于用户身份验证 我想在以下位置显示应用程序名称keycloak登录页面 例如 如果用户正在登录App1 the keycloak登录页面应显示 登录到 App1 同样的情
  • 如何在 Travis 中显示 HTML 格式的输出文件?

    我正在尝试使用 Travis CI 在 Bintray 上部署 Android 库 但是当我上传我的仓库时 我得到了这个 Ran lint 变体发布 发现 6 个问题 Ran lint on variant debug 6 issues f
  • 存储轮播图像的最佳方式是什么?

    我正在使用 Ruby on Rails 我的目标网页上有两个轮播 我想知道存储和显示这些图像的最佳方式是什么 选项一 将图像放入assets images并在轮播中显示它们 如果这是一种好方法 我可以循环浏览文件夹中的图像还是必须指定每个文
  • 我可以在 WinRT 应用程序中使用 Sqlite (javascript) 吗?

    是否可以在 Windows 8 winRT javascript 应用程序中使用 Sqlite 数据库 我想要实现的是下载一个 Sqlite 数据库并在使用前将其存储在本地存储中 我相信某种形式的本地存储可用于基于 javascript 的
  • 从头开始创建 geom / stat

    我不久前刚刚开始使用 R 目前正在努力加强我的可视化技能 我想做的是创建箱线图平均钻石作为顶部的一层 参见下面链接中的图片 我还没有找到任何可以执行此操作的函数 所以我想我必须自己创建它 我希望做的是创建一个几何或统计数据 让这样的事情能够
  • Azure 服务总线重试策略不会改变行为

    我试图了解 Azure 服务总线上的重试策略 但它没有按我预期的方式工作 我有以下代码 它既侦听消息又将消息发送到特定的天蓝色队列 using System using Microsoft ServiceBus using Microsof
  • 如何更改 C# 中 UWP 应用中按钮的背景颜色?

    我有一个简单的 我需要每秒改变按钮的颜色 我用这个代码btnBlue Background new SolidColorBrush Windows UI Colors Blue 但它不包含我在 xaml 中使用的自定义颜色 例如 FF30B
  • 带参数“-S -save-temps”的 gcc 将中间文件放入当前目录中

    参数 S save temps工作正常 只要我不在同名文件上使用它们 考虑以下情况 我有一个项目 有一个主目录和一个名为subDir并且在这两个目录中都放置了名为file c 如果我现在打电话gcc S save temps file cp
  • 如何锁定 iPhone 某些视图控制器的方向 - Swift?

    我有 2 个视图控制器 VC1 和 VC2 VC1 目前以模态方式呈现 VC2 VC1 仅方向应为纵向 但 VC2 可以具有所有方向 问题是当我在 VC2 中并且我旋转到横向模式然后关闭时 VC1 也处于横向模式 这绝对不应该发生 NOTE
  • 单元测试实体框架验证

    我使用 IValidatableObject 为某些实体框架对象编写了一些自定义验证 并向对象添加了一些 DataAnnotations 以进行验证 我想测试验证是否满足所需的验证 确保自定义验证正常工作 并且所做的任何更改都保留这些数据注
  • Ansible:如何初始化 git bare 存储库并将其克隆到同一台机器?

    我想问一下 如何使用 Ansible 来实现这样的情况 我的主要目标是 nit git bare 存储库并将其克隆到同一台计算机 var www 我通常的步骤是 1 git init bare 在 git project name 中运行
  • 模板特化与别名模板推导区别

    我很难理解在以下情况下演绎是如何工作的 template
  • Laravel 通知 - 延迟电子邮件发送并在满足条件时取消

    我有一个应用程序 我在其中发送推送通知 如果用户登录到该应用程序 那就没问题 但是 如果他们没有登录 如果他们在 X 分钟内没有阅读通知 我想向他们发送一封电子邮件 我的方法是使用 Laravel 通知来创建邮件 广播和数据库通知 上toM
  • 构造函数可以中止实例化吗?

    我想在构造函数中进行测试 以确定当前使用给定参数实例化对象是否是一个好主意 但是我怎样才能中止构造函数并将警告返回到 new 语句呢 调用者必须在每个 新 语句之前完成此类测试吗 我认为构造函数将是一个好地方 您可以改用工厂对象 然后 这可
  • 设计可再确认的

    我想在我的用户模型中使用 devise 选项 reconfirmable 因此每当用户更改其电子邮件时 他需要通过电子邮件发送的链接进行确认 最大的问题是 电子邮件从未发送过 我的 devise 2 1 2 的设置是 用户模型 attr a
  • 错误:失败并出现错误:没有这样的项目:polymod

    我正在尝试制作一个 Friday Night Funkin mod 但是当我编译它时 出现以下错误 Error Could not find haxelib polymod does it need to be installed 所以我当
  • 允许在 Puppeteer 中的所有站点上运行 Flash

    免责声明 我知道 Flash 将在 2020 年底被放弃 但我就是无法放弃这种情况 需要在 Puppeteer 中使用 Flash 尽管我也不喜欢它 我需要抓取某些 Flash 网站并截取它们的屏幕截图 以供以后进行编程比较 我可以提供一个
  • 尽管调用了flush(),Servlet 仍缓冲响应

    我们有一个系统 客户端发出 HTTP GET 请求 系统在后端进行一些处理 压缩结果 然后将其发送给客户端 由于处理可能需要一些时间 因此我们将其作为ZipOutputStream包裹着response getOutputStream 然而