2

我正在尝试向 Twisted 添加一个新的传输,它将从流中读取数据 - 以某种tail -f方式或从管道中读取数据,但我在 Twisted 架构方面存在一些问题。

我已经ITransport准备好传输本身(实现) - 它处理所有文件打开。我已经准备好流媒体功能/延迟。我现在怎么把它放在一起?我想将新数据报告回某些协议的dataReceived().

我当然可以创建一个新对象,该对象将使用适当的回调设置 I/O 监视器,在反应器关闭时注册回调(以关闭文件/协议)并手动启动一切 - 但这是“正确的方式” ? 有没有更好的抽象我可以使用?我见过reactor.connectWith(),但它并没有真正提供太多抽象......

另外 - 我应该如何将数据从我的阅读器传递到协议?ITransport 没有为它定义任何接口,尽管它看起来正是传输的职责。

4

1 回答 1

5

听起来您基本上已经弄清楚如何做到这一点。您可能对 感兴趣twisted.internet.fdesc.readFromFD,但它只有几行长,并且没有做任何特别复杂的事情(不过,您不必维护几行)。除此之外 - 是的,在这种情况下您必须进行 I/O 监控,因为 select/poll/epoll 不支持常规文件描述符(它们总是被报告为准备就绪,而不是您想要的)。

在 Twisted ( http://twistedmatrix.com/trac/ticket/972 )中支持 inotify 方面已经完成了一些工作,但这还没有完成,所以它现在不会对你直接有用(除非你想帮忙完成它然后使用它)。假设您只使用基于时间的轮询,那么反应器中的大部分内容不会对您有太大帮助,因为该代码专注于使用系统提供的就绪 API(即 select/poll/epoll)来触发事件.

但是,对于管道案例,您应该能够使用IReactorFDSet's 方法并从中受益 -addReader等。

您的基于时间的轮询传输可能仍然受益于实施ITransport- 尽管我不确定您将如何实施write类似tail -f传输。你肯定会从让你的传输通过IProtocol接口传递数据中受益,因为这简化了代码重用。 IProtocol.dataReceived正是您想要从您的阅读器传递数据的方式(我认为这与您的transport相同,不是吗?)。这没有定义,ITransport因为它是您在其他不是传输的对象上调用的方法。

reactor.connectWith可能不会给你买任何东西。正如您所说,这并不是什么抽象。我会说这更像是一个错误。:)

不要太担心不能直接向反应器添加方法。接受反应器作为参数的自由函数同样易于使用。

对于关闭回调,addReader实际上应该让您大部分时间到达那里。关闭时反应堆中的任何读者都会connectionLost调用它(部分IFileDescriptor)。您应该实现它以清理文件和协议。

于 2009-11-29T04:31:31.650 回答