gpt4 book ai didi

java - 在 Jersey 2 中流式传输?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:10:22 24 4
gpt4 key购买 nike

我一直在尝试让 json 流在 jersey 2 中工作。在我的生活中,在流完成之前没有流。

我试过这个例子来模拟一个缓慢的数据生产者。

@Path("/foo")
@GET
public void getAsyncStream(@Suspended AsyncResponse response) {
StreamingOutput streamingOutput = output -> {

JsonGenerator jg = new ObjectMapper().getFactory().createGenerator(output, JsonEncoding.UTF8);
jg.writeStartArray();

for (int i = 0; i < 100; i++) {
jg.writeObject(i);

try {
Thread.sleep(100);
}
catch (InterruptedException e) {
logger.error(e, "Error");
}
}

jg.writeEndArray();

jg.flush();
jg.close();

};

response.resume(Response.ok(streamingOutput).build());
}

然而 Jersey 只是坐在那里,直到 json 生成器完成返回结果。我在 charles proxy 中观察结果。

我需要启用某些功能吗?不知道为什么这不会流出


编辑:

这可能真的有效,只是不是我预期的那样。我不认为流正在实时写入东西,这正是我想要的,它更多的是不必缓冲响应并立即将它们写出给客户端。如果我运行一百万个循环并且没有线程 hibernate ,那么数据确实会分块写出,而不必在内存中缓冲。

最佳答案

您的编辑是正确的。它按预期工作。 StreamingOutput 只是一个包装器,让我们直接写入响应流,但实际上并不意味着响应在每个服务器端流式传输到流。 还有 AsyncResponse 就客户端而言,不提供任何不同的响应。它只是为了帮助提高长时间运行任务的吞吐量。长时间运行的任务实际上应该在另一个线程中完成,因此该方法可以返回。

您似乎正在寻找的是 Chunked Output

Jersey offers a facility for sending response to the client in multiple more-or-less independent chunks using a chunked output. Each response chunk usually takes some (longer) time to prepare before sending it to the client. The most important fact about response chunks is that you want to send them to the client immediately as they become available without waiting for the remaining chunks to become available too.

不确定它如何适用于您的特定用例,因为 JsonGenerator 需要一个 OutputStream(其中我们使用的 ChuckedOutput 是不是),但这里有一个更简单的例子

@Path("async")
public class AsyncResource {

@GET
public ChunkedOutput<String> getChunkedStream() throws Exception {
final ChunkedOutput<String> output = new ChunkedOutput<>(String.class);

new Thread(() -> {
try {
String chunk = "Message";

for (int i = 0; i < 10; i++) {
output.write(chunk + "#" + i);
Thread.sleep(1000);
}
} catch (Exception e) {
} finally {
try {
output.close();
} catch (IOException ex) {
Logger.getLogger(AsyncResource.class.getName())
.log(Level.SEVERE, null, ex);
}
}
}).start();
return output;
}
}

注意:一开始我遇到了问题。我只会得到延迟的完整结果。问题似乎出在与程序完全不同的地方。实际上是我的 AVG 导致了问题。一些名为“LinkScanner”的功能阻止了这个分块过程的发生。我禁用了该功能,它开始工作了。

我没有深入研究分块,也不确定安全隐患,所以我不确定为什么 AVG 应用程序会出现问题。

enter image description here


编辑

似乎真正的问题是由于 Jersey 缓冲响应以计算 Content-Length header 。可以看到this post了解如何改变这种行为

关于java - 在 Jersey 2 中流式传输?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29785051/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com