工厂实例不创建新的延迟

Factory instance not creating a new deferred

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

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

factory = LockServerFactory()

但是,LockProtocol 个实例会随着连接的接受而创建。如果你有每个连接状态,放置它的地方是 LockProtocol.

看起来你的 "lock data completed" 事件不是一次性的,所以 Deferred 可能不是这项工作的正确抽象。

而不是 LockServerFactoryDeferred 在该事件发生时触发,也许您想要一个多用途事件处理程序,也许是自定义构建的:

class LockServerFactory(ServerFactory):

  protocol = LockProtocol  

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

 factory = LockServerFactory(got_lockData)

(顺便说一句,请注意我已经从这个实现中删除了 clientConnectionFailed:这是 ClientFactory 的一个方法。它永远不会被调用服务器工厂。)