ConnectionLost exception handling in twisted

I cannot handle ConnectionLost exception. A brief example of what I have. First of all, iIset connects to the jabber server and pings it. For this, I use the wokkel library. Then I add errback to the method that sends the ping. In errback, I handle ConnectionLost error. After that I close the internet connection. But I do not see if this is handled by ConnectionLost. I close the connection in my application and all exception handlers are called.

Ping is going well.

[XmlStream,client] Ping to JID(u'jabber.ru') started at HivemindPingClientProtocol [-] SEND: Β«iq to='jabber.ru' type='get' id='H_3'>/>Β» [XmlStream,client] RECV: "/><feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>" 

Internet connection is closed

 [-] SEND: Β«iq to='jabber.ru' type='get' id='H_6'>/>Β» [-] SEND: Β«iq to='jabber.ru' type='get' id='H_7'>/>Β» 

ConnectionLost handlers are not called. "Stream closed in HivemindXMPPClient" is printed in StreamManager in the _disconnected method

 [-] Protocol stopped [-] Protocol closed [-] Transport stopped [XmlStream,client] Stream closed at HivemindXMPPClient 

All exceptions are processed after the stream closes.

 [XmlStream,client] Failure [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionLost'>: Connection to the other side was lost in a non-clean fashion. [XmlStream,client] Failure [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionLost'>: Connection to the other side was lost in a non-clean fashion.] [XmlStream,client] Connection lost with [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.] [XmlStream,client] Stopping factory <hivemind.network.network_core.HivemindXmlStreamFactory object at 0xa2e904c>> 

Can someone explain why errbacks gets called after the thread closes? Actually, I want to implement the reconnect function (I already use ReconnectingFactory, but not responsive to ConnectionLost). Can someone give me an example of re-implementation in twisted?

Script example. Run this script (make sure ping works fine). Then close your internet connection. When multiple ping has occurred, you need to complete the script. As you can see, ConnectionLost errors are handled after the connection is closed.

 import sys from twisted.python import log from twisted.words.protocols import jabber from twisted.internet.error import ConnectionLost from wokkel.client import XMPPClient from wokkel.ping import PingClientProtocol from twisted.internet.task import LoopingCall JID = unicode(' YOUR@JABBER.ID ') PASSWORD = 'PASSWORD' INTERVAL = 3 class SpecialPingClientProtocol(PingClientProtocol): def __init__(self, entity, interval): self.__entity = jabber.jid.internJID(entity) self.__interval = interval self.__pingLoop = None def _onError(self, failure): log.msg('Failure %s at %s' % (failure, self.__class__.__name__)) error = failure.trap(jabber.error.StanzaError, ConnectionLost) if error == jabber.error.StanzaError: if failure.value.condition == 'feature-not-implemented': return None elif error == ConnectionLost: # Do some beautiful things log.msg('Connection is lost. I want to reconnect NOW') return failure def _sendPing(self): defer = self.ping(self.__entity) defer.addErrback(self._onError) def stopPing(self): log.msg('Ping to %s stopped at %s' % (self.__entity, self.__class__.__name__)) if self.__pingLoop is not None and self.__pingLoop.running: self.__pingLoop.stop() self.__pingLoop = None def startPing(self): log.msg('Ping to %s started at %s ' % (self.__entity, self.__class__.__name__)) self.__pingLoop = LoopingCall(self._sendPing) self.__pingLoop.start(self.__interval, now = False) def main(): log.startLogging(sys.stdout) transport = XMPPClient(jabber.jid.internJID(JID), PASSWORD) transport.logTraffic = True pinger = SpecialPingClientProtocol(JID, INTERVAL) pinger.setHandlerParent(transport) transport.startService() pinger.startPing() reactor.run() if __name__ == '__main__': from twisted.internet import reactor main() 
+4
source share
1 answer

The protocol has:

 clientConnectionFailed(self, connector, reason) clientConnectionLost(self, connector, reason) 

you can override both and call PingClientProtocol.clientConnectionFailed and PingClientProtocol.clientConnectionLost

assuming PingClientProtocol inherits somehow from the protocol

+2
source

Source: https://habr.com/ru/post/1337845/


All Articles