【发布时间】: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