Twisted diferido no invocable después de un error de conexión
Pregunta
Tener la fábrica de mi cliente aquí:
import logging, traceback
from twisted.internet.protocol import ClientFactory
from twisted.internet import defer, reactor, ssl
from twisted.application import service
from protocols.smpp.protocol import SMPPClientProtocol
class SMPPClientFactory(ClientFactory):
protocol = SMPPClientProtocol
def __init__(self, config):
self.config = config
def getConfig(self):
return self.config
def clientConnectionFailed(self, connector, reason):
print "clientConnectionFailed"
self.connectDeferred.errback(reason)
def clientConnectionLost(self, connector, reason):
print "clientConnectionLost"
def connect(self):
self.connectDeferred = defer.Deferred()
factory = SMPPClientFactory(self.config, self.msgHandler)
self.log.warning('Establishing TCP connection to %s:%d' % (self.config.host, self.config.port))
reactor.connectTCP(self.config.host, self.config.port, factory)
return self.connectDeferred
Y su código de lanzamiento aquí:
import logging, traceback
from twisted.internet import reactor, defer
from protocols.smpp.configs import SMPPClientConfig
from protocols.smpp.smpp_operations import SMPPOperationFactory
from testbed.client import SMPPClientFactory
class SMPP(object):
def __init__(self, config=None):
if config is None:
config = SMPPClientConfig()
self.config = config
self.opFactory = SMPPOperationFactory(config)
def run(self):
try:
#Bind
SMPPClientFactory(self.config, self.handleMsg).connect().addErrback(self.connectFailed)
except Exception, e:
print "ERROR: %s" % str(e)
def connectFailed(self, reason):
print "Connection failed %s" % str(reason)
def handleMsg(self, smpp, pdu):
pass
if __name__ == '__main__':
config = SMPPClientConfig(host='127.0.0.1', port=2775, username='smppclient1', password='password',
log_level=logging.DEBUG)
logging.basicConfig(level=config.log_level, filename=config.log_file, format=config.log_format,datefmt=config.log_dateformat)
SMPP(config).run()
reactor.run()
Cuando la conexión falla (el servidor remoto está inactivo), se llama al clientConnectionFailed de fábrica, pero extrañamente recibe un "exceptions.AttributeError: SMPPClientFactory instancia no tiene atributo 'connectDeferred'".
Necesito llamar al errback cuando falla la conexión, parece que falta algo cuando se trata de aplazados ..
Solución
En su código de lanzamiento, creó una instancia de SMPPClientFactory y llamó a connect () en él.Esta instancia en particular tendrá el atributo connectDeferred.Sin embargo, connect también creó una instancia de otro SMPPClientFactory: factory = SMPPClientFactory(self.config, self.msgHandler)
y esta es la instancia que usó para crear la conexión real.Esto no tiene el atributo connectDeferred porque con esta instancia nunca se ha llamado a connect.