作为AsyncHTTPClient接收块的Tornado流HTTP响应

我正在尝试编写一个Tornado请求处理程序,它使得异步HTTP请求成为可能,并且在它从异步请求中接收数据时将数据返回给客户端。 不幸的是,我无法让Tornado将任何数据返回给客户端,直到它的所有异步HTTP请求都完成为止。

下面是我的请求处理程序的演示。

class StreamingHandler(web.RequestHandler):

    all_requested = False
    requests = []

    @web.asynchronous
    def get(self):

        http_client = httpclient.AsyncHTTPClient()
        self.write('some opening')

        big_request = httpclient.HTTPRequest(url='[some_big_request]', streaming_callback=self.on_chunk)
        small_request = httpclient.HTTPRequest(url='[some_small_request]', streaming_callback=self.on_chunk)

        self.requests.append(http_client.fetch(big_request, callback=self.on_response_complete))
        self.requests.append(http_client.fetch(small_request, callback=self.on_response_complete))

        self.all_requested = True

    def on_chunk(self, chunk):
        self.write('some chunk')
        self.flush()

    def on_response_complete(self, response):
        if self.all_requested and all(request.done() for request in self.requests):
            self.write('some closing')
            self.finish()

我期望一个GET请求到这个处理程序最初返回文本“一些开放”,然后很快返回“一些块”的小请求,并稍后返回“一些块”(可能多次)为更大的请求,之前最后返回'一些关闭',并关闭连接。 相反,在建立连接之后,客户端会等待几秒钟完成所有请求,然后在关闭之前立即接收所有HTTPResponse。

我将如何去从Tornado获得我想要的行为?

提前致谢!


gen.coroutine装饰你的方法并产生期货清单。 这里有一个简单的例子:

from tornado import gen, web, httpclient

class StreamingHandler(web.RequestHandler):
    @web.asynchronous
    @gen.coroutine
    def get(self):
        client = httpclient.AsyncHTTPClient()

        self.write('some opening')
        self.flush()

        requests = [
            httpclient.HTTPRequest(
                url='http://httpbin.org/delay/' + str(delay),
                streaming_callback=self.on_chunk
            ) for delay in [5, 4, 3, 2, 1]
        ]

        # `map()` doesn't return a list in Python 3
        yield list(map(client.fetch, requests))

        self.write('some closing')
        self.finish()

    def on_chunk(self, chunk):
        self.write('some chunk')
        self.flush()

请注意,即使请求被“倒退”,第一个块仍然会在约一秒后被接收。 如果你同步发送它们,它会花费你15秒。 当你异步地请求它时,它只需要5个。

链接地址: http://www.djcxy.com/p/27849.html

上一篇: Tornado streaming HTTP response as AsyncHTTPClient receives chunks

下一篇: Running blocking code in Tornado