简体   繁体   English

端到端响应式流RESTful服务

[英]End-to-End Reactive Streaming RESTful service

I have read this post and I don't know if it is a stupid question. 我已经阅读了这篇文章 ,但不知道这是否是一个愚蠢的问题。 I am completely newbie in reactive programming. 我是反应式编程的新手。

The question is very simple: supposing I have a fully-reactive back-end, how can I stream to browser (a large text, for instance), and print each chunk to the user as soon as they come from server? 问题很简单:假设我有一个完全可响应的后端,我该如何流式传输到浏览器(例如大文本),并在每个块来自服务器时立即将它们打印给用户?

Probably I am missing some important conceptual points, but all I need to know is: Can I send small parts of data (from server to browser), with one single HTTP GET (? or not) request? 可能我缺少一些重要的概念性要点,但是我需要知道的是:是否可以通过一个HTTP GET(或否)请求发送少量数据(从服务器到浏览器)? The key is: can I write those small parts, until the whole data is sent? 关键是:在发送全部数据之前,我可以写那些小的部分吗?

Thanks for any help. 谢谢你的帮助。 I really tried google before, but I always get information about other concepts (like websockets, long-polling, react.js), that I think it is not the case. 我以前确实尝试过google,但是我总是会得到其他概念的信息(例如websockets,long-polling,react.js),我认为并非如此。

EDIT: I'am not asking for a specific API ou library. 编辑:我不要求特定的API ou库。 I just want to understand the concept, for example: "You CANNOT do this with HTTP protocol, period!" 我只是想了解这个概念,例如:“您不能使用HTTP协议来做到这一点!” or "This has NOTHING to do with Reactive Programming, you are confused about what stream really means. See 'something_else.js' ". 或“这与反应式编程无关,您对流的真正含义感到困惑。请参阅'something_else.js'”。

EDIT2: I did a small rest controller using spring-mvc (spring-boot) with this method: EDIT2:我通过以下方法使用spring-mvc(spring-boot)做了一个小的rest控制器:

@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();
    }

}

In the browser, only the whole response arrived, even using the flushBuffer. 在浏览器中,即使使用flushBuffer,也只有整个响应到达。 After some research, that this could be a TOMCAT issue, I changed my pom.xml including undertow: 经过研究,这可能是TOMCAT问题,我更改了pom.xml并包括了underwow:

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

With default configurations: 使用默认配置:

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

At this moment, using debug in my IDE, each chunk was being written after the flushBuffer. 此时,在我的IDE中使用调试,每个块都在flushBuffer之后写入。

So, I believe this could be a TOMCAT configuration. 因此,我相信这可能是TOMCAT配置。 Long story short, I know there are a lot of things to help me on "streaming solutions", and thanks for all the comments, but my problem was a little bit more conceptual. 长话短说,我知道“流式解决方案”上有很多东西可以帮助我,感谢所有评论,但是我的问题有点概念性。

There is a protocol on top of HTTP which allows delivery of a server response in smaller, ready-to-be-consumed, chunks to the browser using HTTP transport. HTTP之上有一个协议,该协议允许使用HTTP传输将服务器响应以较小的,易于使用的块形式传递给浏览器。 It's called SSE (Server Sent Events) or EventSource , here is pretty thoroughly assembled article on the topic. 它称为SSE (服务器发送事件)或EventSource这里是有关该主题的相当完整的文章。

There are other means to stream data using the HTTP protocol. 还有其他使用HTTP协议流式传输数据的方法。 One such alternative is JSON streaming, in which you write partial responses on the wire from the server and consume the JSON chunks when they arrive. 一种这样的替代方法是JSON流传输,您可以在其中从服务器在线路上写入部分响应,并在到达JSON块时使用它们。 On the consuming side a popular library is called Oboe.js , on the server side you basically need to write the partial data on the response wire when you want to sent it, or when it's available. 在消费方面,一个流行的库称为Oboe.js ,在服务器端,您基本上需要在要发送或可用时在响应线路上写入部分数据。

For both approaches Rx is useful for handling the streaming logic on the server side. 对于这两种方法,Rx对于处理服务器端的流逻辑都是有用的。 You model the pieces as a stream (handle errors, etc.) and eventually, in the Subscriber, you write the single emissions on the wire, closing the response when the Observable is finished. 您将片段建模为流(处理错误等),最终在订户中将单个发射写在导线上,在Observable完成时关闭响应。

On the client side, the EventSource events can be wrapped in a new Observable (via Rx.Observable.create() ) and processed further as a stream. 在客户端,可以将EventSource事件包装在新的Observable中(通过Rx.Observable.create() ),并作为流进一步处理。 Also Oboe.js events can be converted into Observables (via Rx.Observable.fromEvent() . Oboe.js事件也可以转换为Observables(通过Rx.Observable.fromEvent()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM