diff options
Diffstat (limited to 'sleekxmpp/plugins/xep_0199')
-rw-r--r-- | sleekxmpp/plugins/xep_0199/ping.py | 147 |
1 files changed, 77 insertions, 70 deletions
diff --git a/sleekxmpp/plugins/xep_0199/ping.py b/sleekxmpp/plugins/xep_0199/ping.py index b9d145aa..836ff4ae 100644 --- a/sleekxmpp/plugins/xep_0199/ping.py +++ b/sleekxmpp/plugins/xep_0199/ping.py @@ -9,8 +9,8 @@ import time import logging -import sleekxmpp -from sleekxmpp import Iq +from sleekxmpp.jid import JID +from sleekxmpp.stanza import Iq from sleekxmpp.exceptions import IqError, IqTimeout from sleekxmpp.xmlstream import register_stanza_plugin from sleekxmpp.xmlstream.matcher import StanzaPath @@ -38,7 +38,7 @@ class XEP_0199(BasePlugin): keepalive -- If True, periodically send ping requests to the server. If a ping is not answered, the connection will be reset. - frequency -- Time in seconds between keepalive pings. + interval -- Time in seconds between keepalive pings. Defaults to 300 seconds. timeout -- Time in seconds to wait for a ping response. Defaults to 30 seconds. @@ -51,14 +51,16 @@ class XEP_0199(BasePlugin): description = 'XEP-0199: XMPP Ping' dependencies = set(['xep_0030']) stanza = stanza + default_config = { + 'keepalive': False, + 'interval': 300, + 'timeout': 30 + } def plugin_init(self): """ Start the XEP-0199 plugin. """ - self.keepalive = self.config.get('keepalive', False) - self.frequency = float(self.config.get('frequency', 300)) - self.timeout = self.config.get('timeout', 30) register_stanza_plugin(Iq, Ping) @@ -69,88 +71,70 @@ class XEP_0199(BasePlugin): if self.keepalive: self.xmpp.add_event_handler('session_start', - self._handle_keepalive, + self.enable_keepalive, threaded=True) self.xmpp.add_event_handler('session_end', - self._handle_session_end) + self.disable_keepalive) def plugin_end(self): self.xmpp['xep_0030'].del_feature(feature=Ping.namespace) self.xmpp.remove_handler('Ping') if self.keepalive: self.xmpp.del_event_handler('session_start', - self._handle_keepalive) + self.enable_keepalive) self.xmpp.del_event_handler('session_end', - self._handle_session_end) + self.disable_keepalive) def session_bind(self, jid): self.xmpp['xep_0030'].add_feature(Ping.namespace) - def _handle_keepalive(self, event): - """ - Begin periodic pinging of the server. If a ping is not - answered, the connection will be restarted. - - The pinging interval can be adjused using self.frequency - before beginning processing. + def enable_keepalive(self, interval=None, timeout=None): + if interval: + self.interval = interval + if timeout: + self.timeout = timeout - Arguments: - event -- The session_start event. - """ - def scheduled_ping(): - """Send ping request to the server.""" - log.debug("Pinging...") - try: - self.send_ping(self.xmpp.boundjid.host, self.timeout) - except IqError: - log.debug("Ping response was an error." + \ - "Requesting Reconnect.") - self.xmpp.reconnect() - except IqTimeout: - log.debug("Did not recieve ping back in time." + \ - "Requesting Reconnect.") - self.xmpp.reconnect() - - self.xmpp.schedule('Ping Keep Alive', - self.frequency, - scheduled_ping, + self.keepalive = True + self.xmpp.schedule('Ping keepalive', + self.interval, + self._keepalive, repeat=True) - def _handle_session_end(self, event): - self.xmpp.scheduler.remove('Ping Keep Alive') + def disable_keepalive(self, event=None): + self.xmpp.scheduler.remove('Ping keepalive') - def _handle_ping(self, iq): - """ - Automatically reply to ping requests. + def _keepalive(self, event=None): + log.debug("Keepalive ping...") + try: + rtt = self.ping(self.xmpp.boundjid.host, timeout=self.timeout) + except IqTimeout: + log.debug("Did not recieve ping back in time." + \ + "Requesting Reconnect.") + self.xmpp.reconnect() + else: + log.debug('Keepalive RTT: %s' % rtt) - Arguments: - iq -- The ping request. - """ + def _handle_ping(self, iq): + """Automatically reply to ping requests.""" log.debug("Pinged by %s", iq['from']) iq.reply().send() - def send_ping(self, jid, timeout=None, errorfalse=False, - ifrom=None, block=True, callback=None): - """ - Send a ping request and calculate the response time. + def send_ping(self, jid, ifrom=None, block=True, timeout=None, callback=None): + """Send a ping request. Arguments: jid -- The JID that will receive the ping. - timeout -- Time in seconds to wait for a response. - Defaults to self.timeout. - errorfalse -- Indicates if False should be returned - if an error stanza is received. Defaults - to False. ifrom -- Specifiy the sender JID. block -- Indicate if execution should block until a pong response is received. Defaults to True. + timeout -- Time in seconds to wait for a response. + Defaults to self.timeout. callback -- Optional handler to execute when a pong is received. Useful in conjunction with the option block=False. """ - log.debug("Pinging %s", jid) - if timeout is None: + if not timeout: timeout = self.timeout iq = self.xmpp.Iq() @@ -159,21 +143,44 @@ class XEP_0199(BasePlugin): iq['from'] = ifrom iq.enable('ping') - start_time = time.clock() - - try: - resp = iq.send(block=block, - timeout=timeout, - callback=callback) - except IqError as err: - resp = err.iq + return iq.send(block=block, timeout=timeout, callback=callback) - end_time = time.clock() + def ping(self, jid=None, ifrom=None, timeout=None): + """Send a ping request and calculate RTT. - delay = end_time - start_time + Arguments: + jid -- The JID that will receive the ping. + ifrom -- Specifiy the sender JID. + timeout -- Time in seconds to wait for a response. + Defaults to self.timeout. + """ + own_host = False + if not jid: + if self.xmpp.is_component: + jid = self.xmpp.server + else: + jid = self.xmpp.boundjid.host + jid = JID(jid) + if jid == self.xmpp.boundjid.host or \ + self.xmpp.is_component and jid == self.xmpp.server: + own_host = True + + if not timeout: + timeout = self.timeout - if not block: - return None + start = time.time() - log.debug("Pong: %s %f", jid, delay) - return delay + log.debug('Pinging %s' % jid) + try: + self.send_ping(jid, ifrom=ifrom, timeout=timeout) + except IqError as e: + if own_host: + rtt = time.time() - start + log.debug('Pinged %s, RTT: %s', jid, rtt) + return rtt + else: + raise e + else: + rtt = time.time() - start + log.debug('Pinged %s, RTT: %s', jid, rtt) + return rtt |