2011-01-31 80 views
4

我无法处理ConnectionLost异常。 我有什么简单的例子。首先,设置连接到Jabber服务器并ping它。我为此使用了wokkel库。然后我将errback添加到发送ping的方法中。在errback中,我处理ConnectionLost错误。之后,我关闭了互联网连接。但是我看不到ConnectionLost是否被处理。我在我的应用程序中关闭连接,并调用所有异常处理程序。扭曲处理ConnectionLost异常

平安顺利。

[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的处理程序不被调用。 “流收于HivemindXMPPClient”被印刷在StreamManager在_disconnected方法

[-] 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?其实我想实现一个重新连接功能(我已经使用重新连接工厂,但它不会对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('[email protected]') 
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() 

回答

2

协议有:

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

可以同时覆盖和通话 PingClientProtocol.clientConnectionFailed 和PingClientProtocol.clientConnectionLost

假设PingClientProtocol从某种程度上协议继承

+0

谢谢,但实际上PingClientProtocol从XMPPHandler继承,而不是从Protocol继承。而这些方法属于ClientFactory。我不知道如何实现你所说的。你能提供一个简单的例子吗? – 2011-05-22 07:47:47