mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2026-09-08 18:01:58 +00:00
Support custom event loops
This commit is contained in:
@@ -21,13 +21,15 @@ class Connection(abc.ABC):
|
||||
Subclasses should implement the actual protocol
|
||||
being used when encoding/decoding messages.
|
||||
"""
|
||||
def __init__(self, proxy=None, timeout=timedelta(seconds=5)):
|
||||
def __init__(self, *, loop, proxy=None, timeout=timedelta(seconds=5)):
|
||||
"""
|
||||
Initializes a new connection.
|
||||
|
||||
:param loop: the event loop to be used.
|
||||
:param proxy: whether to use a proxy or not.
|
||||
:param timeout: timeout to be used for all operations.
|
||||
"""
|
||||
self._loop = loop
|
||||
self._proxy = proxy
|
||||
self._timeout = timeout
|
||||
|
||||
@@ -54,10 +56,13 @@ class Connection(abc.ABC):
|
||||
"""Closes the connection."""
|
||||
raise NotImplementedError
|
||||
|
||||
@abc.abstractmethod
|
||||
def clone(self):
|
||||
"""Creates a copy of this Connection."""
|
||||
raise NotImplementedError
|
||||
return self.__class__(
|
||||
loop=self._loop,
|
||||
proxy=self._proxy,
|
||||
timeout=self._timeout
|
||||
)
|
||||
|
||||
@abc.abstractmethod
|
||||
async def recv(self):
|
||||
|
||||
@@ -14,9 +14,6 @@ class ConnectionTcpAbridged(ConnectionTcpFull):
|
||||
await self.conn.write(b'\xef')
|
||||
return result
|
||||
|
||||
def clone(self):
|
||||
return ConnectionTcpAbridged(self._proxy, self._timeout)
|
||||
|
||||
async def recv(self):
|
||||
length = struct.unpack('<B', await self.read(1))[0]
|
||||
if length >= 127:
|
||||
|
||||
@@ -13,10 +13,12 @@ class ConnectionTcpFull(Connection):
|
||||
Default Telegram mode. Sends 12 additional bytes and
|
||||
needs to calculate the CRC value of the packet itself.
|
||||
"""
|
||||
def __init__(self, proxy=None, timeout=timedelta(seconds=5)):
|
||||
super().__init__(proxy, timeout)
|
||||
def __init__(self, *, loop, proxy=None, timeout=timedelta(seconds=5)):
|
||||
super().__init__(loop=loop, proxy=proxy, timeout=timeout)
|
||||
self._send_counter = 0
|
||||
self.conn = TcpClient(proxy=self._proxy, timeout=self._timeout)
|
||||
self.conn = TcpClient(
|
||||
proxy=self._proxy, timeout=self._timeout, loop=self._loop
|
||||
)
|
||||
self.read = self.conn.read
|
||||
self.write = self.conn.write
|
||||
|
||||
@@ -40,9 +42,6 @@ class ConnectionTcpFull(Connection):
|
||||
async def close(self):
|
||||
self.conn.close()
|
||||
|
||||
def clone(self):
|
||||
return ConnectionTcpFull(self._proxy, self._timeout)
|
||||
|
||||
async def recv(self):
|
||||
packet_len_seq = await self.read(8) # 4 and 4
|
||||
packet_len, seq = struct.unpack('<ii', packet_len_seq)
|
||||
|
||||
@@ -13,9 +13,6 @@ class ConnectionTcpIntermediate(ConnectionTcpFull):
|
||||
await self.conn.write(b'\xee\xee\xee\xee')
|
||||
return result
|
||||
|
||||
def clone(self):
|
||||
return ConnectionTcpIntermediate(self._proxy, self._timeout)
|
||||
|
||||
async def recv(self):
|
||||
return await self.read(struct.unpack('<i', await self.read(4))[0])
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ class ConnectionTcpObfuscated(ConnectionTcpAbridged):
|
||||
every message with a randomly generated key using the
|
||||
AES-CTR mode so the packets are harder to discern.
|
||||
"""
|
||||
def __init__(self, proxy=None, timeout=timedelta(seconds=5)):
|
||||
super().__init__(proxy, timeout)
|
||||
def __init__(self, *, loop, proxy=None, timeout=timedelta(seconds=5)):
|
||||
super().__init__(loop=loop, proxy=proxy, timeout=timeout)
|
||||
self._aes_encrypt, self._aes_decrypt = None, None
|
||||
self.read = lambda s: self._aes_decrypt.encrypt(self.conn.read(s))
|
||||
self.write = lambda d: self.conn.write(self._aes_encrypt.encrypt(d))
|
||||
@@ -45,6 +45,3 @@ class ConnectionTcpObfuscated(ConnectionTcpAbridged):
|
||||
random[56:64] = self._aes_encrypt.encrypt(bytes(random))[56:64]
|
||||
await self.conn.write(bytes(random))
|
||||
return result
|
||||
|
||||
def clone(self):
|
||||
return ConnectionTcpObfuscated(self._proxy, self._timeout)
|
||||
|
||||
@@ -39,10 +39,11 @@ class MTProtoSender:
|
||||
A new authorization key will be generated on connection if no other
|
||||
key exists yet.
|
||||
"""
|
||||
def __init__(self, state, connection, *, retries=5,
|
||||
def __init__(self, state, connection, loop, *, retries=5,
|
||||
first_query=None, update_callback=None):
|
||||
self.state = state
|
||||
self._connection = connection
|
||||
self._loop = loop
|
||||
self._ip = None
|
||||
self._port = None
|
||||
self._retries = retries
|
||||
@@ -231,9 +232,13 @@ class MTProtoSender:
|
||||
raise _last_error
|
||||
|
||||
__log__.debug('Starting send loop')
|
||||
self._send_loop_handle = asyncio.ensure_future(self._send_loop())
|
||||
self._send_loop_handle = asyncio.ensure_future(
|
||||
self._send_loop(), loop=self._loop)
|
||||
|
||||
__log__.debug('Starting receive loop')
|
||||
self._recv_loop_handle = asyncio.ensure_future(self._recv_loop())
|
||||
self._recv_loop_handle = asyncio.ensure_future(
|
||||
self._recv_loop(), loop=self._loop)
|
||||
|
||||
if self._is_first_query:
|
||||
__log__.debug('Running first query')
|
||||
self._is_first_query = False
|
||||
@@ -347,11 +352,11 @@ class MTProtoSender:
|
||||
continue
|
||||
except ConnectionError as e:
|
||||
__log__.info('Connection reset while receiving %s', e)
|
||||
asyncio.ensure_future(self._reconnect())
|
||||
asyncio.ensure_future(self._reconnect(), loop=self._loop)
|
||||
break
|
||||
except OSError as e:
|
||||
__log__.warning('OSError while receiving %s', e)
|
||||
asyncio.ensure_future(self._reconnect())
|
||||
asyncio.ensure_future(self._reconnect(), loop=self._loop)
|
||||
break
|
||||
|
||||
# TODO Check salt, session_id and sequence_number
|
||||
@@ -370,7 +375,7 @@ class MTProtoSender:
|
||||
# an actually broken authkey?
|
||||
__log__.warning('Broken authorization key?: {}'.format(e))
|
||||
self.state.auth_key = None
|
||||
asyncio.ensure_future(self._reconnect())
|
||||
asyncio.ensure_future(self._reconnect(), loop=self._loop)
|
||||
break
|
||||
except SecurityError as e:
|
||||
# A step while decoding had the incorrect data. This message
|
||||
|
||||
Reference in New Issue
Block a user