【问题标题】:Stream over HTTP SSL is not flushed未刷新 HTTP SSL 上的流
【发布时间】:2014-09-10 07:46:43
【问题描述】:

我有一个在 nginx 后面运行的 Web 应用程序。有些页面可以通过http访问,有些可以通过https访问。我有一些“页面”,它们是流,因为应用程序不会关闭连接并在数据到来时提供数据。提要如下所示:

 TIME1 MESSAGE1
 TIME2 MESSAGE2
 ...
 TIMEn MESSAGEn

在每一行之后我写“\n”然后调用flush()。通过 http,它可以正常工作,我的客户可以收听新数据。但是,通过 https 客户端在连接关闭之前不会接收任何数据。

 ServletOutputStream stream = applicationModel.getOutputStream();
 OutputStreamWriter streamWriter = new OutputStreamWriter(stream);
 BufferedWriter writer = new BufferedWriter(streamWriter);
 while (true) {
     wait();
     writer.write(newMessage);
     writer.flush();
 }

【问题讨论】:

  • flush() 仅刷新应用程序的输出缓冲区,但 nginx 本身也可以缓冲(其他服务器也这样做)。见stackoverflow.com/questions/20018803/…
  • 如果您将其发布为答案,我会接受。奇怪的是,只有 https 请求被缓冲。

标签: java ssl nginx stream


【解决方案1】:

除非应用程序与 Web 服务器紧密集成,否则写入器上的刷新只会刷新应用程序内部的缓冲区,以便将数据发送到 Web 服务器。在 web 服务器内部有更多的缓冲区,这是通过发送更大的 TCP 数据包来优化流量所必需的,从而减少数据的开销。而且,如果您使用 SSL,还有另一层需要观察,因为您的数据将被封装到 SSL 帧中,这又会增加开销,因此最好不要只在其中包含几个字节的有效负载。最后,您在 OS 内核中进行了缓冲,如果希望有更多数据,它可能会延迟发送一个小的 TCP 数据包。

请注意,您希望控制缓冲区违反了 HTTP 的基本设计理念。 HTTP 是基于这样的想法,即您从客户端向服务器发出请求,然后从服务器获得响应,理想情况下,预先知道内容长度。响应的原始设计不知道发展缓慢,一旦新数据到达,浏览器将在哪里更新显示。获取更新的真正方法是让客户端发送另一个请求,然后发回新的响应。另一种方法是使用 WebSockets。

【讨论】:

    猜你喜欢
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    • 2010-09-21
    • 2011-05-27
    • 2023-04-01
    相关资源
    最近更新 更多