Start reconnect if a second ping is sent without a pong for the first

May help with #1564.
This commit is contained in:
Lonami Exo 2020-12-11 17:18:25 +01:00
parent 0a4d54fca4
commit becfe2ce7a
2 changed files with 21 additions and 4 deletions

View File

@ -348,7 +348,7 @@ class UpdateMethods:
# We also don't really care about their result. # We also don't really care about their result.
# Just send them periodically. # Just send them periodically.
try: try:
self._sender.send(functions.PingRequest(rnd())) self._sender._keepalive_ping(rnd())
except (ConnectionError, asyncio.CancelledError): except (ConnectionError, asyncio.CancelledError):
return return

View File

@ -16,6 +16,7 @@ from ..errors import (
from ..extensions import BinaryReader from ..extensions import BinaryReader
from ..tl.core import RpcResult, MessageContainer, GzipPacked from ..tl.core import RpcResult, MessageContainer, GzipPacked
from ..tl.functions.auth import LogOutRequest from ..tl.functions.auth import LogOutRequest
from ..tl.functions import PingRequest
from ..tl.types import ( from ..tl.types import (
MsgsAck, Pong, BadServerSalt, BadMsgNotification, FutureSalts, MsgsAck, Pong, BadServerSalt, BadMsgNotification, FutureSalts,
MsgNewDetailedInfo, NewSessionCreated, MsgDetailedInfo, MsgsStateReq, MsgNewDetailedInfo, NewSessionCreated, MsgDetailedInfo, MsgsStateReq,
@ -55,6 +56,7 @@ class MTProtoSender:
self._update_callback = update_callback self._update_callback = update_callback
self._auto_reconnect_callback = auto_reconnect_callback self._auto_reconnect_callback = auto_reconnect_callback
self._connect_lock = asyncio.Lock() self._connect_lock = asyncio.Lock()
self._ping = None
# Whether the user has explicitly connected or disconnected. # Whether the user has explicitly connected or disconnected.
# #
@ -419,6 +421,18 @@ class MTProtoSender:
self._reconnecting = True self._reconnecting = True
asyncio.get_event_loop().create_task(self._reconnect(error)) asyncio.get_event_loop().create_task(self._reconnect(error))
def _keepalive_ping(self, rnd_id):
"""
Send a keep-alive ping. If a pong for the last ping was not received
yet, this means we're probably not connected.
"""
# TODO this is ugly, update loop shouldn't worry about this, sender should
if self._ping is None:
self._ping = rnd_id
self.send(PingRequest(rnd_id))
else:
self._start_reconnect(None)
# Loops # Loops
async def _send_loop(self): async def _send_loop(self):
@ -641,6 +655,9 @@ class MTProtoSender:
""" """
pong = message.obj pong = message.obj
self._log.debug('Handling pong for message %d', pong.msg_id) self._log.debug('Handling pong for message %d', pong.msg_id)
if self._ping == pong.ping_id:
self._ping = None
state = self._pending_state.pop(pong.msg_id, None) state = self._pending_state.pop(pong.msg_id, None)
if state: if state:
state.future.set_result(pong) state.future.set_result(pong)