diff options
| author | Fwf <[email protected]> | 2020-01-25 16:24:44 +0000 |
|---|---|---|
| committer | Rapptz <[email protected]> | 2020-04-04 03:00:27 -0400 |
| commit | fa34d357a1c28a48210e68e4b7b1f32320e44b9b (patch) | |
| tree | b9dd9674e46f01675d99f664e3e80e9f6ecaccf9 /discord/gateway.py | |
| parent | [commands] Implement `commands.before/after_invoke` (diff) | |
| download | discord.py-fa34d357a1c28a48210e68e4b7b1f32320e44b9b.tar.xz discord.py-fa34d357a1c28a48210e68e4b7b1f32320e44b9b.zip | |
Added VoiceClient.latency and VoiceClient.average_latency
This also implements the heartbeating a bit more consistent to the
official Discord client.
Diffstat (limited to 'discord/gateway.py')
| -rw-r--r-- | discord/gateway.py | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/discord/gateway.py b/discord/gateway.py index 0e90c5f6..f484c8e5 100644 --- a/discord/gateway.py +++ b/discord/gateway.py @@ -25,7 +25,7 @@ DEALINGS IN THE SOFTWARE. """ import asyncio -from collections import namedtuple +from collections import namedtuple, deque import concurrent.futures import json import logging @@ -132,9 +132,10 @@ class KeepAliveHandler(threading.Thread): class VoiceKeepAliveHandler(KeepAliveHandler): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self.recent_ack_latencies = deque(maxlen=20) self.msg = 'Keeping voice websocket alive with timestamp %s.' self.block_msg = 'Voice heartbeat blocked for more than %s seconds' - self.behind_msg = 'Can\'t keep up, voice websocket is %.1fs behind' + self.behind_msg = 'High socket latency, heartbeat is %.1fs behind' def get_payload(self): return { @@ -142,6 +143,12 @@ class VoiceKeepAliveHandler(KeepAliveHandler): 'd': int(time.time() * 1000) } + def ack(self): + ack_time = time.perf_counter() + self._last_ack = ack_time + self.latency = ack_time - self._last_send + self.recent_ack_latencies.append(self.latency) + class DiscordWebSocket(websockets.client.WebSocketClientProtocol): """Implements a WebSocket for Discord's gateway v6. @@ -702,7 +709,7 @@ class DiscordVoiceWebSocket(websockets.client.WebSocketClientProtocol): await self.load_secret_key(data) elif op == self.HELLO: interval = data['heartbeat_interval'] / 1000.0 - self._keep_alive = VoiceKeepAliveHandler(ws=self, interval=interval) + self._keep_alive = VoiceKeepAliveHandler(ws=self, interval=min(interval, 5.0)) self._keep_alive.start() async def initial_connection(self, data): @@ -735,6 +742,19 @@ class DiscordVoiceWebSocket(websockets.client.WebSocketClientProtocol): await self.client_connect() + @property + def latency(self): + """:class:`float`: Latency between a HEARTBEAT and its HEARTBEAT_ACK in seconds.""" + heartbeat = self._keep_alive + return float('inf') if heartbeat is None else heartbeat.latency + + @property + def average_latency(self): + """:class:`list`: Average of last 20 HEARTBEAT latencies.""" + heartbeat = self._keep_alive + average_latency = sum(heartbeat.recent_ack_latencies)/len(heartbeat.recent_ack_latencies) + return float('inf') if heartbeat is None else average_latency + async def load_secret_key(self, data): log.info('received secret key for voice connection') self._connection.secret_key = data.get('secret_key') |