Twisted différé non appelable après une défaillance de la connexion
Question
Avoir mon usine client ici:
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
Et il lance le code ici:
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()
Lorsque la connexion échoue (le serveur distant est en baisse), je reçois le client ClientConnection Failed, mais il obtient étrangement une "instruction excepte.AttributeError: l'instance smppClientFactory n'a pas d'attribut 'ConnectDeferred'".
J'ai besoin d'appeler l'errback lorsque la connexion échoue, il semble qu'il manque quelque chose lors de la gestion des différés.
La solution
Sur votre code de lancement, vous avez instancié un SMPPClientFactory et appelé Connect () dessus. Cette instance particulière aura l'attribut ConnectDeferred. Cependant, Connect a également instancié un autre SMPPClientFactory: factory = SMPPClientFactory(self.config, self.msgHandler)
Et c'est l'instance que vous avez utilisée pour créer la connexion réelle. Cela n'a pas l'attribut ConnectDeferred car avec cette instance, la connexion n'a jamais été appelée.