5

我正在尝试使用 Twisted 框架编写一个简单的程序,并且我正在努力解决(或者甚至想像如何编写它)我找不到任何相关文档的问题:

主反应器使用两个工厂,一个是自定义的,监听给定端口(比如 8000)上的 TCP 连接,第二个是登录给定的 IRC 服务器和通道。在 8000 监听的工厂接收数据(简单的一行文本)时,我需要将该数据传递给第二个工厂,因此可以对其进行相应处理 - 将带有该文本的消息发送到通道,或发送 priv 消息对某些人来说,那现在并不重要。我找不到任何方法从第一个工厂获取数据并将其发送到另一个工厂进行处理(可能像通常收到的第二个 IRC 工厂的连接一样?)。

如果这可以通过某种方式解决,那么我想添加一个甚至更多工厂(例如 Jabber),以便将端口 8000 上接收到的数据一次发送给所有工厂,并将其相应地传递给协议(IRC 到通道, Jabber 到联系人,等等)。

有没有人遇到过类似的问题并愿意给我一些建议甚至分享一些代码行?任何帮助将不胜感激!

提前致谢。

4

3 回答 3

6

工厂只是对象。要将数据从一个传递到另一个,您定义和调用方法并将数据作为参数传递,或设置属性。我认为这个常见问题解答会对您有所帮助:

如何使一个连接上的输入导致另一个连接上的输出?

这似乎是一个 Twisted 问题,但实际上它是一个 Python 问题。每个Protocol对象代表一个连接;您可以调用它transport.write来向其写入一些数据。这些是常规的 Python 对象;您可以将它们放入列表、字典或任何其他适合您的应用程序的数据结构中。

作为一个简单的例子,将一个列表添加到您的工厂,并在您的协议的 connectionMadeandconnectionLost中,将其添加到该列表中并从该列表中删除它。这是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()
于 2010-09-17T19:23:08.123 回答
0

我认为您上面的评论是正确的 - 您需要为您希望将数据发送到的对象提供参考或“句柄”。

换句话说,如果您想使用对象到对象的通信——即方法调用,发送工厂对象必须具有接收工厂对象的引用。实现此目的的一种方法是在初始化时将接收工厂的名称传递给发送工厂。

从示例中并不总是很明显,但是工厂可以在初始化时将数据传递给它。例如,在上面的例子中,创建 MultiEchoFactory 的行可以修改为:

 reactor.listenTCP(4321, MultiEchoFactory(someOtherObject))

和 MultiEchoFactory 对象本身在它的init方法中修改:

class MultiEchoFactory(Factory):
    protocol = MultiEcho
    def __init__(self, otherObjectReference):
        self.echoers = []
        self.otherObject = otherObjectReference

现在您有了对另一个对象的引用并在其上调用方法。

另一种方法可能是拥有一个完全独立的对象,在初始化时为所有工厂提供一个引用,并且当一个对象想要与另一个对象交谈时,它充当对象引用的一种“查找”服务器。如果您不想使用对象,则此功能可以由函数提供。

于 2010-09-22T11:47:15.707 回答
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()

这可能不是最好的方法,但它可以工作并且具有一定的灵活性

于 2010-10-08T06:05:50.593 回答