Python 将一个扭曲工厂中接收到的数据发送到第二个工厂

Python 将一个扭曲工厂中接收到的数据发送到第二个工厂,python,twisted,factory,xmpp,irc,Python,Twisted,Factory,Xmpp,Irc,我正在尝试使用Twisted framework编写一个简单的程序,我正在努力解决(甚至是想象如何编写)这个问题,我找不到任何相关文档: 主反应器使用两个工厂,一个是定制的,监听给定端口(比如8000)上的TCP连接,另一个是登录给定的IRC服务器和通道。在8000监听工厂接收数据(简单的一行文本)时,我需要将该数据传递给第二个工厂,以便对其进行相应的处理——要么将带有该文本的消息发送到某个频道,要么将priv消息发送给某个人,现在这并不重要。我找不到任何方法从第一个工厂获取数据并将其发送到另一

我正在尝试使用Twisted framework编写一个简单的程序,我正在努力解决(甚至是想象如何编写)这个问题,我找不到任何相关文档:

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

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

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


提前感谢。

工厂只是对象。要将数据从一个传递到另一个,可以定义和调用方法,并将数据作为参数传递,或设置属性。我认为这将有助于你:

如何在一个连接上进行输入 在另一台计算机上产生输出

这似乎是一个扭曲的 问题,但实际上它是一条蟒蛇 问题。每个
协议
对象 表示一个连接;你可以 调用它的
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()

我认为你上面的评论是正确的——你需要有一个引用或一个“句柄”来表示你想要发送数据的对象

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

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

 reactor.listenTCP(4321, MultiEchoFactory(someOtherObject))
多回声工厂对象本身在其init方法中进行了修改:

class MultiEchoFactory(Factory):
    protocol = MultiEcho
    def __init__(self, otherObjectReference):
        self.echoers = []
        self.otherObject = otherObjectReference
现在您有了对另一个对象的引用并对其调用方法


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

我的方法是创建一个容器类

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()

这可能不是最好的方法,但它很有效,并允许一定的灵活性

谢谢你的回答,但我看到了这一点,而这并不是我要问的——你的例子将数据发送给同一工厂内的许多客户,而我的问题似乎更广泛——在工厂之间发送数据。我试过把它们当作物品,但运气不好。也许我不知道用这种不寻常的方式使用工厂时应该调用哪些方法(而工厂通常的方式是接收连接)。@SpankMe:我无法想象你在做什么,你无法通过在工厂上创建普通的python方法并调用它们来解决这个问题。也许你应该编辑你的问题,并添加一个小的示例代码,说明你想做什么。在这个示例中,我只使用一个工厂,在两个端口上侦听。在您的问题中,您提到连接到irc服务器。用这种方法应该很简单。只需将相关变量添加到irc客户端工厂init,并添加message_sibling、message_sibling等方法。