aboutsummaryrefslogtreecommitdiff
path: root/discord/gateway.py
diff options
context:
space:
mode:
authorFwf <[email protected]>2020-01-25 16:24:44 +0000
committerRapptz <[email protected]>2020-04-04 03:00:27 -0400
commitfa34d357a1c28a48210e68e4b7b1f32320e44b9b (patch)
treeb9dd9674e46f01675d99f664e3e80e9f6ecaccf9 /discord/gateway.py
parent[commands] Implement `commands.before/after_invoke` (diff)
downloaddiscord.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.py26
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')