作为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