Sending data received in one Twisted factory to second factory

后端 未结 3 752
[愿得一人]
[愿得一人] 2021-01-01 02:39

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 doc

相关标签:
3条回答
  • 2021-01-01 02:57

    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()
    
    0 讨论(0)
  • 2021-01-01 03:09

    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.

    0 讨论(0)
  • 2021-01-01 03:19

    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

    0 讨论(0)
提交回复
热议问题