use XMPP ping (XEP-0199) to detect connection lost at applicatin level. fixes #2767
This commit is contained in:
parent
059ed3dd27
commit
85cc4889ec
|
@ -705,11 +705,21 @@ class Connection(ConnectionHandlers):
|
|||
return
|
||||
common.xmpp.features_nb.getPrivacyLists(self.connection)
|
||||
|
||||
def sendPing(self, pingTo):
|
||||
def sendPing(self, pingTo=None):
|
||||
'''Send XMPP Ping (XEP-0199) request. If pingTo is not set, ping is sent
|
||||
to server to detect connection failure at application level.'''
|
||||
if not self.connection:
|
||||
return
|
||||
iq = common.xmpp.Iq('get', to = pingTo.get_full_jid())
|
||||
id = self.connection.getAnID()
|
||||
if pingTo:
|
||||
to = pingTo.get_full_jid()
|
||||
self.dispatch('PING_SENT', (pingTo))
|
||||
else:
|
||||
to = gajim.config.get_per('accounts', self.name, 'hostname')
|
||||
self.awaiting_xmpp_ping_id = id
|
||||
iq = common.xmpp.Iq('get', to=to)
|
||||
iq.addChild(name = 'ping', namespace = common.xmpp.NS_PING)
|
||||
iq.setID(id)
|
||||
def _on_response(resp):
|
||||
timePong = time_time()
|
||||
if not common.xmpp.isResultNode(resp):
|
||||
|
@ -717,9 +727,12 @@ class Connection(ConnectionHandlers):
|
|||
return
|
||||
timeDiff = round(timePong - timePing,2)
|
||||
self.dispatch('PING_REPLY', (pingTo, timeDiff))
|
||||
self.dispatch('PING_SENT', (pingTo))
|
||||
timePing = time_time()
|
||||
self.connection.SendAndCallForResponse(iq, _on_response)
|
||||
if pingTo:
|
||||
timePing = time_time()
|
||||
self.connection.SendAndCallForResponse(iq, _on_response)
|
||||
else:
|
||||
self.connection.send(iq)
|
||||
gajim.idlequeue.set_alarm(self.check_keepalive, 5)
|
||||
|
||||
def get_active_default_lists(self):
|
||||
if not self.connection:
|
||||
|
@ -877,7 +890,7 @@ class Connection(ConnectionHandlers):
|
|||
self.connection = con
|
||||
if not self.connection:
|
||||
return
|
||||
self.connection.set_send_timeout(self.keepalives, self.send_keepalive)
|
||||
self.connection.set_send_timeout(self.keepalives, self.sendPing)
|
||||
self.connection.onreceive(None)
|
||||
iq = common.xmpp.Iq('get', common.xmpp.NS_PRIVACY, xmlns = '')
|
||||
id = self.connection.getAnID()
|
||||
|
@ -1601,10 +1614,10 @@ class Connection(ConnectionHandlers):
|
|||
c.setTagData('reason', reason)
|
||||
self.connection.send(message)
|
||||
|
||||
def send_keepalive(self):
|
||||
# nothing received for the last foo seconds (60 secs by default)
|
||||
if self.connection:
|
||||
self.connection.send(' ')
|
||||
def check_keepalive(self):
|
||||
if self.awaiting_xmpp_ping_id:
|
||||
# We haven't got the pong in time, disco and reconnect
|
||||
self.disconnect()
|
||||
|
||||
def _reconnect_alarm(self):
|
||||
if self.time_to_reconnect:
|
||||
|
|
|
@ -427,6 +427,9 @@ class ConnectionBytestream:
|
|||
real_id = unicode(iq_obj.getAttr('id'))
|
||||
if real_id[:3] != 'au_':
|
||||
return
|
||||
if real_id == self.awaiting_xmpp_ping_id:
|
||||
self.awaiting_xmpp_ping_id = None
|
||||
return
|
||||
frm = helpers.get_full_jid_from_iq(iq_obj)
|
||||
id = real_id[3:]
|
||||
if self.files_props.has_key(id):
|
||||
|
@ -666,8 +669,8 @@ class ConnectionDisco:
|
|||
query = iq.setTag('query')
|
||||
query.setAttr('node','http://gajim.org/caps#' + gajim.version.split('-',
|
||||
1)[0])
|
||||
for f in (common.xmpp.NS_BYTESTREAM, common.xmpp.NS_SI, \
|
||||
common.xmpp.NS_FILE, common.xmpp.NS_COMMANDS):
|
||||
for f in (common.xmpp.NS_BYTESTREAM, common.xmpp.NS_SI,
|
||||
common.xmpp.NS_FILE, common.xmpp.NS_COMMANDS):
|
||||
feature = common.xmpp.Node('feature')
|
||||
feature.setAttr('var', f)
|
||||
query.addChild(node=feature)
|
||||
|
@ -1243,6 +1246,8 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
|||
self.last_ids = []
|
||||
# IDs of jabber:iq:version requests
|
||||
self.version_ids = []
|
||||
# ID of urn:xmpp:ping requests
|
||||
self.awaiting_xmpp_ping_id = None
|
||||
|
||||
# keep track of sessions this connection has with other JIDs
|
||||
self.sessions = {}
|
||||
|
@ -1312,6 +1317,8 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
|||
self.dispatch('LAST_STATUS_TIME', (jid_stripped, resource, -1, ''))
|
||||
self.last_ids.remove(id)
|
||||
return
|
||||
if id == self.awaiting_xmpp_ping_id:
|
||||
self.awaiting_xmpp_ping_id = None
|
||||
errmsg = iq_obj.getErrorMsg()
|
||||
errcode = iq_obj.getErrorCode()
|
||||
self.dispatch('ERROR_ANSWER', (id, jid_from, errmsg, errcode))
|
||||
|
@ -1400,9 +1407,9 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
|||
qp.setTagData('os', helpers.get_os_info())
|
||||
self.connection.send(iq_obj)
|
||||
raise common.xmpp.NodeProcessed
|
||||
|
||||
|
||||
def _LastCB(self, con, iq_obj):
|
||||
gajim.log.debug('IdleCB')
|
||||
gajim.log.debug('LastCB')
|
||||
iq_obj = iq_obj.buildReply('result')
|
||||
qp = iq_obj.getTag('query')
|
||||
if not HAS_IDLE:
|
||||
|
@ -1412,7 +1419,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
|||
|
||||
self.connection.send(iq_obj)
|
||||
raise common.xmpp.NodeProcessed
|
||||
|
||||
|
||||
def _LastResultCB(self, con, iq_obj):
|
||||
gajim.log.debug('LastResultCB')
|
||||
qp = iq_obj.getTag('query')
|
||||
|
@ -1432,7 +1439,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
|||
self.last_ids.remove(id)
|
||||
jid_stripped, resource = gajim.get_room_and_nick_from_fjid(who)
|
||||
self.dispatch('LAST_STATUS_TIME', (jid_stripped, resource, seconds, status))
|
||||
|
||||
|
||||
def _VersionResultCB(self, con, iq_obj):
|
||||
gajim.log.debug('VersionResultCB')
|
||||
client_info = ''
|
||||
|
|
Loading…
Reference in New Issue