Python (Twisted) - 从fifo读取并将数据发送到多个协议

4 投票
2 回答
1831 浏览
提问于 2025-04-15 20:36

我正在尝试写一个可以同时支持多种协议的机器人(比如jabber和irc),这个机器人会从一个fifo文件中读取消息(大多数是单行消息),然后把这些消息发送到irc频道和jabber联系人。目前,我已经成功创建了两个连接到jabber和irc的工厂,它们似乎都能正常工作。

不过,我在读取fifo文件时遇到了问题——我不知道怎么在一个循环中读取它(打开文件、读取一行、关闭文件,然后再打开文件,反复这样),这样才能获取我需要发送的数据,然后把这些数据放到反应器循环中去发送到这两种协议。我一直在寻找最佳的方法来做到这一点,但我完全迷失了方向。任何建议或帮助都将非常感谢。

提前谢谢大家!

2 个回答

1

问题出在fifo上。建议你改为从socket读取数据。这样会更适合Twisted的事件驱动模型。试图在反应器控制之外做事情,通常不是正确的做法。

---- 根据反馈更新,fifo是一个外部限制,无法避免 ----

好的,核心问题是你不能在Twisted应用的主线程中写代码去执行阻塞的fifo读取操作。如果没有数据可读,这样会导致整个应用卡住。所以你要么考虑异步读取fifo,要么创建一个单独的线程来读取它,或者把应用拆分成两个部分。

最后一个选项是最简单的——修改Twisted应用,让它监听一个socket,然后写一个单独的小“转发器”应用,简单循环地读取fifo,把它听到的所有内容写入socket。

3

你可以像使用套接字一样,在文件描述符上进行读写,而不会阻塞反应器。顺便说一下,套接字不也是用文件描述符吗?

在你的情况下,可以创建一个类,来实现 twisted.internet.interfaces.IReadDescriptor 接口,然后通过 twisted.internet.interfaces.IReactorFDSet.addReader 方法将其添加到反应器中。想要了解 IReadDescriptor 的实现,可以参考 twisted.internet.tcp.Connection

我不能给出更具体的建议,因为我自己也没有这样做过,但我希望这能成为一个起点。

撰写回答