gpt4 book ai didi

python - 使用 Twisted 的 twisted.web 类,我如何刷新传出缓冲区?

转载 作者:太空狗 更新时间:2023-10-29 20:19:25 27 4
gpt4 key购买 nike

我使用 Twisted 制作了一个简单的 http 服务器,它发送 Content-Type: multipart/x-mixed-replace header 。我正在使用它来测试我想设置为接受长期流的 http 客户端。

出现的问题是我的客户端请求挂起,直到 http.Request 调用 self.finish(),然后它立即接收所有多部分文档。

有没有办法手动将输出缓冲区刷新到客户端?我假设这就是我没有收到单独的多部分文档的原因。

#!/usr/bin/env python

import time

from twisted.web import http
from twisted.internet import protocol

class StreamHandler(http.Request):
BOUNDARY = 'BOUNDARY'

def writeBoundary(self):
self.write("--%s\n" % (self.BOUNDARY))

def writeStop(self):
self.write("--%s--\n" % (self.BOUNDARY))

def process(self):
self.setHeader('Connection', 'Keep-Alive')
self.setHeader('Content-Type', "multipart/x-mixed-replace;boundary=%s" % (self.BOUNDARY))

self.writeBoundary()

self.write("Content-Type: text/html\n")
s = "<html>foo</html>\n"
self.write("Content-Length: %s\n\n" % (len(s)))
self.write(s)
self.writeBoundary()
time.sleep(2)

self.write("Content-Type: text/html\n")
s = "<html>bar</html>\n"
self.write("Content-Length: %s\n\n" % (len(s)))
self.write(s)
self.writeBoundary()
time.sleep(2)

self.write("Content-Type: text/html\n")
s = "<html>baz</html>\n"
self.write("Content-Length: %s\n\n" % (len(s)))
self.write(s)

self.writeStop()

self.finish()

class StreamProtocol(http.HTTPChannel):
requestFactory = StreamHandler

class StreamFactory(http.HTTPFactory):
protocol = StreamProtocol


if __name__ == '__main__':
from twisted.internet import reactor
reactor.listenTCP(8800, StreamFactory())
reactor.run()

最佳答案

使用 time.sleep() 阻止 twisted 完成它的工作。要使其正常工作,您不能使用 time.sleep(),您必须将控制权返回给 twisted。修改现有代码的最简单方法是使用 twisted.internet.defer.inlineCallbacks ,这是继切片面包之后最好的东西:

#!/usr/bin/env python

import time

from twisted.web import http
from twisted.internet import protocol
from twisted.internet import reactor
from twisted.internet import defer

def wait(seconds, result=None):
"""Returns a deferred that will be fired later"""
d = defer.Deferred()
reactor.callLater(seconds, d.callback, result)
return d

class StreamHandler(http.Request):
BOUNDARY = 'BOUNDARY'

def writeBoundary(self):
self.write("--%s\n" % (self.BOUNDARY))

def writeStop(self):
self.write("--%s--\n" % (self.BOUNDARY))

@defer.inlineCallbacks
def process(self):
self.setHeader('Connection', 'Keep-Alive')
self.setHeader('Content-Type', "multipart/x-mixed-replace;boundary=%s" % (self.BOUNDARY))

self.writeBoundary()

self.write("Content-Type: text/html\n")
s = "<html>foo</html>\n"
self.write("Content-Length: %s\n\n" % (len(s)))
self.write(s)
self.writeBoundary()


yield wait(2)

self.write("Content-Type: text/html\n")
s = "<html>bar</html>\n"
self.write("Content-Length: %s\n\n" % (len(s)))
self.write(s)
self.writeBoundary()

yield wait(2)

self.write("Content-Type: text/html\n")
s = "<html>baz</html>\n"
self.write("Content-Length: %s\n\n" % (len(s)))
self.write(s)

self.writeStop()

self.finish()


class StreamProtocol(http.HTTPChannel):
requestFactory = StreamHandler

class StreamFactory(http.HTTPFactory):
protocol = StreamProtocol


if __name__ == '__main__':
reactor.listenTCP(8800, StreamFactory())
reactor.run()

这在 firefox 中有效,我想它正确地回答了你的问题。

关于python - 使用 Twisted 的 twisted.web 类,我如何刷新传出缓冲区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/776631/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com