diff --git a/discord/gateway.py b/discord/gateway.py index 5940c6baa..d388d12ad 100644 --- a/discord/gateway.py +++ b/discord/gateway.py @@ -71,7 +71,7 @@ class KeepAliveHandler(threading.Thread): while not self._stop_ev.wait(self.interval): if self._last_ack + 2 * self.interval < time.time(): log.warn("We have stopped responding to the gateway.") - coro = self.ws.close(1006) + coro = self.ws.close(1001) f = compat.run_coroutine_threadsafe(coro, loop=self.ws.loop) try: @@ -191,7 +191,13 @@ class DiscordWebSocket(websockets.client.WebSocketClientProtocol): This is for internal use only. """ gateway = yield from client.http.get_gateway() - ws = yield from websockets.connect(gateway, loop=client.loop, klass=cls) + try: + ws = yield from asyncio.wait_for( + websockets.connect(gateway, loop=client.loop, klass=cls), + timeout=60, loop=client.loop) + except asyncio.TimeoutError: + log.warn('timed out waiting for client connect') + return (yield from cls.from_client(client, resume=resume)) # dynamically add attributes needed ws.token = client.http.token @@ -206,7 +212,12 @@ class DiscordWebSocket(websockets.client.WebSocketClientProtocol): log.info('Created websocket connected to {}'.format(gateway)) # poll event for OP Hello - yield from ws.poll_event() + try: + yield from asyncio.wait_for(ws.poll_event(), timeout=60, loop=client.loop) + except asyncio.TimeoutError: + log.warn("timed out waiting for client HELLO") + yield from ws.close(1001) + return (yield from cls.from_client(client, resume=resume)) if not resume: yield from ws.identify() @@ -219,7 +230,7 @@ class DiscordWebSocket(websockets.client.WebSocketClientProtocol): yield from ws.ensure_open() except websockets.exceptions.ConnectionClosed: # ws got closed so let's just do a regular IDENTIFY connect. - log.info('RESUME failure.') + log.warn('RESUME failure.') return (yield from cls.from_client(client)) else: return ws @@ -523,6 +534,7 @@ class DiscordVoiceWebSocket(websockets.client.WebSocketClientProtocol): HEARTBEAT = 3 SESSION_DESCRIPTION = 4 SPEAKING = 5 + HELLO = 8 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -538,7 +550,14 @@ class DiscordVoiceWebSocket(websockets.client.WebSocketClientProtocol): def from_client(cls, client): """Creates a voice websocket for the :class:`VoiceClient`.""" gateway = 'wss://' + client.endpoint - ws = yield from websockets.connect(gateway, loop=client.loop, klass=cls) + try: + ws = yield from asyncio.wait_for( + websockets.connect(gateway, loop=client.loop, klass=cls), + timeout=60, loop=client.loop) + except asyncio.TimeoutError: + log.warn("timed out waiting for voice client connect") + return (yield from cls.from_client(client)) + ws.gateway = gateway ws._connection = client @@ -553,6 +572,16 @@ class DiscordVoiceWebSocket(websockets.client.WebSocketClientProtocol): } yield from ws.send_as_json(identify) + + try: + # Wait until we have processed READY and keep alive is running + while not ws._keep_alive: + yield from asyncio.wait_for(ws.poll_event(), timeout=60, loop=client.loop) + except asyncio.TimeoutError: + log.warn("timed out waiting for voice client READY") + yield from ws.close(1001) + return (yield from cls.from_client(client)) + return ws @asyncio.coroutine