5 Stimmen

Senden von in einer Twisted Factory empfangenen Daten an eine zweite Factory

Ich versuche, ein einfaches Programm mit Twisted-Framework zu schreiben und ich kämpfe mit der Lösung (oder sogar mit der Vorstellung, wie es zu schreiben) Problem, das ich keine relevante Dokumentation für finden konnte:

Der Hauptreaktor verwendet zwei Fabriken, eine benutzerdefinierte, die auf TCP-Verbindungen an einem bestimmten Port (z. B. 8000) wartet, und eine zweite, die sich bei einem bestimmten IRC-Server und -Kanal anmeldet. Beim Empfang von Daten (einfache, einzeilige Text) auf der Fabrik, die auf 8000 hört, muss ich diese Daten an die zweite Fabrik übergeben, so dass es dann entsprechend verarbeitet werden könnte - entweder eine Nachricht mit diesem Text an einen Kanal oder eine private Nachricht an eine Person senden, das ist jetzt nicht wirklich wichtig. Ich kann keine Möglichkeit finden, die Daten von der ersten Fabrik zu erhalten und sie an eine andere zu senden, um sie zu verarbeiten (vielleicht wie die übliche empfangene Verbindung für die zweite IRC-Fabrik?).

Wenn dies irgendwie gelöst werden könnte, dann würde ich gerne eine oder sogar mehrere Fabriken (z.B. Jabber) hinzufügen, um die empfangenen Daten auf Port 8000 an alle auf einmal zu senden, um sie entsprechend an Protokolle weiterzuleiten (IRC an einen Kanal, Jabber an einen Kontakt, und so weiter).

Gibt es jemanden, der ein ähnliches Problem hatte und bereit ist, mir einen Rat zu geben oder sogar einige Codezeilen zu teilen? Jede Hilfe wird sehr geschätzt werden!

Vielen Dank im Voraus.

6voto

nosklo Punkte 204121

Fabriken sind nur Objekte. Um Daten von einem Objekt an ein anderes zu übergeben, definieren Sie Methoden, rufen diese auf und übergeben die Daten als Parameter oder setzen Attribute. Ich denke, dies FAQ-Frage wird Ihnen helfen:

Wie mache ich eine Eingabe für eine Verbindung? zu einer Ausgabe auf einer anderen führen?

Dies scheint ein Twisted Frage, aber eigentlich ist es eine Python Frage. Jede Protocol Objekt repräsentiert eine Verbindung; Sie können rufen seine transport.write um etwas zu schreiben Daten zu schreiben. Dies sind normale Python Objekte; Sie können sie in Listen einfügen, Wörterbücher oder jede andere Daten Struktur, die für Ihre Anwendung Anwendung passt.

Ein einfaches Beispiel ist das Hinzufügen einer Liste zu in Ihre Fabrik ein, und in Ihrem Protokoll connectionMade y connectionLost , hinzufügen zu dieser Liste hinzufügen und aus ihr entfernen. Hier ist der 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()

0voto

Mick Punkte 21629

Ich denke, Ihr obiger Kommentar geht in die richtige Richtung - Sie brauchen einen Verweis oder ein "Handle" für das Objekt, an das Sie die Daten senden möchten.

Mit anderen Worten: Das sendende Fabrikobjekt muss einen Verweis auf das empfangende Fabrikobjekt haben, wenn Sie eine Objekt-zu-Objekt-Kommunikation - d.h. Methodenaufrufe - verwenden wollen. Eine Möglichkeit, dies zu erreichen, besteht darin, dass der Name der empfangenden Fabrik bei der Initialisierung an die sendende Fabrik übergeben wird.

Es ist in den Beispielen nicht immer ersichtlich, aber einer Fabrik können bei ihrer Initialisierung Daten übergeben werden. Zum Beispiel könnte im obigen Fall die Zeile, die die MultiEchoFactory erstellt, geändert werden in:

 reactor.listenTCP(4321, MultiEchoFactory(someOtherObject))

und das MultiEchoFactory-Objekt selbst, das in seinem init Methode:

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

Jetzt haben Sie einen Verweis auf das andere Objekt und können Methoden dafür aufrufen.

Ein anderer Ansatz könnte darin bestehen, ein völlig separates Objekt zu haben, auf das alle Ihre Fabriken bei der Initialisierung einen Verweis erhalten und das als eine Art "Look-up"-Server für Objektverweise fungiert, wenn ein Objekt mit einem anderen sprechen möchte. Diese Funktionalität könnte durch eine Funktion bereitgestellt werden, wenn Sie lieber kein Objekt verwenden möchten.

0voto

tomfmason Punkte 969

Ich mache das, indem ich eine Containerklasse erstelle.

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

Dies ist vielleicht nicht die beste Methode, aber sie funktioniert und ermöglicht eine gewisse Flexibilität

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X