在一个应用中通过线程或其他方式实现多个反应堆(主循环)

19 投票
2 回答
9126 浏览
提问于 2025-04-16 06:28

我有个想法,想做一个应用程序,借此机会多了解一下TwistedWebSockets。我打算把之前写的IRC机器人整合到一个网页应用里。根据我的理解,我需要三个“反应器”来让它正常工作:

  • 主反应器:网页服务器(HTTP)。这就是普通的twisted.web应用。当你访问这个应用时,可以发送一个IRC服务器/频道的连接请求。网页服务器会和另一个在不同线程里的反应器进行沟通,这个反应器是...
  • 次反应器:IRC机器人。这是一个通过Twisted IRC客户端协议运行的IRC机器人。它会加入一个频道,每当有人说话时,它会把这些信息拿去发送给另一个反应器,这个反应器又在另一个线程里,具体是...
  • 第三反应器:WebSocket服务器(WS):因为WebSockets不使用普通的HTTP协议,所以需要自己的服务器(从一些例子来看,比如这个)。当IRC机器人收到消息时,它会告诉WebSocket服务器把这个消息推送给连接的客户端。

在我看来,这个想法是合理的,似乎是可行的。有没有人能提供一些在不同线程中运行多个反应器的例子,或者这是我想象的,实际上在当前的Twisted版本中无法实现的呢?

有没有什么架构上的改动可以(或者应该)做,以减少反应器的数量等等?

谢谢大家的帮助。

2 个回答

5

不,我觉得你不需要多个反应器。

你需要的是一个多服务、多协议的应用程序。这正是Twisted的强项所在。

所以你的应用程序应该启动一个网页服务、一个IRC机器人服务和一个WebSocket服务器。

使用Twisted的应用服务框架,特别是启动多服务。

可以看看IRC机器人的实现和Twisted对IRC协议的支持:

还有关于WebSocket和Twisted的内容:

20

很幸运,这里有个简单的方法可以把反应器的数量减少到1个:

在任何一个Twisted进程中,你只能有一个反应器,并且只能在一个线程里运行。如果你试图使用多个反应器,那就会出问题,什么都无法正常工作。

反应器的主要作用其实是把多个事件源结合到一个线程里。如果你想同时监听3个不同的端口,并且使用3种不同的协议,你的应用程序可能会像这样:

from twisted.internet import reactor
reactor.listenTCP(4321, FirstProtocolFactory())
reactor.listenTCP(5432, SecondProtocolFactory())
reactor.listenTCP(6543, ThirdProtocolFactory())
reactor.run()

当然,你可能并不是直接调用listenTCP,因为如果你使用twistd,你可能更想使用来自twisted.application.internetService对象,无论是通过.tac文件还是twistd插件。而且如果twistd为你处理了,你也不需要自己调用reactor.run()。我的意思是,无论你用什么方式,你都要把所有你希望反应器处理的事件加载进去——比如监听的服务器、客户端连接、定时事件——然后它会在每个事件发生时做出反应。(这就是“反应器”的意思。)

关于FirstProtocolFactorySecondProtocolFactoryThirdProtocolFactory具体应该是什么值,可以查看pyfunc的回答中的链接。

撰写回答