我正在尝试使用Twisted框架编写一个简单的程序,我正在努力解决(甚至成像如何编写它)问题我找不到任何相关的文档:
主反应堆使用两个工厂,一个定制,在给定端口(例如,8000)上侦听TCP连接,第二个,以登录到给定的IRC服务器和通道。在工厂收听8000时接收数据(简单,一行文本)时,我需要将该数据传递给第二工厂,然后可以相应地处理它 - 将带有该文本的消息发送到通道,或者发送一条私有消息对某些人而言,现在并不重要。我找不到任何方法从第一个工厂获取数据并将其发送到另一个工厂进行处理(可能像第二个IRC工厂通常收到的连接一样?)。
如果这可以以某种方式解决,那么我想添加一个甚至更多的工厂(例如Jabber)将端口8000上的接收数据立即发送到所有这些工厂,以相应地传递给协议(IRC到一个频道,Jabber到一个联系人,等等。
是否有人遇到过类似的问题并且愿意给我一些建议甚至分享一些代码?任何帮助将受到高度赞赏!
提前致谢。
答案 0 :(得分:6)
工厂只是对象。要将数据从一个传递到另一个,您可以定义和调用方法并将数据作为参数或设置属性传递。我认为faq question会对您有所帮助:
如何在一个连接上输入 导致另一个输出?
这似乎是扭曲的 问题,但实际上它是一个Python 问题。每个
Protocol
对象 代表一个连接;您可以 叫它transport.write
写一些 数据到它。这些是常规的Python 对象;你可以将它们列入清单, 字典或其他任何数据 结构适合你 应用举个简单的例子,添加一个列表 你的工厂,以及你的协议
connectionMade
和connectionLost
,添加 它从该列表中删除它。 这是Python代码:from twisted.internet.protocol import Protocol, Factory from twisted.internet import reactor class MultiEcho(Protocol): def connectionMade(self): self.factory.echoers.append(self) def dataReceived(self, data): for echoer in self.factory.echoers: echoer.transport.write(data) def connectionLost(self, reason): self.factory.echoers.remove(self) class MultiEchoFactory(Factory): protocol = MultiEcho def __init__(self): self.echoers = [] reactor.listenTCP(4321, MultiEchoFactory()) reactor.run()
答案 1 :(得分:0)
我认为您上面的评论是沿着正确的方向 - 您需要为要发送数据的对象提供引用或“句柄”。
换句话说,如果要使用对象进行对象通信(即方法调用),则发送工厂对象必须具有接收工厂对象的引用。实现此目的的一种方法是在初始化时将接收工厂的名称传递给发送工厂。
从示例中并不总是很明显,但是工厂在初始化时可以将数据传递给它。例如,在上面的情况中,创建MultiEchoFactory的行可以修改为:
reactor.listenTCP(4321, MultiEchoFactory(someOtherObject))
并且MultiEchoFactory对象本身在其 init 方法中进行了修改:
class MultiEchoFactory(Factory):
protocol = MultiEcho
def __init__(self, otherObjectReference):
self.echoers = []
self.otherObject = otherObjectReference
现在您可以引用其他对象并在其上调用方法。
另一种方法可能是拥有一个完全独立的对象,所有工厂都在初始化时被赋予引用,当一个对象想要与另一个对象通话时,它可以作为对象引用的一种“查找”服务器。如果您不想使用对象,则可以通过函数提供此功能。
答案 2 :(得分:0)
我这样做的方法是创建一个容器类。
from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor
class QOTD(Protocol):
def connectionMade(self):
self.factory.message_siblings("Got a client")
self.transport.loseConnection()
class MyFactory(Factory):
protocol = QOTD
def __init__(self,root,name):
self.clients = []
self.root = root
self.name = name
#self.root.add_child(name,self)
def message_siblings(self,message):
self.root.message_children(self.name,message)
def message_sibling(self,message):
self.root.message_child(self.name,message)
def get_message(self,name,message):
#do something here
print name,message
class Container(object):
def __init__(self):
self.servers = {}
def add_child(self,obj,name):
self.servers[name] = obj(self,name)
def message_children(self,name,message):
for server in self.servers:
if server != name:
self.servers[server].get_message(name,message)
def message_child(self,name,message):
if name in self.servers.keys():
self.servers[server].get_message(name,message)
container = Container()
container.add_child(MyFactory,'test')
container.add_child(MyFactory,'test2')
reactor.listenTCP(8007, container.servers['test'])
reactor.listenTCP(8008, container.servers['test2'])
reactor.run()
这可能不是最好的方法,但它有效并且允许一些灵活性