discord-jda / JDA

Java wrapper for the popular chat & VOIP service: Discord https://discord.com
Apache License 2.0
4.28k stars 735 forks source link

JDASocket Disconnect and Audio Connections #68

Closed AlexSafatli closed 8 years ago

AlexSafatli commented 8 years ago

Hello. I am using JDA2 with my Discord bot and I am encountering the following issue while leaving my bot running and it being already connected with an audio connection to a voice channel. If disconnected from the WebSocket:

[06:55:02] [Warning] [JDASocket]: Got disconnected from WebSocket (Internet?!)... Attempting to reconnect in 2s

I will eventually run into an IllegalStateException:

java.lang.IllegalStateException: Cannot have more than 1 audio connection at a time. Please close existing connection before attempting to open a new connection. at net.dv8tion.jda.managers.impl.AudioManagerImpl.openAudioConnection(AudioManagerImpl.java:66) at net.dv8tion.jda.requests.WebSocketClient.reconnectAudioConnections(WebSocketClient.java:483) at net.dv8tion.jda.requests.WebSocketClient.ready(WebSocketClient.java:117) at net.dv8tion.jda.requests.WebSocketClient.handleEvent(WebSocketClient.java:533) at net.dv8tion.jda.requests.WebSocketClient.onTextMessage(WebSocketClient.java:296) at com.neovisionaries.ws.client.ListenerManager.callOnTextMessage(ListenerManager.java:352) at com.neovisionaries.ws.client.ReadingThread.callOnTextMessage(ReadingThread.java:233) at com.neovisionaries.ws.client.ReadingThread.callOnTextMessage(ReadingThread.java:211) at com.neovisionaries.ws.client.ReadingThread.handleTextFrame(ReadingThread.java:910) at com.neovisionaries.ws.client.ReadingThread.handleFrame(ReadingThread.java:693) at com.neovisionaries.ws.client.ReadingThread.main(ReadingThread.java:102) at com.neovisionaries.ws.client.ReadingThread.run(ReadingThread.java:61)

Any idea how I should resolve this? What essentially happens is the bot leaves the voice channel and is no longer able to rejoin it or any other channel in that particular guild.

DV8FromTheWorld commented 8 years ago

So, I've seen this error but I'm not quite sure where in the reconnection process it fails. Somewhere, for some reason, JDA doesn't properly sever the audio connection when it disconnects and attempts to reconnect, so when it attempts to reconnect it due to a resume/reconnect, it fails because it thinks it is still connected.

@Almighty-Alpaca could you take a look into this one and see what you think?

TheEpTic commented 8 years ago

I've experienced this too. To fix it I just paused the bot and played again. Reconnected and continued from where it left off. Maybe add a check that detects this and reconnects after X seconds?

AlexSafatli commented 8 years ago

What's the best way to check for that state? Just in a try-catch you think or is there a better way? I noticed that looking for the audio connection and seeing if connected to a channel appears to merely show that it is connected despite being disconnected.

Almighty-Alpaca commented 8 years ago

@DV8FromTheWorld I will look at it either this evening or tomorrow, depending on when i come home.

Almighty-Alpaca commented 8 years ago

@DV8FromTheWorld I finally know why this happens. It happens if the main websocket disconnects but the audio websocket doesn't. You can reproduce it by executing

try {
    Field field = WebSocketClient.class.getDeclaredField("socket");
    field.setAccessible(true);
    WebSocket socket = (WebSocket) field.get(jda.getClient());
    socket.disconnect(WebSocketCloseCode.UNEXPECTED, null);
} catch (NoSuchFieldException | SecurityException | IllegalAccessException e) {
    e.printStackTrace();
}

I still don't know how to fix it though...

DV8FromTheWorld commented 8 years ago

Interesting. Thanks for that debug, I'll look into it.

DV8FromTheWorld commented 8 years ago

This is fixed as of v2.1.1