2017-09-15 7 views
0
Schaffung

ich Twisted ziemlich neu bin, so bin ich sicher, dass dies ein Rookie Fehler. Ich habe einen einfachen Server aufgebaut, die eine Nachricht von dem Client empfängt und nach Erhalt der Nachricht feuert der Server einen Rückruf, den die Nachricht an die Konsole ausgibt.Fabrik Beispiel keine neue latente

In erster Instanz arbeitet der Server wie erwartet. Leider, wenn ich einen zweiten Client starten erhalte ich die folgenden Fehler „twisted.internet.defer.AlreadyCalledError.“ Es war mein Verständnis, dass die Fabrik eine neue Instanz der aufgeschobenen machen würde, d. H. Die neue aufgeschobene wäre vorher nicht aufgerufen worden?

Bitte beachten Sie den folgenden Code. Jede Hilfe wäre sehr willkommen.

import sys 
from twisted.internet.protocol import ServerFactory, Protocol 
from twisted.internet import defer 

class LockProtocol(Protocol): 

    lockData = '' 

    def dataReceived(self, data): 
    self.lockData += data 

    if self.lockData.endswith('??'): 
     self.lockDataReceived(self.lockData) 

    def lockDataReceived(self, lockData): 
    self.factory.lockDataFinished(lockData) 

class LockServerFactory(ServerFactory): 

    protocol = LockProtocol 

    def __init__(self): 
    self.deferred = defer.Deferred() # Initialise deferred 

    def lockDataFinished(self, lockData): 
     self.deferred.callback(lockData) 

    def clientConnectionFailed(self, connector, reason): 
     self.deferred.errback(reason) 


def main(): 

    HOST = '127.0.0.1' # localhost 
    PORT = 10001 

    def got_lockData(lockData): 
    print "We have received lockData. It is as follows:", lockData 

    def lockData_failed(err): 
    print >> sys.stderr, 'The lockData download failed.' 
    errors.append(err) 


    factory = LockServerFactory() 

    from twisted.internet import reactor 

    # Listen for TCP connections on a port, and use our factory to make a protocol instance for each new connection 

    port = reactor.listenTCP(PORT,factory) 

    print 'Serving on %s' % port.getHost() 

    # Set up callbacks 

    factory.deferred.addCallbacks(got_lockData,lockData_failed) 

    reactor.run() # Start the reactor 

if __name__ == '__main__': 
    main() 

Antwort

0

Beachten Sie, dass es nur einen LockServerFactory jemals erstellt in Ihrem Programm ist:

factory = LockServerFactory() 

Da jedoch viele LockProtocol Instanzen erstellt werden als Verbindungen akzeptiert werden. Wenn Sie pro Verbindungszustand haben, ist es der Ort, setzen ist auf LockProtocol.

Es sieht so aus, als ob Ihr "lock data completed" -Ereignis nicht einmalig ist, also ist Deferred wahrscheinlich nicht die richtige Abstraktion für diesen Job.

Statt eines LockServerFactory mit einem Deferred, der ausgelöst wird, wenn das Ereignis geschieht, vielleicht möchten Sie ein Multi-Use-Event-Handler, vielleicht speziell angefertigten:

class LockServerFactory(ServerFactory): 

    protocol = LockProtocol 

    def __init__(self, lockDataFinished): 
    self.lockDataFinished = lockDataFinished 

factory = LockServerFactory(got_lockData) 

(übrigens bemerken, dass ich fallen gelassen habe clientConnectionFailed aus diese Implementierung: das ist eine Methode der ClientFactory Es wird nie auf einem Server ab Werk genannt werden)

..