2017-09-15 46 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。它永遠不會在服務器工廠調用。)

相關問題