2017-09-15 49 views
0

我是Twisted的新手,所以我确信这是一个新手的错误。我已经构建了一个简单的服务器,它接收来自客户端的消息,并在收到消息时触发将消息打印到控制台的回调。工厂实例没有创建新的推迟

在第一个实例中,服务器按预期工作。不幸的是,当我启动第二个客户端时,出现跟随错误“twisted.internet.defer.AlreadyCalledError”。我的理解是,工厂会制造一个延期的新实例,即新的延期将不会被调用过吗?

请参阅下面的代码。任何帮助将非常感激。

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

回答

0

注意,只有一个LockServerFactory在程序中创建过:

factory = LockServerFactory() 

然而,随着连接都接受创建为许多LockProtocol实例。如果你有每个连接状态,放置它的地方是LockProtocol

看起来您的“锁定数据已完成”事件不是一次性的,因此Deferred可能不是此作业的正确抽象。

而不是一个Deferred当事件发生时触发一个LockServerFactory,也许你要多用事件处理程序,也许定制:

class LockServerFactory(ServerFactory): 

    protocol = LockProtocol 

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

factory = LockServerFactory(got_lockData) 

(顺便说一句,请注意,我已经从下降clientConnectionFailed这个实现:这是一种方法ClientFactory。它永远不会在服务器工厂调用。)

相关问题