【问题标题】:Handling of ConnectionLost exception in twisted处理扭曲中的 ConnectionLost 异常
【发布时间】:2011-05-22 10:20:38
【问题描述】:

我无法处理 ConnectionLost 异常。 我所拥有的简要示例。首先 iIset 建立与 jabber 服务器的连接并 ping 它。我为此使用 wokkel 库。然后我将 errback 添加到发送 ping 的方法中。在 errback 中,我处理 ConnectionLost 错误。之后,我关闭了互联网连接。但我看不到是否处理了 ConnectionLost。我在我的应用程序中关闭连接并调用所有异常处理程序。

Ping 顺利。

[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'/>"

互联网连接已关闭

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

不会调用 ConnectionLost 的处理程序。 “Stream closed at HivemindXMPPClient”以_disconnected方法打印在StreamManager中

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

所有异常都在关闭流后处理。

[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>> 

谁能解释为什么在关闭流后调用 errbacks?实际上我想实现一个重新连接功能(我已经使用了 ReconnectingFactory,但它对 ConnectionLost 没有反应)。有人可以给我一些扭曲的重新连接实现的例子吗?

脚本示例。 运行此脚本(确保 ping 正常工作)。然后关闭您的互联网连接。当多次 ping 发生时,您需要终止脚本。可以看到,ConnectionLost 错误是在关闭连接后处理的。

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()

【问题讨论】:

    标签: python error-handling twisted


    【解决方案1】:

    协议有:

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

    您可以同时覆盖两者并调用 PingClientProtocol.clientConnectionFailed 和 PingClientProtocol.clientConnectionLost

    假设 PingClientProtocol 以某种方式从 Protocol 继承

    【讨论】:

    • 谢谢,但实际上 PingClientProtocol 继承自 XMPPHandler,而不是协议。而这些方法属于ClientFactory。我不知道如何实现你所说的。你能提供一个简单的例子吗?
    • twistedmatrix.com/documents/current/api/… 有类似的方法,所以你可以重写: def connectionLost(reason): # do your stuff here # 然后调用超级方法 XMPPHandler.connectionLost(self, reason)
    猜你喜欢
    • 2016-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-21
    • 1970-01-01
    • 2019-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多