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
|
return
|
||||||
common.xmpp.features_nb.getPrivacyLists(self.connection)
|
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:
|
if not self.connection:
|
||||||
return
|
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.addChild(name = 'ping', namespace = common.xmpp.NS_PING)
|
||||||
|
iq.setID(id)
|
||||||
def _on_response(resp):
|
def _on_response(resp):
|
||||||
timePong = time_time()
|
timePong = time_time()
|
||||||
if not common.xmpp.isResultNode(resp):
|
if not common.xmpp.isResultNode(resp):
|
||||||
|
@ -717,9 +727,12 @@ class Connection(ConnectionHandlers):
|
||||||
return
|
return
|
||||||
timeDiff = round(timePong - timePing,2)
|
timeDiff = round(timePong - timePing,2)
|
||||||
self.dispatch('PING_REPLY', (pingTo, timeDiff))
|
self.dispatch('PING_REPLY', (pingTo, timeDiff))
|
||||||
self.dispatch('PING_SENT', (pingTo))
|
if pingTo:
|
||||||
timePing = time_time()
|
timePing = time_time()
|
||||||
self.connection.SendAndCallForResponse(iq, _on_response)
|
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):
|
def get_active_default_lists(self):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
|
@ -877,7 +890,7 @@ class Connection(ConnectionHandlers):
|
||||||
self.connection = con
|
self.connection = con
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
self.connection.set_send_timeout(self.keepalives, self.send_keepalive)
|
self.connection.set_send_timeout(self.keepalives, self.sendPing)
|
||||||
self.connection.onreceive(None)
|
self.connection.onreceive(None)
|
||||||
iq = common.xmpp.Iq('get', common.xmpp.NS_PRIVACY, xmlns = '')
|
iq = common.xmpp.Iq('get', common.xmpp.NS_PRIVACY, xmlns = '')
|
||||||
id = self.connection.getAnID()
|
id = self.connection.getAnID()
|
||||||
|
@ -1601,10 +1614,10 @@ class Connection(ConnectionHandlers):
|
||||||
c.setTagData('reason', reason)
|
c.setTagData('reason', reason)
|
||||||
self.connection.send(message)
|
self.connection.send(message)
|
||||||
|
|
||||||
def send_keepalive(self):
|
def check_keepalive(self):
|
||||||
# nothing received for the last foo seconds (60 secs by default)
|
if self.awaiting_xmpp_ping_id:
|
||||||
if self.connection:
|
# We haven't got the pong in time, disco and reconnect
|
||||||
self.connection.send(' ')
|
self.disconnect()
|
||||||
|
|
||||||
def _reconnect_alarm(self):
|
def _reconnect_alarm(self):
|
||||||
if self.time_to_reconnect:
|
if self.time_to_reconnect:
|
||||||
|
|
|
@ -427,6 +427,9 @@ class ConnectionBytestream:
|
||||||
real_id = unicode(iq_obj.getAttr('id'))
|
real_id = unicode(iq_obj.getAttr('id'))
|
||||||
if real_id[:3] != 'au_':
|
if real_id[:3] != 'au_':
|
||||||
return
|
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)
|
frm = helpers.get_full_jid_from_iq(iq_obj)
|
||||||
id = real_id[3:]
|
id = real_id[3:]
|
||||||
if self.files_props.has_key(id):
|
if self.files_props.has_key(id):
|
||||||
|
@ -666,8 +669,8 @@ class ConnectionDisco:
|
||||||
query = iq.setTag('query')
|
query = iq.setTag('query')
|
||||||
query.setAttr('node','http://gajim.org/caps#' + gajim.version.split('-',
|
query.setAttr('node','http://gajim.org/caps#' + gajim.version.split('-',
|
||||||
1)[0])
|
1)[0])
|
||||||
for f in (common.xmpp.NS_BYTESTREAM, common.xmpp.NS_SI, \
|
for f in (common.xmpp.NS_BYTESTREAM, common.xmpp.NS_SI,
|
||||||
common.xmpp.NS_FILE, common.xmpp.NS_COMMANDS):
|
common.xmpp.NS_FILE, common.xmpp.NS_COMMANDS):
|
||||||
feature = common.xmpp.Node('feature')
|
feature = common.xmpp.Node('feature')
|
||||||
feature.setAttr('var', f)
|
feature.setAttr('var', f)
|
||||||
query.addChild(node=feature)
|
query.addChild(node=feature)
|
||||||
|
@ -1243,6 +1246,8 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
self.last_ids = []
|
self.last_ids = []
|
||||||
# IDs of jabber:iq:version requests
|
# IDs of jabber:iq:version requests
|
||||||
self.version_ids = []
|
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
|
# keep track of sessions this connection has with other JIDs
|
||||||
self.sessions = {}
|
self.sessions = {}
|
||||||
|
@ -1312,6 +1317,8 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
self.dispatch('LAST_STATUS_TIME', (jid_stripped, resource, -1, ''))
|
self.dispatch('LAST_STATUS_TIME', (jid_stripped, resource, -1, ''))
|
||||||
self.last_ids.remove(id)
|
self.last_ids.remove(id)
|
||||||
return
|
return
|
||||||
|
if id == self.awaiting_xmpp_ping_id:
|
||||||
|
self.awaiting_xmpp_ping_id = None
|
||||||
errmsg = iq_obj.getErrorMsg()
|
errmsg = iq_obj.getErrorMsg()
|
||||||
errcode = iq_obj.getErrorCode()
|
errcode = iq_obj.getErrorCode()
|
||||||
self.dispatch('ERROR_ANSWER', (id, jid_from, errmsg, errcode))
|
self.dispatch('ERROR_ANSWER', (id, jid_from, errmsg, errcode))
|
||||||
|
@ -1402,7 +1409,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
raise common.xmpp.NodeProcessed
|
raise common.xmpp.NodeProcessed
|
||||||
|
|
||||||
def _LastCB(self, con, iq_obj):
|
def _LastCB(self, con, iq_obj):
|
||||||
gajim.log.debug('IdleCB')
|
gajim.log.debug('LastCB')
|
||||||
iq_obj = iq_obj.buildReply('result')
|
iq_obj = iq_obj.buildReply('result')
|
||||||
qp = iq_obj.getTag('query')
|
qp = iq_obj.getTag('query')
|
||||||
if not HAS_IDLE:
|
if not HAS_IDLE:
|
||||||
|
|
Loading…
Reference in New Issue