我正在尝试向Twisted添加一个新的传输,它将从流中读取数据 - 可以是tail -f
方式的文件,也可以是来自管道的文件,但是我对Twisted体系结构有一些问题。 / p>
我已准备好传输本身(实现ITransport
) - 它处理所有文件打开。我已准备好流媒体功能/延迟功能。我现在怎么把它放在一起?我想将新数据报告回某些协议的dataReceived()
。
我当然可以创建一个新对象,它将使用适当的回调设置I / O监视器,在reactor关闭时注册回调(关闭文件/协议)并手动启动所有内容 - 但是“正确的方法”?我可以使用更好的抽象吗?我见过reactor.connectWith()
,但它并没有真正提供很多抽象......
另外 - 我应该如何将读取数据传递给协议? ITransport没有为它定义任何接口,即使它看起来完全是传输的责任。
答案 0 :(得分:5)
听起来你大部分都知道如何做到这一点。您可能对twisted.internet.fdesc.readFromFD
感兴趣,但它只有几行而且它没有做任何特别复杂的事情(尽管如此,它不需要维护几行)。除此之外 - 是的,在这种情况下你必须进行I / O监控,因为select / poll / epoll不支持常规文件描述符(它们总是被报告为准备好,而不是你想要的)。
已经完成了在Twisted(http://twistedmatrix.com/trac/ticket/972)中支持inotify的一些工作,但这还没有完成,所以它现在不会直接对你有用(除非你想帮助完成它然后使用它)。假设您只使用基于时间的轮询,反应堆中的大部分内容都无法帮助您,因为该代码专注于使用系统提供的就绪API(即select / poll / epoll)来触发事件
对于管道案例,您应该能够使用IReactorFDSet
的方法并从中受益 - addReader
等。
您的基于时间的轮询传输可能仍然可以从实施ITransport
中受益 - 尽管我不确定如何为write
类似的传输实施tail -f
。通过IProtocol
接口传输数据肯定会使您受益,因为这样可以简化代码重用。 IProtocol.dataReceived
正是您想要从阅读器传递数据的方式(我认为这与您的传输相同,不是吗?)。这不是在ITransport
上定义的,因为它是您调用其他非传输对象的方法。
reactor.connectWith
可能不会给你买任何东西。正如你所说,它并不是一个抽象的东西;我会说这更像是一个错误。 :)
不要过分担心无法将方法直接添加到反应器中。接受反应堆作为参数的自由功能同样易于使用。
对于关机回调,addReader
实际上应该可以帮助你完成任务。关机时反应堆中的任何读卡器都会connectionLost
调用它(IFileDescriptor
的一部分)。您应该实现此操作来清理文件和协议。