Экземпляр фабрики не создает новый отложенный
Я довольно новичок в 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 ответ
Обратите внимание, что есть только один 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
, Он никогда не будет вызываться на фабрике серверов.)