当前位置: 首页 > 面试题库 >

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

公良鸿风
2023-03-14
问题内容

我使用Twisted制作了一个简单的http服务器,该服务器发送Content-Type:multipart / x-mixed-
replace标头。我正在使用它来测试要设置为接受长期流的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()可以防止扭曲工作。要使其无法使用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中有效,我想它可以正确回答您的问题。



 类似资料:
  • 问题内容: 在log4j中,当使用具有BufferedIO = true和BufferSize = xxx属性(即启用了缓冲)的FileAppender时,我希望能够在正常关闭过程中刷新日志。有关如何执行此操作的任何想法? 问题答案:

  • 问题内容: 我正在优化一个大型查询,并希望在比较之前和之后从同一基准运行它。 我知道mysql查询缓存,但与我无关,因为无论如何都不会缓存2个查询。 正在缓冲的是缓冲池中的innodb页面。有没有一种方法可以清除整个缓冲池,以便可以从同一起点比较两个查询? 虽然在运行每个查询后重新启动mysql服务器无疑会工作,但我想尽可能避免这种情况 问题答案: 警告:以下内容仅适用于MySQL 5.5和MyS

  • 问题内容: 有人可以保存这两个文件并运行它们,然后告诉我为什么我得到错误“ ob_flush()[ref.outcontrol]:无法刷新缓冲区。没有要刷新的缓冲区”。我尝试了四处搜寻,并说必须使用ob_start();。但是,当我这样做时,它不会逐行打印出来,而是在完成后从FOR循环返回整个对象。我对PHP有点陌生,所以我不确定其他地方。 test_process.php main.html 问

  • 演示一个问题的简化示例是 如果有的话,有什么方法可以保证journald收到?

  • 本文向大家介绍刷新PHP缓冲区为你的站点加速,包括了刷新PHP缓冲区为你的站点加速的使用技巧和注意事项,需要的朋友参考一下 在当前 PHP 版本的默认配置下,“输出缓冲(Output Buffering)”是被打开的。旧版本则不是这样,在旧版本的 PHP 中,字符串在每次被输出的时候(通过 echo 或 print 函数),都会触发一次发送到客户端浏览器的动作。 “输出缓冲”的引入,使得这一过程更

  • 本文向大家介绍如何刷新浏览器的应用缓存?相关面试题,主要包含被问及如何刷新浏览器的应用缓存?时的应答技巧和注意事项,需要的朋友参考一下 按F5或浏览器刷新按钮 浏览器会在请求中附加必要的缓存协商,但不允许浏览器直接使用本地缓存,它能够让 Last-Modified、ETag发挥效果,但是对Expires无效。 按Ctrl+F5或按Ctrl并点击刷新按钮 这种方式就是强制刷新,总会发起一个全新的请求

  • 问题内容: 我有一个简单的User $ resource,它使用默认的$ http缓存实现,如下所示: 这非常好用,即我的服务器在应用程序中仅被调用一次,然后从缓存中获取值。 但是我需要在执行某些操作后从服务器刷新值。有没有简单的方法可以做到这一点? 谢谢。 问题答案: 保留布尔值并获取缓存: 然后,您可以像使用所提供的任何其他缓存一样控制它,这是下面提供的用法实例:

  • 问题内容: 我编写了一个简单的中继脚本,该脚本连接到网络摄像机并从套接字读取数据,并使用打印功能输出此数据。数据是已设置边界的MJPG数据。我只是输出读取的数据。 问题是PHP似乎正在缓冲这些数据。当我将相机设置为1 FPS时,Feed将冻结7-8秒,然后快速显示8帧。如果将分辨率设置为很大,则相机每秒将以大约1帧的速度移动。我认为那时正在发生一些缓冲(因为大尺寸的缓冲区会很快填充,而小尺寸的缓冲