在mod_wsgi中,我通过运行函数start_response()发送头文件,但所有页面内容都通过yield / return传递。有没有办法以与start_response()类似的方式传递页面内容?在处理分块数据时,使用return.yield语句是非常严格的。
E.g。
def Application():
b = buffer()
[... page code ...]
while True:
out = b.flush()
if out:
yield out
class buffer:
def __init__(self):
b = ['']
l = 0
def add(self, s):
s = str(s)
l += len(s)
b.append(s)
def flush(self):
if self.l > 1000:
out = ''.join(b)
self.__init__()
return out
我希望缓冲区在页面加载时输出内容,但只有在内容堆积起来时才输出内容(例如1000字节)。
答案 0 :(得分:2)
没有;但我不认为这是限制性的。也许您想要在描述限制的地方粘贴示例代码,我们可以提供帮助。
要处理块数据,只需yield
块:
def application(environ, start_response):
start_response('200 OK', [('Content-type', 'text/plain')]
yield 'Chunk 1\n'
yield 'Chunk 2\n'
yield 'Chunk 3\n'
for chunk in chunk_data_generator():
yield chunk
def chunk_data_generator()
yield 'Chunk 4\n'
yield 'Chunk 5\n'
编辑:根据您提供的评论,在向前发送之前将数据堆积到一定长度的示例:
BUFFER_SIZE = 10 # 10 bytes for testing. Use something bigger
def application(environ, start_response):
start_response('200 OK', [('Content-type', 'text/plain')]
buffer = []
size = 0
for chunk in chunk_generator():
buffer.append(chunk)
size += len(chunk)
if size > BUFFER_SIZE:
for buf in buffer:
yield buf
buffer = []
size = 0
def chunk_data_generator()
yield 'Chunk 1\n'
yield 'Chunk 2\n'
yield 'Chunk 3\n'
yield 'Chunk 4\n'
yield 'Chunk 5\n'
答案 1 :(得分:1)
您的应用程序可能将数据“推送”到WSGI服务器:
一些现有的应用程序框架API以不同于WSGI的方式支持无缓冲输出。具体来说,它们提供了一种“写”功能或某种方法来编写一个无缓冲的数据块,或者它们提供了一个缓冲的“写”功能和一个“刷新”机制来刷新缓冲区。
不幸的是,除非使用线程或其他特殊机制,否则无法根据WSGI的“可迭代”应用程序返回值实现此类API。
因此,为了允许这些框架继续使用命令式API,WSGI包含一个特殊的
write()
可调用,由start_response
可调用返回。新的WSGI应用程序和框架不应该使用
write()
可调用的,如果可以避免这样做的话。
但不建议这样做。
一般来说,应用程序将通过缓冲其(适度大小)输出并立即发送所有内容来实现最佳吞吐量。这是现有框架(如Zope)中的常见方法:输出缓存在StringIO或类似对象中,然后一起传输,并与响应头一起传输。
WSGI中的相应方法是让应用程序简单地将包含响应主体的单元素可迭代(例如列表)作为单个字符串返回。这是绝大多数应用程序函数的推荐方法,它可以呈现其文本很容易适合内存的HTML页面。
http://www.python.org/dev/peps/pep-0333/#buffering-and-streaming
答案 2 :(得分:1)
如果您不希望在发送之前更改WSGI应用程序本身以部分缓冲响应数据,那么实现一个WSGI中间件,它包装您的WSGI应用程序并执行该任务。