刷新弹簧休息端点的InputStreamResource



我有一个显示流内容的应用程序。这个流是通过Spring Rest提供的。流的内容很少从另一个线程推送。

这已经工作了,但我唯一有问题的是"冲洗"这条小溪。目前我看到的内容只有当流关闭,但我想有一个实时显示的内容。

我通过chrome/firefox调用端点来测试这一点,并且(完整)内容仅在流关闭后出现(页面不再加载)。在我的应用程序中,内容只在最后显示,而不是在同时显示。

@GetMapping("/session")
public ResponseEntity<InputStreamResource> openSession(){
var inLog = new PipedInputStream();
var logWritable = new PipedOutputStream(inLog);
spawnThreadAndPushMessages(logWritable);
return ResponseEntity.ok()
.contentType(MediaType.TEXT_PLAIN)
.body(new InputStreamResource(inLog));
}

我像这样写PipedOutputStream (logWritable):

spawnThreadAndPushMessages(OutputStream logWritable){
//thread stuff etc omitted for clarity
logWritable.write("test".getBytes());
logWritable.flush();
}

这里出了什么问题?

所以我终于想通了:

.contentType(MediaType.TEXT_EVENT_STREAM)

我必须重新考虑我的架构。现在我在另一个线程中写入并发列表。我的端点现在看起来像这样:

@GetMapping("/session")
public ResponseEntity<StreamingResponseBody> openSession(){
var shutdown = new AtomicBoolean(false);
var tobeFlushed = new ConcurrentLinkedQueue<String>();
//thread management etc
createThreadAndWriteToList(tobeFlushed, shutdown);
return ResponseEntity.ok()
.contentType(MediaType.TEXT_EVENT_STREAM)
.body(outputStream -> {
while (!shutdown.get()) {
tobeFlushed.forEach(x -> {
try {
outputStream.write((x+"n").getBytes(StandardCharsets.UTF_8));
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
});
tobeFlushed.clear();
}
System.out.println("Finished request!! ------------------------");
});
}