Streaming

简介

如果dealer是生成器,且所有的拦截器的返回值都是生成器,就能实现流式返回(Streaming)。

示例

import time
from lessweb import Application, Context, interceptor
from wsgiref.simple_server import make_server

def wrap_map(ctx:Context):
    def mapper(x):
        yield '['
        yield from x
        yield ']'
    return mapper(ctx())

def upper_map(ctx:Context):
    return (c.upper() for c in ctx())

@interceptor(wrap_map)
@interceptor(upper_map)
def stream(ctx:Context, n:int):
    for i in range(n):
        yield chr(ord('a') + i)
        time.sleep(1)

app = Application()
app.add_get_mapping('/stream/{n}', stream)
if __name__ == '__main__':
    make_server('', 8080, app.wsgifunc()).serve_forever()

在浏览器地址栏输入http://localhost:8080/stream/5,就能看到页面每秒都在更新内容。5秒钟后页面内容为[ABCDE]

限制

  1. 之所以不使用app.run()来启动服务,是因为目前aiohttp_wsgi支持流式返回还有问题,会等所有内容全部生成后才返回给页面,这就失去了流式返回的意义。
  2. 虽然在拦截器中ctx()的结果类型是生成器对象,但不能直接用yield使拦截器变成生成器,不然会使框架抛异常。

总之要慎用