工厂实例未创建新的延迟

时间:2017-09-15 01:57:40

标签: python-2.7 twisted twisted.internet

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

1 个答案:

答案 0 :(得分:0)

请注意,您的程序中只创建了一个LockServerFactory

factory = LockServerFactory()

但是,在接受连接时会创建许多LockProtocol个实例。如果您具有每个连接状态,则将其置于LockProtocol

看起来你的“锁定数据已完成”事件不是一次性的,所以Deferred可能不是这项工作的正确抽象。

可能您需要一个多用途事件处理程序,可能是自定义构建的,而不是在事件发生时触发LockServerFactory Deferred的事件:

class LockServerFactory(ServerFactory):

  protocol = LockProtocol  

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

 factory = LockServerFactory(got_lockData)

(顺便提一下,请注意我已从此实现中删除clientConnectionFailed:这是 ClientFactory 的方法。它永远不会在服务器工厂中调用。)< / p>