我已阅读this post,我不知道这是不是一个愚蠢的问题。我是反应式编程的新手。
问题很简单:假设我有一个完全反应的后端,我如何流式传输到浏览器(例如一个大文本),并在它们来自服务器时立即将每个块打印给用户?
可能我缺少一些重要的概念点,但我需要知道的是:我可以发送一小部分数据(从服务器到浏览器),只需一个HTTP GET(?或不是)请求?关键是:我可以写出那些小部件,直到整个数据被发送?
感谢您的帮助。我之前真的尝试过谷歌,但我总是得到有关其他概念的信息(比如websockets,long-polling,react.js),我认为情况并非如此。
编辑:我不是要求特定的API ou库。我只是想理解这个概念,例如:“你不能用HTTP协议做这个,期间!”或者“这与反应式编程没有任何关系,你对这个流的真正含义感到困惑。请参阅'something_else.js'”。
EDIT2:我用这种方法使用spring-mvc(spring-boot)做了一个小型休息控制器:
@RequestMapping(value = "/flush", method = RequestMethod.GET)
public void flushTest(HttpServletResponse response) {
response.setContentType("text/html");
response.setStatus(SC_OK);
try (ServletOutputStream outputStream = response.getOutputStream()) {
for (int i = 0; i < 3; i++) {
String chunk = "chunk_" + i;
outputStream.print(chunk);
outputStream.flush();
response.flushBuffer();
}
} catch (IOException e) {
e.printStackTrace();
}
}
在浏览器中,即使使用flushBuffer,也只有整个响应到达。经过一些研究,这可能是一个TOMCAT问题,我改变了我的pom.xml,包括下载:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
使用默认配置:
server.undertow.accesslog.enabled=true
server.undertow.accesslog.dir=target/logs
server.undertow.accesslog.pattern=combined
server.compression.enabled=true
server.compression.min-response-size=1l
此时,在我的IDE中使用debug,每个块都在flushBuffer之后写入。
所以,我相信这可能是TOMCAT配置。长话短说,我知道有很多东西可以帮助我解决“流媒体解决方案”,并感谢所有的评论,但我的问题更具概念性。
答案 0 :(得分:2)
在HTTP之上有一个协议,它允许使用HTTP传输将较小的,准备好的消息块中的服务器响应传递给浏览器。它被称为 SSE (服务器发送事件)或 EventSource ,here是关于该主题的非常完整的文章。
还有其他方法可以使用HTTP协议传输数据。一种这样的替代方案是JSON流式传输,您可以在服务器上的线路上编写部分响应,并在它们到达时使用JSON块。在消费方面,一个流行的库称为Oboe.js,在服务器端,当您想要发送它时,或者当它可用时,您基本上需要在响应线上写入部分数据。
对于这两种方法,Rx对于处理服务器端的流逻辑非常有用。您将这些碎片建模为流(处理错误等),最终,在订购者中,您在线上编写单个发射,在Observable完成时关闭响应。
在客户端,EventSource事件可以包装在新的Observable中(通过Rx.Observable.create()
),并作为流进一步处理。此外,Oboe.js事件可以转换为Observables(通过Rx.Observable.fromEvent()
。