将一个 Twisted 工厂收到的数据发送到第二个工厂

发布于 2024-09-24 08:59:48 字数 489 浏览 1 评论 0原文

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

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

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

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

提前致谢。

I am trying to write a simple program using Twisted framework and I am struggling with resolving (or even with imaging how to write it) issue I couldnt find any relevant documentation for:

The main reactor uses two factories, one custom, listening for TCP connections on given port (say, 8000) and second one, to log into given IRC server and channel. On receiving data (simple, one line text) on the factory listening at 8000, I need to pass that data to second factory, so it could be then processed accordingly - either send a message with that text to a channel, or a priv message to some person, thats not really important now. I cant find any way to get the data from first factory and send it to another, for processing (maybe like usual received connection for second IRC factory?).

If this could be somehow resolved, then I would like to add one or even more factories (Jabber for example) to send the received data on port 8000 to all of them at once, to pass it accordingly to protocols (IRC to a channel, Jabber to a contact, and so on).

Is there anyone who met similar issue and is willing to give me some advice or even share some lines of code? Any help will be highly appreciated!

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

走野 2024-10-01 08:59:48

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

如何在一个连接上进行输入
结果在另一个上输出?

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

作为一个简单的例子,添加一个列表
你的工厂,以及你的协议中
connectionMadeconnectionLost,添加
并将其从该列表中删除。
Python 代码如下:

fromtwisted.internet.protocol 导入协议、工厂
从twisted.internet导入反应器

MultiEcho 类(协议):
    def 连接建立(自身):
        self.factory.echoers.append(self)
    def dataReceived(自身,数据):
        对于 self.factory.echoers 中的 echoer:
            echoer.transport.write(数据)
    def 连接丢失(自身,原因):
        self.factory.echoers.remove(self)

MultiEchoFactory 类(工厂):
    协议 = MultiEcho
    def __init__(自身):
        self.echoers = []

reactor.listenTCP(4321, MultiEchoFactory())
反应堆.run()

Factories are just objects. To pass data from one to another, you define and call methods and pass the data as parameter, or set attributes. I think this faq question will help you:

How do I make input on one connection
result in output on another?

This seems like it's a Twisted
question, but actually it's a Python
question.
Each Protocol object
represents one connection; you can
call its transport.write to write some
data to it. These are regular Python
objects; you can put them into lists,
dictionaries, or whatever other data
structure is appropriate to your
application.

As a simple example, add a list to
your factory, and in your protocol's
connectionMade and connectionLost, add
it to and remove it from that list.
Here's the Python code:

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()
欢你一世 2024-10-01 08:59:48

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

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

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

 reactor.listenTCP(4321, MultiEchoFactory(someOtherObject))

并且 MultiEchoFactory 对象本身在其 init 方法中进行修改:

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

现在您拥有对另一个对象的引用并调用它的方法。

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

I think your comment above is along the right lines - you need to have a reference or a 'handle' for the object you wish to send the data to.

In other words the sending factory object must have a reference for the receiving factory object if you want to use object to object communication - i.e. method calls. One way to achieve this is for the name of the receiving factory to be passed to the sending factory at initialization.

It is not always obvious from examples but a factory can have data passed to it when it is initialized. For example in the case above the line that creates the MultiEchoFactory could be modified to:

 reactor.listenTCP(4321, MultiEchoFactory(someOtherObject))

and the MultiEchoFactory object itself modified in it's init method:

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

Now you have a reference to the other object and call methods on it.

Another approach might be to have a completely separate object which all your factories are given a reference to on initialization, and which acts as a sort of 'look up' server for object references when one object wants to speak to another. This functionality could be provided by a function if you would rather not use an object.

素年丶 2024-10-01 08:59:48

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

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

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

The way I do it is by creating a container class.

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

This may not be the best method but it works and allows for some flexibility

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文