Skip to content

Commit 3047756

Browse files
Add delay on node transfer to hopefully prevent 4006 (#24)
* Fix transfer delay, double delay to 1000ms * Add closecode reconnect example --------- Co-authored-by: Freya Arbjerg <[email protected]>
1 parent 56fe8c5 commit 3047756

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

src/main/kotlin/dev/arbjerg/lavalink/client/LavalinkClient.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import reactor.core.publisher.Flux
1111
import reactor.core.publisher.Sinks
1212
import java.io.Closeable
1313
import java.net.URI
14+
import java.time.Duration
1415
import java.util.concurrent.ConcurrentHashMap
1516
import java.util.concurrent.CopyOnWriteArrayList
1617
import java.util.concurrent.Executors
@@ -203,7 +204,8 @@ class LavalinkClient(val userId: Long) : Closeable, Disposable {
203204
val voiceRegion = link.cachedPlayer?.voiceRegion
204205

205206
link.state = LinkState.CONNECTING
206-
link.transferNode(loadBalancer.selectNode(region = voiceRegion))
207+
// The delay is used to prevent a race condition in Discord, causing close code 4006
208+
link.transferNode(loadBalancer.selectNode(region = voiceRegion), delay = Duration.ofMillis(1000))
207209
}
208210
}
209211
}

src/main/kotlin/dev/arbjerg/lavalink/client/Link.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,14 @@ class Link(
6161
*/
6262
fun loadItem(identifier: String) = node.loadItem(identifier)
6363

64-
internal fun transferNode(newNode: LavalinkNode) {
64+
internal fun transferNode(newNode: LavalinkNode, delay: Duration = Duration.ZERO) {
6565
val player = node.getCachedPlayer(guildId)
6666

6767
if (player != null) {
6868
node.removeCachedPlayer(guildId)
6969
newNode.createOrUpdatePlayer(guildId)
7070
.applyBuilder(player.stateToBuilder())
71-
// Delay by 500ms to hopefully prevent a race-condition from triggering
72-
.delayElement(Duration.ofMillis(500))
71+
.delaySubscription(delay)
7372
.subscribe()
7473
}
7574

testbot/src/main/java/me/duncte123/testbot/Main.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import dev.arbjerg.lavalink.client.loadbalancing.builtin.VoiceRegionPenaltyProvider;
66
import dev.arbjerg.lavalink.libraries.jda.JDAVoiceUpdateListener;
77
import net.dv8tion.jda.api.JDABuilder;
8+
import net.dv8tion.jda.api.entities.channel.unions.AudioChannelUnion;
89
import net.dv8tion.jda.api.requests.GatewayIntent;
910
import net.dv8tion.jda.api.utils.cache.CacheFlag;
1011
import org.slf4j.Logger;
@@ -16,6 +17,8 @@
1617
public class Main {
1718
private static final Logger LOG = LoggerFactory.getLogger(Main.class);
1819

20+
private static final int SESSION_INVALID = 4006;
21+
1922
public static void main(String[] args) throws InterruptedException {
2023
final var token = System.getenv("BOT_TOKEN");
2124
final LavalinkClient client = new LavalinkClient(Helpers.getUserIdFromToken(token));
@@ -25,15 +28,35 @@ public static void main(String[] args) throws InterruptedException {
2528
registerLavalinkListeners(client);
2629
registerLavalinkNodes(client);
2730

28-
JDABuilder.createDefault(token)
31+
final var jda = JDABuilder.createDefault(token)
2932
.setVoiceDispatchInterceptor(new JDAVoiceUpdateListener(client))
3033
.enableIntents(GatewayIntent.GUILD_VOICE_STATES)
3134
.enableCache(CacheFlag.VOICE_STATE)
3235
.addEventListeners(new JDAListener(client))
3336
.build()
3437
.awaitReady();
35-
}
3638

39+
// Got a lot of 4006 closecodes? Try this "fix"
40+
client.on(WebSocketClosedEvent.class).subscribe((event) -> {
41+
if (event.getCode() == SESSION_INVALID) {
42+
final var guildId = event.getGuildId();
43+
final var guild = jda.getGuildById(guildId);
44+
45+
if (guild == null) {
46+
return;
47+
}
48+
49+
final var connectedChannel = guild.getSelfMember().getVoiceState().getChannel();
50+
51+
// somehow
52+
if (connectedChannel == null) {
53+
return;
54+
}
55+
56+
jda.getDirectAudioController().reconnect(connectedChannel);
57+
}
58+
});
59+
}
3760

3861

3962
private static void registerLavalinkNodes(LavalinkClient client) {

0 commit comments

Comments
 (0)