【问题标题】:Factory instance not creating a new deferred工厂实例未创建新的延迟
【发布时间】:2017-09-15 01:57:39
【问题描述】:

我对 Twisted 还很陌生,所以我确信这是一个新手错误。我已经构建了一个简单的服务器,它接收来自客户端的消息,并且在收到消息后,服务器会触发一个回调,将消息打印到控制台。

首先,服务器按预期工作。不幸的是,当我启动第二个客户端时,我收到以下错误“twisted.internet.defer.AlreadyCalledError”。我的理解是工厂会创建一个新的 deferred 实例,即新的 deferred 之前不会被调用?

请看下面的代码。任何帮助将不胜感激。

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

【问题讨论】:

    标签: python-2.7 twisted twisted.internet


    【解决方案1】:

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

    factory = LockServerFactory()
    

    但是,当连接被接受时,就会创建尽可能多的LockProtocol 实例。如果你有每个连接的状态,放置它的地方是LockProtocol

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

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

    class LockServerFactory(ServerFactory):
    
      protocol = LockProtocol  
    
      def __init__(self, lockDataFinished):
        self.lockDataFinished = lockDataFinished
    
     factory = LockServerFactory(got_lockData)
    

    (顺便提一下,我已经从这个实现中删除了clientConnectionFailed:这是一个ClientFactory的方法。它永远不会在服务器工厂上调用。)

    【讨论】:

      猜你喜欢
      • 2018-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-28
      相关资源
      最近更新 更多