工厂实例不创建新的延迟
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
可能不是这项工作的正确抽象。
而不是 LockServerFactory
和 Deferred
在该事件发生时触发,也许您想要一个多用途事件处理程序,也许是自定义构建的:
class LockServerFactory(ServerFactory):
protocol = LockProtocol
def __init__(self, lockDataFinished):
self.lockDataFinished = lockDataFinished
factory = LockServerFactory(got_lockData)
(顺便说一句,请注意我已经从这个实现中删除了 clientConnectionFailed
:这是 ClientFactory
的一个方法。它永远不会被调用服务器工厂。)
我是 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
可能不是这项工作的正确抽象。
而不是 LockServerFactory
和 Deferred
在该事件发生时触发,也许您想要一个多用途事件处理程序,也许是自定义构建的:
class LockServerFactory(ServerFactory):
protocol = LockProtocol
def __init__(self, lockDataFinished):
self.lockDataFinished = lockDataFinished
factory = LockServerFactory(got_lockData)
(顺便说一句,请注意我已经从这个实现中删除了 clientConnectionFailed
:这是 ClientFactory
的一个方法。它永远不会被调用服务器工厂。)